Merge remote-tracking branch 'origin/feature/v9.0/9.0.1' into feature/v9.0/9.0.1
21 files modified
1 files added
| | |
| | | method: 'get', |
| | | }); |
| | | }; |
| | | // 大屏首页=>事件状态数量 |
| | | export const getEventStatusNum = data => { |
| | | return request({ |
| | | url: '/drone-device-core/jobEvent/eventStatusNum', |
| | | method: 'post', |
| | | data, |
| | | }) |
| | | } |
| | | // 事件概况分类数 |
| | | export const getJobEventByStatus = data => { |
| | | return request({ |
| New file |
| | |
| | | <svg width="133" height="47" viewBox="0 0 133 47" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| | | <g id="Group 1321316177"> |
| | | <g id="Rectangle 34624973" filter="url(#filter0_d_2810_2521)"> |
| | | <rect x="4" width="125" height="39" rx="4" fill="#A4A4A4"/> |
| | | </g> |
| | | <path id="保存" d="M65.584 13.17L67.124 13.674C66.76 14.584 66.326 15.536 65.822 16.432V26.19H64.24V18.868C63.89 19.316 63.54 19.736 63.176 20.114C63.022 19.708 62.56 18.812 62.28 18.406C63.582 17.146 64.856 15.158 65.584 13.17ZM68.986 15.214V17.09H73.088V15.214H68.986ZM75.44 21.332H72.64C73.466 22.55 74.67 23.698 75.846 24.384C75.468 24.706 74.936 25.294 74.67 25.714C73.648 24.986 72.626 23.852 71.828 22.606V26.218H70.148V22.676C69.294 23.908 68.23 24.972 67.124 25.686C66.872 25.28 66.354 24.678 65.976 24.356C67.236 23.698 68.482 22.564 69.35 21.332H66.48V19.82H70.148V18.56H67.404V13.758H74.754V18.56H71.828V19.82H75.44V21.332ZM89.23 16.544H81.768C81.292 17.552 80.732 18.518 80.074 19.414V26.19H78.394V21.304C77.974 21.682 77.554 22.018 77.078 22.34C76.91 21.906 76.546 21.164 76.294 20.744C77.806 19.75 79.024 18.224 79.878 16.544H76.798V14.948H80.592C80.816 14.332 81.012 13.73 81.166 13.128L82.902 13.548C82.762 14.024 82.594 14.472 82.426 14.948H89.23V16.544ZM89.44 21.15V22.704H86.122V24.454C86.122 25.294 85.982 25.728 85.38 25.98C84.792 26.204 83.966 26.232 82.846 26.218C82.79 25.742 82.594 25.098 82.384 24.622C83.084 24.664 83.91 24.664 84.134 24.664C84.372 24.65 84.442 24.594 84.442 24.412V22.704H80.886V21.15H84.442V20.17C84.876 19.904 85.338 19.526 85.772 19.134H81.978V17.636H87.298L87.648 17.538L88.698 18.392C87.984 19.148 87.046 19.974 86.122 20.618V21.15H89.44Z" fill="white"/> |
| | | <g id="Frame"> |
| | | <path id="Vector" d="M47.3855 24.4975C47.1585 24.4975 46.9402 24.4126 46.7756 24.2584L42.0787 19.8785C41.7269 19.551 41.7148 19.007 42.0509 18.664C42.387 18.3209 42.9467 18.3105 43.2984 18.638L47.3093 22.3786L54.5843 13.7695C54.8944 13.4039 55.4506 13.3502 55.8266 13.6517C56.2025 13.9531 56.2562 14.4937 55.9478 14.861L48.0681 24.1857C47.9122 24.371 47.6835 24.4837 47.4392 24.4975H47.3855Z" fill="white"/> |
| | | </g> |
| | | </g> |
| | | <defs> |
| | | <filter id="filter0_d_2810_2521" x="0" y="0" width="133" height="47" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> |
| | | <feFlood flood-opacity="0" result="BackgroundImageFix"/> |
| | | <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/> |
| | | <feOffset dy="4"/> |
| | | <feGaussianBlur stdDeviation="2"/> |
| | | <feComposite in2="hardAlpha" operator="out"/> |
| | | <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/> |
| | | <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2810_2521"/> |
| | | <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_2810_2521" result="shape"/> |
| | | </filter> |
| | | </defs> |
| | | </svg> |
| | |
| | | `${website.clientId}:${website.clientSecret}` |
| | | )}`; |
| | | } |
| | | // 后端的要求 |
| | | if (router.currentRoute.value.path === '/job/jobstatistics'){ |
| | | const userAreaCode = store?.state?.user?.userInfo?.detail?.areaCode |
| | | const paramsKey = config.method === 'get' ? 'params' : 'data'; |
| | | const codeKey = config.method === 'get' ? 'areaCode' : 'area_code'; |
| | | const paramCode = config?.params?.areaCode || config?.data?.area_code |
| | | try { |
| | | if (paramCode){ |
| | | if (paramCode === userAreaCode) { |
| | | config[paramsKey][codeKey] = config.method === 'get' ? '' : undefined; |
| | | } else { |
| | | if (!Array.isArray(config[paramsKey])){ |
| | | config[paramsKey] = {...config[paramsKey],[codeKey]: paramCode} |
| | | } |
| | | } |
| | | } |
| | | }catch (e) {} |
| | | } |
| | | |
| | | //headers判断请求是否携带token |
| | | const meta = config.meta || {}; |
| | | const isToken = meta.isToken === false; |
| | |
| | | import dayjs from 'dayjs' |
| | | import 'dayjs/locale/zh-cn' |
| | | import weekday from 'dayjs/plugin/weekday' |
| | | |
| | | // 配置 dayjs |
| | | dayjs.locale('zh-cn') |
| | | dayjs.extend(weekday) |
| | | |
| | | export const calcDate = (date1, date2) => { |
| | | let date3 = date2 - date1; |
| | | |
| | |
| | | export function dateNow() { |
| | | return dateFormat(new Date(), 'yyyyMMddhhmmss'); |
| | | } |
| | | |
| | | export const getDateRange = (unit, formatStr = 'YYYY-MM-DD HH:mm:ss') => { |
| | | const todayDate = dayjs() |
| | | let returnArr = [dayjs(), todayDate] |
| | | if (unit === 'today') { |
| | | returnArr = [dayjs(), todayDate] |
| | | } |
| | | if (unit === 'week') { |
| | | returnArr = [dayjs().weekday(0), todayDate] |
| | | } |
| | | if (unit === 'month') { |
| | | returnArr = [dayjs().startOf('month'), todayDate] |
| | | } |
| | | if (unit === 'year') { |
| | | returnArr = [dayjs().startOf('year'), todayDate] |
| | | } |
| | | returnArr = [returnArr[0].startOf('day').format(formatStr), returnArr[1].endOf('day').format(formatStr)] |
| | | return returnArr |
| | | } |
| | |
| | | <div class="mange-table"> |
| | | <el-table border :data="tableList" class="ztzf-table-mange"> |
| | | <el-table-column label="序号" type="index" width="60"></el-table-column> |
| | | <el-table-column prop="model_name" label="算法名称" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="alg_name" label="算法名称" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="alg_type" label="算法类型" align="center"></el-table-column> |
| | | <el-table-column prop="qua_rate" label="最低准确率" align="center"> |
| | | <template #header> |
| | |
| | | {{ scope.row.event_type == 0 ? '常规类' : '紧急类' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="version" label="算法版本" align="center"/> |
| | | <el-table-column prop="remark" label="算法描述" show-overflow-tooltip /> |
| | | <el-table-column label="操作" width="180" align="center"> |
| | | <template #default="scope"> |
| | |
| | | |
| | | <el-table-column property="link" label="缩略图" width="120"> |
| | | <template #default="scope"> |
| | | <img |
| | | <div v-if="scope.row?.resultType === 5" class="videoItem1"> |
| | | <img |
| | | class="quanjing" |
| | | @click="clickpanorama(scope.row)" |
| | | v-if="scope.row?.resultType === 5" |
| | | |
| | | :src="scope.row?.smallUrl" |
| | | alt="" |
| | | /> |
| | | </div> |
| | | <!-- 视频 --> |
| | | <div v-else-if="scope.row?.resultType === 1" class="videoItem1"> |
| | | <img |
| | |
| | | /> |
| | | </div> |
| | | <!-- 正射 --> |
| | | <el-image |
| | | v-else-if="scope.row?.resultType === 4" |
| | | <div v-else-if="scope.row?.resultType === 4" class="videoItem1"> |
| | | <el-image |
| | | |
| | | :src="getzsSmallImg(scope.row?.link)" |
| | | :preview-src-list="[getzsSmallImg(scope.row?.link)]" |
| | | fit="cover" |
| | | preview-teleported |
| | | /> |
| | | <el-image |
| | | v-else |
| | | </div> |
| | | <div v-else class="videoItem1"> |
| | | <el-image |
| | | :src="scope.row?.smallUrl" |
| | | :preview-src-list="[scope.row?.showUrl]" |
| | | fit="cover" |
| | | preview-teleported |
| | | /> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="jobTime" label="任务时间" /> |
| | |
| | | > |
| | | <div class="video-container"> |
| | | <video |
| | | style="width: 100%" |
| | | style="width: 100%;height: 500px" |
| | | class="videoBox" |
| | | ref="videoRefs" |
| | | controls |
| | |
| | | width: 76px; |
| | | height: 72px; |
| | | } |
| | | |
| | | .videoItem1 { |
| | | .playBox { |
| | | width: 20px; |
| | | height: 20px; |
| | | position: absolute; |
| | | top: 46%; |
| | | left: 43%; |
| | | transform: translate(-50%, -50%); |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | position: relative; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | width: 100%; |
| | | height: 100%; |
| | | |
| | | min-height: 80px; |
| | | } |
| | | |
| | | .playBox { |
| | | position: absolute; |
| | | width: 20px; |
| | | height: 20px; |
| | | cursor: pointer; |
| | | |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | |
| | | z-index: 1; |
| | | } |
| | | .videoDialog :deep(.el-dialog) { |
| | | height: 600px; |
| | | width: 54%; |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | ], |
| | | }, |
| | |
| | | console.error('获取行政区划数据失败:', error); |
| | | return []; |
| | | } |
| | | }, |
| | | }, |
| | | findNodeById(tree, id) { |
| | | if (tree.id === id) { |
| | | return tree; |
| | |
| | | try { |
| | | const response = await this.getFullAreaCode(areaCode); |
| | | const codes = response.split(','); |
| | | |
| | | |
| | | // 获取区域树数据 |
| | | const xzqhData = await this.getRegionTreeList(codes[0]); |
| | | if (!xzqhData) return '/'; |
| | | |
| | | |
| | | const names = []; |
| | | for (const code of codes) { |
| | | const node = this.findNodeById(xzqhData, code); |
| | |
| | | copyInfo (row, index) { |
| | | const ipAddress = import.meta.env.VITE_APP_DEVICE_IP |
| | | let params = ` |
| | | host: tcp://${ipAddress} |
| | | 网关地址: tcp://${ipAddress} |
| | | 账号:drone |
| | | 密码:drone@123 |
| | | 组织id:${row.bing_id} |
| | |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | |
| | | |
| | | const { releaseTimeRange } = this.query |
| | | let values = { |
| | | ...params, |
| | |
| | | if (values.area_code) { |
| | | values['area_code'] = values.area_code.split(',').pop() |
| | | } |
| | | |
| | | |
| | | this.loading = true |
| | | getList(page.currentPage, page.pageSize, values).then(async res => { |
| | | const data = res.data.data |
| | |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }) |
| | | |
| | | |
| | | }, |
| | | treeLoad (tree, treeNode, resolve) { |
| | | var params = { |
| | |
| | | <template #firmware_status="{ row }"> |
| | | <div v-if="row.firmware_status == 1" class="onlineStatus1"> |
| | | <el-tag type="info">无需升级</el-tag> |
| | | <el-tag type="primary" effect="dark" class="active-element" @click="rollFirmware(row)">版本管理</el-tag> |
| | | <!-- <el-tag type="primary" effect="dark" class="active-element" @click="rollFirmware(row)">版本管理</el-tag>--> |
| | | <!-- <div style="background-color: #f1f1f1; border-radius: 4px">无需升级</div> --> |
| | | </div> |
| | | <div v-if="row.firmware_status == 2" class="onlineStatus1"> |
| | | <!-- <el-tag type="success" effect="dark" class="active-element" @click="updateFirmware(row)" |
| | | >升级固件</el-tag |
| | | > --> |
| | | <el-tag type="primary" effect="dark" class="active-element" @click="rollFirmware(row)">版本管理</el-tag> |
| | | <!-- <el-tag type="primary" effect="dark" class="active-element" @click="rollFirmware(row)">版本管理</el-tag>--> |
| | | <!-- <div @click="updateFirmware(row)" class="firmware_status">升级固件</div> --> |
| | | </div> |
| | | <div v-if="row.firmware_status == 3" class="onlineStatus"> |
| | | <el-tag type="success" effect="dark" class="active-element" @click="updateFirmware(row)">一致性升级</el-tag> |
| | | <!-- <el-tag type="success" effect="dark" class="active-element" @click="updateFirmware(row)">一致性升级</el-tag>--> |
| | | <!-- <div @click="updateFirmware(row)" class="firmware_status">一致性升级</div> --> |
| | | </div> |
| | | <div v-if="row.firmware_status == 4" class="onlineStatus"> |
| | |
| | | </el-icon>更多</el-button> |
| | | <template #dropdown v-if="scope.row.domain == 3"> |
| | | <el-dropdown-menu teleported> |
| | | <el-dropdown-item command="a"> |
| | | <el-button type="primary" text icon="el-icon-paperclip" v-if="permission.oss_set" |
| | | <el-dropdown-item command="a" v-if="permission.oss_set"> |
| | | <el-button type="primary" text icon="el-icon-paperclip" |
| | | @click.stop="handleOpenOssSet(scope.row, scope.index)">存储配置</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="b"> |
| | | <el-button type="primary" text icon="el-icon-share" v-if="permission.per_share && scope.row.domain == 3" |
| | | <el-dropdown-item command="b" v-if="permission.per_share && scope.row.domain == 3"> |
| | | <el-button type="primary" text icon="el-icon-share" |
| | | @click.stop="handleOpenDevicePerShare(scope.row, scope.index)">机场授权</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="c"> <el-button type="primary" text icon="el-icon-position" |
| | | :disabled="!scope.row.status" v-if="permission.rang_con && scope.row.domain == 3" |
| | | <el-dropdown-item command="c" v-if="permission.rang_con && scope.row.domain == 3"> |
| | | <el-button type="primary" text icon="el-icon-position" |
| | | :disabled="!scope.row.status" |
| | | @click.stop="handleOpenRemoteDebugging(scope.row, scope.index)">远程调试</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="d"><el-button type="primary" text icon="el-icon-collection" |
| | | v-if="permission.fly_device_offline" @click.stop="rollFirmware(scope.row)">固件版本管理</el-button> |
| | | <el-dropdown-item command="d" v-if="permission.fly_device_offline"> |
| | | <el-button type="primary" text icon="el-icon-collection" |
| | | @click.stop="rollFirmware(scope.row)">固件版本管理</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="d" v-if="!scope.row.status"> |
| | | <el-button type="primary" text icon="el-icon-collection" @click.stop="dockNotLine(scope.row)"> |
| | | {{ scope.row.hidden_flag === 1 ? '设备上线' : '设备下线' }} |
| | | </el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="e"><el-button type="primary" text icon="el-icon-document-delete" |
| | | v-if="permission.fly_device_offline && scope.row.mode_code !==0" @click.stop="handleDeviceOffline(scope.row)">注销</el-button> |
| | | <el-dropdown-item command="e" v-if="permission.fly_device_offline && scope.row.mode_code !==0"> |
| | | <el-button type="primary" text icon="el-icon-document-delete" @click.stop="handleDeviceOffline(scope.row)">注销</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="e"> |
| | | <el-button type="primary" text icon="el-icon-document-delete" v-if="permission.fly_device_offline" |
| | | <el-dropdown-item command="e" v-if="permission.fly_device_offline"> |
| | | <el-button type="primary" text icon="el-icon-document-delete" |
| | | :disabled="scope.row.dem_status === 1" @click.stop="handleStatus(scope.row)"> |
| | | {{ scope.row.dem_status === 0 ? '初始化地形' : (scope.row.dem_status === 1 ? '初始化中' : '更新地形') }} |
| | | </el-button> |
| | |
| | | rollFirmVersion: '', |
| | | firmList: [], |
| | | rollFirmwareBox: false, |
| | | isUpdateDrone: {}, |
| | | // 用于记录已经创建的websocket,防止重复创建 |
| | | webSocketIdSet: new Set(), |
| | | // 用于保存多组websocket |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | { |
| | | label: '4G增强', |
| | | prop: 'link_workmode', |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | { |
| | | label: '固件升级', |
| | | prop: 'firmware_status', |
| | | labelWidth: 145, |
| | | width: 100, |
| | | // hide: true, |
| | | viewDisabled: true, |
| | | addDisabled: true, |
| | | editDisplay: false, //编辑显示 |
| | | addDisplay: false, |
| | | viewDisplay: false, |
| | | }, |
| | | { |
| | | label: '设备SN', |
| | | prop: 'device_sn', |
| | |
| | | labelWidth: 145, |
| | | width: 110, |
| | | editDisplay: false, //编辑显示 |
| | | }, |
| | | { |
| | | label: '固件升级', |
| | | prop: 'firmware_status', |
| | | labelWidth: 145, |
| | | width: 100, |
| | | hide: true, |
| | | viewDisabled: true, |
| | | addDisabled: true, |
| | | editDisplay: false, //编辑显示 |
| | | addDisplay: false, |
| | | viewDisplay: false, |
| | | }, |
| | | { |
| | | label: '所属部门', |
| | |
| | | websocket?.initSocket() |
| | | }, |
| | | async messageHandler(payload) { |
| | | if (!payload) { |
| | | let loadData = JSON.parse(payload) |
| | | if (!loadData) { |
| | | return |
| | | } |
| | | if (payload.biz_code != 'ota_progress') { |
| | | |
| | | if (loadData.biz_code != 'ota_progress') { |
| | | return |
| | | } |
| | | var data = payload.data |
| | | this.data.forEach(e => { |
| | | if (e.device_sn == data.sn && data.output.status == 'in_progress') { |
| | | e.firmware_progress = data.output.progress.percent |
| | | console.log(loadData.data.output.progress.percent, '升级进度') |
| | | this.data.forEach((e, index) => { |
| | | if ((e.device_sn == loadData.data.sn || e.child_sn == loadData.data.sn) && loadData.data.output.status == 'in_progress') { |
| | | e.firmware_progress = loadData.data.output.progress.percent |
| | | if (e.children[0]) { |
| | | e.children[0].firmware_progress = loadData.data.output.progress.percent; |
| | | } |
| | | // console.log('是否更新中2',e.children[0]) |
| | | } |
| | | |
| | | if (e.device_sn == data.sn && data.output.status == 'ok') { |
| | | if ((e.device_sn == loadData.data.sn || e.child_sn == loadData.data.sn) && loadData.data.output.status == 'ok') { |
| | | // 升级完成修改状态 |
| | | e.firmware_status = 1 |
| | | e.mode_code = 0 |
| | | if (e.children[0]) { |
| | | e.children[0].firmware_status = 1 |
| | | } |
| | | const webscoket = this.websocketMap.get(e.workspace_id) |
| | | // 关闭 |
| | | webscoket?.close() |
| | |
| | | this.webSocketIdSet.delete(e.workspace_id) |
| | | } |
| | | }) |
| | | // this.$forceUpdate() |
| | | }, |
| | | init() { |
| | | (this.page = { |
| | |
| | | }, |
| | | // 版本回退点击事件 |
| | | rollFirmware(row) { |
| | | console.log(this.data,row, '打印看看值') |
| | | if (row.status == 0) { |
| | | this.$message({ |
| | | type: 'warning', |
| | |
| | | } |
| | | var that = this |
| | | this.rollFirmwareBox = true |
| | | this.isUpdateDrone = row |
| | | const param = { |
| | | device_name: row.device_name, |
| | | } |
| | |
| | | // 需要改变的版本号和无人机版本号如果是一致,进行单独的机场升级/回滚操作 |
| | | } |
| | | } |
| | | |
| | | ota(that.firmwareInfo.workspaceId, arr).then(res => { |
| | | that.firmwareVersion = '' |
| | | that.firmwareInfo = {} |
| | |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.onLoad(this.page) |
| | | done() |
| | | // 此处需分是无人机升级还是机巢升级版本 |
| | | // console.log('看看是无人机更新还是机场更新',that.isUpdateDrone) |
| | | if(that.isUpdateDrone.domain == 3) { |
| | | this.onLoad(this.page) |
| | | } else { |
| | | this.data.map(item => { |
| | | if(item.workspace_id === that.isUpdateDrone.workspace_id) { |
| | | item.firmware_status = 2 |
| | | item.mode_code = 3 |
| | | item.children[0].mode_code = 0 |
| | | item.children[0].firmware_status = 4 |
| | | this.connectWebSocket(item) |
| | | console.log('无人机更新中',item) |
| | | } |
| | | }) |
| | | } |
| | | // 获取保存的 resolve 函数===== 此处需要更新子集塞入父级 |
| | | // done() |
| | | }) |
| | | }, |
| | | // 升级固件按钮事件 |
| | |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }, |
| | | async getFullAreaCode(areaCode) { |
| | | console.log('getFullAreaCode', areaCode) |
| | | if (!areaCode) return '' |
| | | |
| | | const code = areaCode.toString() |
| | | |
| | | if (code.includes(',')) return code |
| | | |
| | | if (code.endsWith('0000000000')) { |
| | | return code |
| | | } else if (code.endsWith('00000000') && !code.endsWith('0000000000')) { |
| | | const provinceCode = code.substring(0, 2) + '0000000000' |
| | | return `${provinceCode},${code}` |
| | | } else { |
| | | const provinceCode = code.substring(0, 2) + '0000000000' |
| | | const cityCode = code.substring(0, 4) + '00000000' |
| | | return `${provinceCode},${cityCode},${code}` |
| | | } |
| | | }, |
| | | // async getFullAreaCode(areaCode) { |
| | | // console.log('getFullAreaCode', areaCode) |
| | | // if (!areaCode) return '' |
| | | // |
| | | // const code = areaCode.toString() |
| | | // |
| | | // if (code.includes(',')) return code |
| | | // |
| | | // if (code.endsWith('0000000000')) { |
| | | // return code |
| | | // } else if (code.endsWith('00000000') && !code.endsWith('0000000000')) { |
| | | // const provinceCode = code.substring(0, 2) + '0000000000' |
| | | // return `${provinceCode},${code}` |
| | | // } else { |
| | | // const provinceCode = code.substring(0, 2) + '0000000000' |
| | | // const cityCode = code.substring(0, 4) + '00000000' |
| | | // return `${provinceCode},${cityCode},${code}` |
| | | // } |
| | | // }, |
| | | beforeOpen(done, type) { |
| | | if (['edit', 'view'].includes(type)) { |
| | | getDetail(this.form.id).then(async res => { |
| | |
| | | this.page.total = data.total |
| | | data.records.forEach(e => { |
| | | e['hasChildren'] = e.has_children |
| | | if (e.firmware_status == 4) { |
| | | if (e.firmware_status == 4 || e.mode_code === 3) { |
| | | console.log('监听了没')// 机巢升级 firmware_status === 4 |
| | | this.connectWebSocket(e) |
| | | } |
| | | e.duration_of_insurance = [e?.insure_start_time?.slice(0, 10) || '', e?.insure_expired_time?.slice(0, 10) || ''] |
| | | }) |
| | | this.data = data.records |
| | | this.data = data.records.map(item => ({ |
| | | ...item, |
| | | firmware_progress: 0 |
| | | })); |
| | | // console.log('2222',this.data) |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }) |
| | |
| | | childSn: tree.child_sn, |
| | | } |
| | | getList(1, 10, params).then(res => { |
| | | const data = res.data.data.records |
| | | const data = res.data.data.records.map(item =>({ |
| | | ...item, |
| | | firmware_progress: 0 |
| | | })) |
| | | data.forEach(e => { |
| | | e.duration_of_insurance = [e?.insure_start_time?.slice(0, 10) || '', e?.insure_expired_time?.slice(0, 10) || ''] |
| | | }) |
| | |
| | | watch( |
| | | () => Store.getters.deviceState, |
| | | value => { |
| | | console.log(value, '测试') |
| | | // console.log(value, '测试') |
| | | // console.log('设备状态变化', value.deviceInfo[props.deviceInfo.child_sn]) |
| | | if (props.sn && (value.currentSn === props.deviceInfo.child_sn || value.currentSn === props.deviceInfo.device_sn)) { |
| | | debugStatus.value = value.dockInfo[props.deviceInfo.device_sn]?.basic_osd?.mode_code === EDockModeCode.Remote_Debugging |
| | |
| | | fit="cover" |
| | | /> |
| | | |
| | | <el-dialog |
| | | class="ztzf-dialog" |
| | | append-to-body |
| | | modal-class="detailsOfHistoricalTasks" |
| | | v-model="VideoShow" |
| | | :width="pxToRem(1600)" |
| | | :close-on-click-modal="false" |
| | | :destroy-on-close="true" |
| | | > |
| | | <div class="fullscreen"> |
| | | <video |
| | | ref="fullscreenVideo" |
| | | class="fullscreen-video" |
| | | :src="currentVideoUrl" |
| | | :style="{ width: pxToRem(1567), height: '80vh' }" |
| | | controls |
| | | preload="auto" |
| | | @play="handleVideoPlay" |
| | | @ended="handleVideoEnded" |
| | | ></video> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | </div> |
| | | |
| | | </template> |
| | |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | <el-dialog |
| | | class="ztzf-dialog" |
| | | append-to-body |
| | | modal-class="detailsOfHistoricalTasks" |
| | | v-model="VideoShow" |
| | | :width="pxToRem(1600)" |
| | | :close-on-click-modal="false" |
| | | :destroy-on-close="true" |
| | | > |
| | | <div class="fullscreen"> |
| | | <video |
| | | ref="fullscreenVideo" |
| | | class="fullscreen-video" |
| | | :src="currentVideoUrl" |
| | | :style="{ width: pxToRem(1567), height: '80vh' }" |
| | | controls |
| | | preload="auto" |
| | | @play="handleVideoPlay" |
| | | @ended="handleVideoEnded" |
| | | ></video> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- 全景360 --> |
| | | <PanoramaPopup |
| | | v-if="'全景'" |
| | |
| | | { name: '任务类型', value: '', field: 'industry_type_str' }, |
| | | { name: '飞行事件', value: '', field: 'event_number' }, |
| | | { name: '所属机巢', value: '', field: 'device_names' }, |
| | | { name: '创建人', value: '', field: 'creator_name' }, |
| | | { name: '所属部门', value: '', field: 'dept_name' }, |
| | | { name: '任务时间', value: '', field: 'cycle_time_value' }, |
| | | { name: '关联算法', value: '', field: 'ai_type_str' }, |
| | | { name: '自定义识别区', value: '', field: 'enable_custom_area' }, |
| | | { name: '创建人', value: '', field: 'creator_name' }, |
| | | { name: '任务描述', value: '', field: 'remark' }, |
| | | // { name: '任务执行次数', value: '', field: 'job_num' }, |
| | | ]) |
| | |
| | | jobTimes.value = res.data.data.job_times |
| | | infoList.value.forEach(item => { |
| | | if (item.name === '任务频次') { |
| | | const { rep_rule_type = '', rep_rule_val = '' } = detailsData?.value || {} |
| | | item.value = rep_rule_type + ' -- ' + rep_rule_val |
| | | const { rep_rule_type = '',final_cycle_frequency = '' } = detailsData?.value || {} |
| | | item.value = rep_rule_type ? final_cycle_frequency : '1次' |
| | | } else { |
| | | item.value = detailsData.value?.[item.field] || '--' |
| | | } |
| | |
| | | let timeListEnum = ['TODAY', 'CURRENT_WEEK', 'CURRENT_MONTH', 'CURRENT_YEAR']; |
| | | let checked = ref('month'); |
| | | |
| | | // 根据 周期 获取时间段 |
| | | function getDateRange(date_enum) { |
| | | // 设置对应的日期范围 |
| | | switch (date_enum) { |
| | | case 'today': |
| | | dateRange.value = [dayjs().startOf('day').format(timeFormat), dayjs().endOf('day').format(timeFormat)] |
| | | break |
| | | case 'week': |
| | | dateRange.value = [dayjs().startOf('week').format(timeFormat), dayjs().format(timeFormat)] |
| | | break |
| | | case 'month': |
| | | dateRange.value = [dayjs().startOf('month').format(timeFormat), dayjs().format(timeFormat)] |
| | | break |
| | | case 'year': |
| | | dateRange.value = [dayjs().startOf('year').format(timeFormat), dayjs().format(timeFormat)] |
| | | break |
| | | } |
| | | } |
| | | |
| | | let timeClick = (item, index) => { |
| | | if (checked.value === item){ |
| | | if (checked.value === item) { |
| | | checked.value = null |
| | | searchForm.date_enum = undefined |
| | | }else{ |
| | | dateRange.value = [] |
| | | } else { |
| | | checked.value = item |
| | | searchForm.date_enum = timeListEnum[index] |
| | | getDateRange(item) |
| | | } |
| | | dateRange.value = [] |
| | | handleSearch() |
| | | }; |
| | | } |
| | | // 搜索 |
| | | const handleSearch = () => { |
| | | if (!dateRange.value) { |
| | | dateRange.value = []; |
| | | } |
| | | if (dateRange.value && dateRange.value.length) { |
| | | // 有值时 清除 日 本周 本月 本年状态 |
| | | checked.value = ''; |
| | | searchForm.date_enum = ''; |
| | | } |
| | | // if (dateRange.value && dateRange.value.length) { |
| | | // // 有值时 清除 日 本周 本月 本年状态 |
| | | // checked.value = ''; |
| | | // searchForm.date_enum = ''; |
| | | // } |
| | | // 提交至store |
| | | let params = { |
| | | ...searchForm, |
| | |
| | | dateRange.value = dateArray; |
| | | const find = store.state.tags.bsTagList.find(i => i.path === '/job/jobstatistics') |
| | | find && (find.query = {}) |
| | | } else { |
| | | getDateRange('month') |
| | | } |
| | | // 查询一次 |
| | | handleSearch() |
| | |
| | | // isShowCurrentTaskDetails.value = true |
| | | // 跳转大屏当前任务详情 |
| | | const adminUrl = `${import.meta.env.VITE_APP_AREA_NAME}/command-center-dashboard/#/taskManage` |
| | | const targetPath = `id=${encodeURIComponent(rowData.value.id)}&batchNo=${encodeURIComponent(rowData.value.batch_no)}` |
| | | const targetPath = `id=${encodeURIComponent(rowData.value.id)}&batchNo=${encodeURIComponent(rowData.value.batch_no)}&dockSn=${encodeURIComponent(rowData.value.device_sns[0])}` |
| | | window.open(`${adminUrl}?${targetPath}`, '_blank') |
| | | } else { |
| | | isShowDeviceJobDetails.value = true |
| | |
| | | :expand-on-click-node="false" |
| | | :check-on-click-node="false" |
| | | :filter-node-method="filterNode" |
| | | highlight-current |
| | | @check="handleCheck" |
| | | :props="{ |
| | | label: 'name', |
| | |
| | | loading.value = true; |
| | | const res = await treeDataApi({filterExpired:false}); |
| | | treeAllData.value = res.data.data; |
| | | if(coverData.value.length===0){ |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | nextTick(() => { |
| | | if (treeRef.value) { |
| | | treeRef.value.setCheckedKeys([]); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | setupWatch(); |
| | | } catch (error) { |
| | |
| | | }; |
| | | // 定位按钮事件 |
| | | const handleLocation = node => { |
| | | const currentKey = treeRef.value.getCurrentKey(); |
| | | if (currentKey === node.data.id) { |
| | | treeRef.value.setCurrentKey(null); // 取消高亮 |
| | | } else { |
| | | treeRef.value.setCurrentKey(node.data.id); // 高亮当前节点 |
| | | } |
| | | if (node.data.level === 2) { |
| | | layerParams.value.isSingleLocating = false; |
| | | // 新增:标记当前定位的文件夹ID |
| | |
| | | const currentCheckedKeys = [...checkedKeys.value]; |
| | | const currentCheckedNodes = [...checkedNodes.value]; |
| | | EventBus.emit('focusOnNode', node.data); |
| | | |
| | | if (node.data.level === 2) { |
| | | const folderChildren = node.data.children || []; |
| | | const childrenIds = folderChildren.map(child => child.id); |
| | |
| | | |
| | | // 删除按钮事件 |
| | | const handleDelete = node => { |
| | | |
| | | let id = node.data.id; |
| | | ElMessageBox.confirm('确定要删除该内容吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | |
| | | overflow-y: scroll; |
| | | height: 0; |
| | | flex-grow: 1; |
| | | padding-right: 12px; |
| | | // padding-right: 12px; |
| | | :deep(.el-tree-node__content) { |
| | | height: 45px !important; |
| | | line-height: 45px !important; |
| | | // padding-left: 0 !important; |
| | | border-bottom: 1px dotted rgba(255,255,255,0.1); |
| | | } |
| | | |
| | | // 定位选中节点的背景色样式 |
| | | ::v-deep(.el-tree-node.is-current > .el-tree-node__content) { |
| | | background-color: rgba(64, 158, 255, 0.2) !important; // 浅蓝色半透明背景 |
| | | } |
| | | .isTheTerritory { |
| | | :deep() { |
| | | .el-tree-node__expand-icon { |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding-right: 12px; |
| | | width: 100%; |
| | | .nodeName { |
| | | font-size: 12px !important; |
| | |
| | | </div> |
| | | </div> |
| | | <div class="btnGroups"> |
| | | <img v-if="!layerParams.editingIsProhibited" src="/src/assets/images/layerManagement/savebtn.svg" alt="" @click="submitHandle" /> |
| | | <img v-if="layerParams.editingIsProhibited" src="/src/assets/images/layerManagement/closeBtn.svg" @click="cancelHandel" alt="" /> |
| | | <img v-if="!layerParams.editingIsProhibited && layerParams.fenceArea / 1000000 > 50" src="/src/assets/images/layerManagement/disabled.svg" alt="" /> |
| | | <img v-if="!layerParams.editingIsProhibited && layerParams.fenceArea / 1000000 < 50" src="/src/assets/images/layerManagement/savebtn.svg" alt="" @click="submitHandle" /> |
| | | <img v-if="layerParams.editingIsProhibited" src="/src/assets/images/layerManagement/closeBtn.svg" @click="cancelHandel" alt="" /> |
| | | <img v-else src="/src/assets/images/layerManagement/cancelbtn.svg" @click="cancelHandel" alt="" /> |
| | | |
| | | </div> |
| | |
| | | () => layerParams.value.fenceArea, |
| | | newArea => { |
| | | if (newArea !== undefined && newArea !== null) { |
| | | fenceArea.value = newArea; |
| | | formData.value.area = newArea; |
| | | if (newArea / 1000000 < 50) { |
| | | fenceArea.value = newArea; |
| | | formData.value.area = newArea; |
| | | } |
| | | } |
| | | }, |
| | | { immediate: true } |
| | |
| | | <span class="icon"> |
| | | <el-icon><WarningFilled /></el-icon> |
| | | </span> |
| | | <span>测区不支持交叉面</span> |
| | | <span>{{ showWarnToolTipText }}</span> |
| | | </div> |
| | | <div class="tool-tip" v-if="!isShowWaringTip && layerParams.addNest"> |
| | | {{ showToolTipText }} |
| | |
| | | const userInfo = computed(() => store.getters.userInfo); |
| | | const areaCode = userInfo.value?.detail?.areaCode || ''; |
| | | const showToolTipText = ref('点击地图生成测绘区域') |
| | | const showWarnToolTipText = ref('测区不支持交叉面') |
| | | // 红色警告交叉面提示窗 |
| | | const isShowWaringTip = ref(false); |
| | | const activeName = ref('自定义识别区'); |
| | |
| | | } |
| | | if(polygon.length > 0 && !isShowWaringTip.value){ |
| | | showToolTipText.value = '测绘区域已绘制完成' |
| | | }else { |
| | | } else { |
| | | showToolTipText.value = '点击地图生成测绘区域' |
| | | } |
| | | |
| | |
| | | const closedPolygon = isClosed ? polygon : [...polygon, firstPoint]; |
| | | const turfPolygon = turf.polygon([closedPolygon]); |
| | | const area = _.round(turf.area(turfPolygon), 2); |
| | | layerParams.value.fenceArea = area; |
| | | if (area / 1000000 < 50) { |
| | | layerParams.value.fenceArea = area; |
| | | } else { |
| | | layerParams.value.fenceArea = area; |
| | | isShowWaringTip.value = true |
| | | showWarnToolTipText.value = '自定义禁飞区不能超过50平方公里' |
| | | } |
| | | } else { |
| | | layerParams.value.fenceArea = 0; |
| | | } |
| | | }; |
| | | drawPolygonExample.subscribe('getShowWaringTip', data => { |
| | | isShowWaringTip.value = data; |
| | | showWarnToolTipText.value = '测区不支持交叉面' |
| | | layerParams.value.crossSurface = data |
| | | }); |
| | | const throttleLoadPlanarRoute = throttle(loadPlanarRoute, 200); |
| | |
| | | }); |
| | | // 更新选中数据列表 |
| | | selectDataList.value = selectDataList.value.filter(item => item.folder_id !== folderId); |
| | | getdataFolderApi() |
| | | }; |
| | | </script> |
| | | |
| | |
| | | v-model="item.value" |
| | | placeholder="请选择图斑类型" |
| | | style="width: 102%" |
| | | :disabled="item.value ==='综合类'" |
| | | > |
| | | <el-option |
| | | v-for="opt in spotTypeOptions" |
| | |
| | | <div class="table-overlay"> |
| | | <div class="table-content"> |
| | | <div class="tabname">图斑列表</div> |
| | | <el-table |
| | | <div class="tabBoxLoading" |
| | | v-loading="tableLoading" |
| | | element-loading-text="加载中..." |
| | | element-loading-background="rgba(0, 0, 0, 0.1)" |
| | | > |
| | | <el-table |
| | | v-if="tableData.length > 0" |
| | | |
| | | ref="polygonTableEle" |
| | | highlight-current-row |
| | | :row-class-name="tableRowClassName" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | |
| | | const homeViewer = shallowRef(null); |
| | | let tbJwdList = []; |
| | | const loading = ref(false); |
| | | const tableLoading = ref(true); |
| | | const tableData = ref([]); |
| | | const AlltableData = ref([]); |
| | | let total = ref(0); |
| | |
| | | const isInit = ref(true); |
| | | // 图斑管理表格 |
| | | const getTableList = () => { |
| | | tableLoading.value = true; |
| | | const requestParams = { |
| | | patchesInfoId: props.detailid, |
| | | |
| | | }; |
| | | AlltableMapListApi(requestParams).then(res => { |
| | | tableData.value = res.data.data?.map(item => ({ |
| | |
| | | } else { |
| | | entitiesAddSpot(); |
| | | } |
| | | }).finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | |
| | | getspotManagementTableApi(); |
| | | }, 0); |
| | | } else { |
| | | |
| | | tableLoading.value = false; |
| | | tableData.value = []; |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | |
| | | z-index: 9999 !important; |
| | | max-width: 300px; |
| | | } |
| | | .tabBoxLoading { |
| | | height: 100%; |
| | | |
| | | } |
| | | |
| | | .el-table { |
| | | flex: 1; |
| | | overflow: auto; |
| | | height: 98%; |
| | | overflow: auto; |
| | | |
| | | } |
| | | .btnGroups { |
| | | position: absolute; |
| | |
| | | }); |
| | | }; |
| | | // 图斑上传 |
| | | const uploadFlightFile = (file, t) => { |
| | | const uploadFlightFile = async (file, t) => { |
| | | loading.value = true; |
| | | const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1); |
| | | if (!['kmz', 'kml', 'zip'].includes(fileSuffix)) { |
| | | return ElMessage.error('请上传zip/kmz/kml格式的文件'); |
| | | } |
| | | if (file) { |
| | | box.value = false; |
| | | } |
| | | let data = new FormData(); |
| | | let type = t === '3' ? '' : t; |
| | | const params = { |
| | | file: file, |
| | | fileName: ruleForm.name, |
| | | LotTypeId: ruleForm.region, |
| | | }; |
| | | try { |
| | | const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1); |
| | | if (!['kmz', 'kml', 'zip'].includes(fileSuffix)) { |
| | | ElMessage.error('请上传zip/kmz/kml格式的文件'); |
| | | return; |
| | | } |
| | | box.value = false; |
| | | let data = new FormData(); |
| | | let type = t === '3' ? '' : t; |
| | | const params = { |
| | | file: file, |
| | | fileName: ruleForm.name, |
| | | LotTypeId: ruleForm.region, |
| | | }; |
| | | |
| | | Object.keys(params).forEach(key => { |
| | | data.append(key, params[key]); |
| | | }); |
| | | Object.keys(params).forEach(key => { |
| | | data.append(key, params[key]); |
| | | }); |
| | | |
| | | uploadManagementApi(data).then(res => { |
| | | const res = await uploadManagementApi(data); |
| | | if (res.data.code !== 0) { |
| | | return ElMessage.error('上传失败'); |
| | | ElMessage.error('上传失败'); |
| | | return; |
| | | } |
| | | |
| | | ElMessage.success('上传成功'); |
| | | |
| | | loading.value = false; |
| | | |
| | | // 重置表单 |
| | | ruleForm.name = ''; |
| | | ruleForm.region = ''; |
| | | |
| | | if (ruleFormRef.value) { |
| | | ruleFormRef.value.resetFields(); |
| | | } |
| | | |
| | | searchReset(); |
| | | }); |
| | | } catch (error) { |
| | | loading.value = false; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | provide('searchReset', searchReset); |
| | | onMounted(() => { |
| | |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="关联航线" prop="file_id"> |
| | | <el-select v-model="formParams.file_id" placeholder="请选择航线" filterable @change="getFlyingNest" |
| | | :disabled="txtTitle === '工单审核' || txtTitle === '工单详情'"> |
| | | <el-select v-if="txtTitle === '新建工单'" v-model="formParams.file_id" placeholder="请选择航线" filterable |
| | | @change="getFlyingNest"> |
| | | <el-option v-for="item in lineList" :key="item.wayline_id" :label="item.name" |
| | | :value="item.wayline_id" /> |
| | | </el-select> |
| | | <el-input v-else v-model="formParams.wayline_file_region_vo.name" |
| | | :disabled="txtTitle === '工单审核' || txtTitle === '工单详情'"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | |
| | | |
| | | // initMapLine 方法 |
| | | const initMapLine = async (infos = {}, cb = () => { }) => { |
| | | const currentLine = lineList.value.find(item => item.wayline_id == formParams.value.file_id) |
| | | let currentLine = lineList.value.find(item => item.wayline_id == formParams.value.file_id) |
| | | |
| | | |
| | | if (!currentLine) return |
| | | if (!currentLine) { |
| | | currentLine = formParams.value.wayline_file_region_vo |
| | | } |
| | | |
| | | await nextTick() |
| | | if (mapContainerRef.value?.initAddEntity) { |
| | |
| | | formParams.value = { |
| | | ...data |
| | | } |
| | | console.log(formParams.value, '898789') |
| | | drone_sns.value = data.device_list |
| | | initMapLine(data.device_map_infos) |
| | | } else { |
| | |
| | | import AddEditDetails from './component/AddEditDetails.vue' |
| | | import NProgress from 'nprogress' |
| | | import { useStore } from 'vuex' |
| | | import { useRoute } from 'vue-router' |
| | | import { downloadXls } from '@/utils/util' |
| | | import { |
| | | getList, |
| | | saveUpdateOrderLog, |
| | | orderLogDetails, |
| | | orderLogRecall, |
| | | orderLogReject, |
| | | orderLogPass, |
| | | orderLogExport, |
| | | jobStatusNum, |
| | | userPublish, |
| | | deleteOrderLog, |
| | | getWaylineMaxTerrainHeight |
| | | } from '@/api/tickets/orderLog' |
| | | import { newGetWorkspacesPage } from '@/api/resource/wayline' |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz' |
| | |
| | | import { aiImagesPage } from '@/api/dataCenter/dataCenter'; |
| | | |
| | | const store = useStore() |
| | | const route = useRoute() |
| | | |
| | | const userInfo = computed(() => store.state.user.userInfo) |
| | | const permission = computed(() => store.state.user.permission); |
| | | |
| | | console.log(userInfo,permission, '8888') |
| | | |
| | | const isShowAddEditDetails = ref(false) |
| | | |
| | |
| | | activeTab.value = tabsList.value[0].name |
| | | // tab值传 |
| | | orderListParams.status = tabsList.value[0].value |
| | | console.log('8878797', tabsList.value) |
| | | // tabsList.value |
| | | // .map(tab => { |
| | | // if (tab.name === 'all') { |
| | |
| | | ...cloneDeep(orderListParams.searchParams) |
| | | } |
| | | const res = await orderLogExport(apiParams) |
| | | console.log(res, '导出') |
| | | downloadXls(res.data, `智飞工单${dayjs().format('YYYY-MM-DD')}.xlsx`) |
| | | ElMessage.success('导出成功') |
| | | |
| | |
| | | filteredTabs() |
| | | getTableList() |
| | | updateGlobalCounts() |
| | | if (route.query.id) { |
| | | route.query.status === '1' ? handleCheckDetail({ id: route.query.id}, '工单审核') : handleCheckDetail({ id: route.query.id}, '工单详情') |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | |
| | | try { |
| | | const response = await getstatusCount(params) |
| | | const statusCount = response.data.data || {} |
| | | const totalCount = Object.values(statusCount).reduce((sum, count) => sum + (count || 0), 0) |
| | | const totalCount = Object.entries(statusCount).reduce((sum, [key, count]) => { |
| | | if (key === '6') return sum |
| | | return sum + (count || 0) |
| | | }, 0) |
| | | tabs.value.forEach(tab => { |
| | | if (tab.name === 'all') { |
| | | tab.count = totalCount |
| | |
| | | const jumporder = val => { |
| | | if (checked.value === '智飞工单') { |
| | | const id = val.id |
| | | const status = val.status |
| | | getaddOrderRecord(id) |
| | | router.replace({ |
| | | path: `/tickets/orderLog`, |
| | | query: { |
| | | id, |
| | | status, |
| | | }, |
| | | }) |
| | | } else { |
| | |
| | | |
| | | <script setup> |
| | | import useEchartsResize from '@/hooks/useEchartsResize'; |
| | | import { getJobEventByStatus } from '@/api/home/index'; |
| | | import { getJobEventByStatus, getEventStatusNum } from '@/api/home/index'; |
| | | import { getDateRange } from '@/utils/date' |
| | | import overviewImg2 from '@/assets/images/workbench/tc2.svg'; |
| | | import overviewImg3 from '@/assets/images/workbench/tc3.svg'; |
| | | import overviewImg4 from '@/assets/images/workbench/tc4.svg'; |
| | | import overviewImg5 from '@/assets/images/workbench/tc5.svg'; |
| | | import { useRouter } from 'vue-router' |
| | | import _ from 'lodash' |
| | | const router = useRouter() |
| | | let checked = ref('CURRENT_YEAR'); |
| | | let timeListStr = ['本周', '本月', '本年']; |
| | | let timeListEnum = ['CURRENT_WEEK', 'CURRENT_MONTH', 'CURRENT_YEAR']; |
| | | |
| | | const dateRanges = { |
| | | today: getDateRange('today'), |
| | | week: getDateRange('week'), |
| | | month: getDateRange('month'), |
| | | year: getDateRange('year'), |
| | | } |
| | | |
| | | const params = ref({ |
| | | date_enum: 'CURRENT_YEAR', |
| | | // date_enum: 'CURRENT_YEAR', |
| | | device_sn: '', |
| | | end_date: undefined, |
| | | start_date: undefined, |
| | | source:1,//数据来源 |
| | | end_date: dateRanges['year'][1], // undefined, |
| | | start_date: dateRanges['year'][0], // undefined, |
| | | source:1,//数据来源 |
| | | }); |
| | | const dateSelect = ref('CURRENT_YEAR'); |
| | | const eventTypeList = ref([ |
| | |
| | | ]); |
| | | // 工单统计 |
| | | const getTypeData = () => { |
| | | getJobEventByStatus(params.value).then(res => { |
| | | getEventStatusNum(params.value).then(res => { |
| | | const resList = res?.data?.data || []; |
| | | let totalNum = resList.reduce((sum, item) => sum + (item.num || 0), 0) - resList[0].num; |
| | | resList.forEach(item => { |
| | | eventTypeList.value.forEach(item1 => { |
| | | if (item1.name === item.name) { |
| | | item1.value = item.num; |
| | | item1.rate = item.rate; |
| | | item1.rate = _.round((item.num/totalNum)*100, 1); |
| | | } |
| | | }); |
| | | }); |
| | |
| | | |
| | | let timeClick = (item, index) => { |
| | | checked.value = item; |
| | | params.value.date_enum = item; |
| | | // params.value.date_enum = item; |
| | | if(item === 'CURRENT_WEEK') { |
| | | params.value.start_date = dateRanges['week'][0] |
| | | params.value.end_date = dateRanges['week'][1] |
| | | } else if(item === 'CURRENT_MONTH') { |
| | | params.value.start_date = dateRanges['month'][0] |
| | | params.value.end_date = dateRanges['month'][1] |
| | | } else { |
| | | params.value.start_date = dateRanges['year'][0] |
| | | params.value.end_date = dateRanges['year'][1] |
| | | } |
| | | |
| | | dateSelect.value = item; |
| | | getTypeData(); |
| | | }; |
| | |
| | | const echartsRef = ref(null); |
| | | let { chart } = useEchartsResize(echartsRef); |
| | | const initChart = val => { |
| | | const totalNum = val.reduce((sum, item) => sum + item.num, 0); |
| | | let totalNum = val[0].num //val.reduce((sum, item) => sum + item.num, 0); |
| | | const data = { |
| | | total: { |
| | | title: '总计', |
| | |
| | | data: val.map(item => ({ |
| | | value: item.num, |
| | | name: item.name, |
| | | rate: item.rate, |
| | | rate: _.round((item.num/totalNum)*100, 1), |
| | | })), |
| | | }; |
| | | const containerWidth = chart.value.clientWidth; |