Merge branch 'feature/v5.0/5.0.5' into test
17 files modified
1 files added
| | |
| | | const workspaceId = localStorage.getItem(ELocalStorageKey.WorkspaceId) || '' |
| | | |
| | | export const putDeviceProps = (deviceSn, body) => { |
| | | console.log(deviceSn, body, workspaceId, '8888') |
| | | return request({ |
| | | url: `/drone-device-core/manage/api/v1/devices/${workspaceId}/devices/${deviceSn}/property`, |
| | | method: 'put', |
| | | body, |
| | | data: body, |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 设置调色盘 |
| | | * @param {机场编码} deviceSn |
| | |
| | | }) |
| | | } |
| | | |
| | | // 设备下线 |
| | | // 注销 |
| | | export const deviceOffline = (dockSn) => { |
| | | return request({ |
| | | url: `/drone-device-core/manage/api/v1/devices/deviceOffline?dockSn=${dockSn}`, |
| | | method: 'get', |
| | | }) |
| | | } |
| | | |
| | | // 设备下线 |
| | | export const devicesUpdate = (param) => { |
| | | return request({ |
| | | url: `/drone-device-core/manage/api/v1/devices/update`, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | | } |
| | |
| | | <svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| | | <g id="Group 1321315688"> |
| | | <g id="Frame" clip-path="url(#clip0_1238_1817)"> |
| | | <g id="Frame_2" clip-path="url(#clip1_1238_1817)"> |
| | | <path id="Vector" d="M4.83697 10.163H3.10692V8.43298H1.37593V11.029H3.10692V11.894H4.83697V11.029H6.56795V8.43298H4.83697V10.163ZM12.625 8.43298H7.43298V13.625H12.625V8.43298ZM10.894 10.164V11.8949H9.16303V10.163L10.894 10.164ZM12.625 2.375H7.43298V7.56982H12.625V2.375ZM10.894 4.10598V5.83697H9.16303V4.10598H10.894ZM6.56702 2.375H1.375V7.56982H6.56795L6.56702 2.375ZM4.83604 4.10598V5.83697H3.10692V4.10598H4.83604ZM3.10692 11.894H1.37593V13.625H3.10692V11.894ZM6.56795 11.894H4.83697V13.625H6.56795V11.894Z" fill="#212121"/> |
| | | <g id="Group 1321316147"> |
| | | <g id="Frame" clip-path="url(#clip0_1360_1927)"> |
| | | <g id="Frame_2" clip-path="url(#clip1_1360_1927)"> |
| | | <path id="Vector" d="M4.83697 10.163H3.10692V8.43298H1.37593V11.029H3.10692V11.894H4.83697V11.029H6.56795V8.43298H4.83697V10.163ZM12.625 8.43298H7.43298V13.625H12.625V8.43298ZM10.894 10.164V11.8949H9.16303V10.163L10.894 10.164ZM12.625 2.375H7.43298V7.56982H12.625V2.375ZM10.894 4.10598V5.83697H9.16303V4.10598H10.894ZM6.56702 2.375H1.375V7.56982H6.56795L6.56702 2.375ZM4.83604 4.10598V5.83697H3.10692V4.10598H4.83604ZM3.10692 11.894H1.37593V13.625H3.10692V11.894ZM6.56795 11.894H4.83697V13.625H6.56795V11.894Z" fill="#1B94FF"/> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | <defs> |
| | | <clipPath id="clip0_1238_1817"> |
| | | <clipPath id="clip0_1360_1927"> |
| | | <rect width="11" height="11" fill="white" transform="translate(1.5 2.13086)"/> |
| | | </clipPath> |
| | | <clipPath id="clip1_1238_1817"> |
| | | <clipPath id="clip1_1360_1927"> |
| | | <rect width="12" height="12" fill="white" transform="matrix(-1 0 0 1 13 2)"/> |
| | | </clipPath> |
| | | </defs> |
| New file |
| | |
| | | <svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| | | <g id="Group 1321315688"> |
| | | <g id="Frame" clip-path="url(#clip0_1238_1817)"> |
| | | <g id="Frame_2" clip-path="url(#clip1_1238_1817)"> |
| | | <path id="Vector" d="M4.83697 10.163H3.10692V8.43298H1.37593V11.029H3.10692V11.894H4.83697V11.029H6.56795V8.43298H4.83697V10.163ZM12.625 8.43298H7.43298V13.625H12.625V8.43298ZM10.894 10.164V11.8949H9.16303V10.163L10.894 10.164ZM12.625 2.375H7.43298V7.56982H12.625V2.375ZM10.894 4.10598V5.83697H9.16303V4.10598H10.894ZM6.56702 2.375H1.375V7.56982H6.56795L6.56702 2.375ZM4.83604 4.10598V5.83697H3.10692V4.10598H4.83604ZM3.10692 11.894H1.37593V13.625H3.10692V11.894ZM6.56795 11.894H4.83697V13.625H6.56795V11.894Z" fill="#212121"/> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | <defs> |
| | | <clipPath id="clip0_1238_1817"> |
| | | <rect width="11" height="11" fill="white" transform="translate(1.5 2.13086)"/> |
| | | </clipPath> |
| | | <clipPath id="clip1_1238_1817"> |
| | | <rect width="12" height="12" fill="white" transform="matrix(-1 0 0 1 13 2)"/> |
| | | </clipPath> |
| | | </defs> |
| | | </svg> |
| | |
| | | <div class="avue-tags" v-if="setting.tag" @click="contextmenuFlag = false"> |
| | | <!-- tag盒子 --> |
| | | <div v-if="contextmenuFlag" class="avue-tags__contentmenu" |
| | | :style="{ left: contentmenuX + 'px', top: contentmenuY + 'px' }"> |
| | | :style="{ left: contentmenuX + 'px', top: contentmenuY + 'px' }"> |
| | | <div class="item" @click="closeOthersTags">{{ $t('tagsView.closeOthers') }}</div> |
| | | <div class="item" @click="closeAllTags">{{ $t('tagsView.closeAll') }}</div> |
| | | <div class="item" @click="clearCacheTags">{{ $t('tagsView.clearCache') }}</div> |
| | | </div> |
| | | <div class="avue-tags__box"> |
| | | <el-tabs v-model="active" type="card" @contextmenu="handleContextmenu" :closable="tagLen !== 1" |
| | | @tab-click="openTag" @edit="menuTag"> |
| | | @tab-click="openTag" @edit="menuTag"> |
| | | <el-tab-pane v-for="(item, index) in bsTagList" :key="index" :label="generateTitle(item)" :name="item.fullPath"> |
| | | <template #label> |
| | | <span> |
| | | {{ generateTitle(item) }} |
| | | <i class="el-icon-refresh" :class="{ turn: refresh }" @click="handleRefresh" |
| | | v-if="active === item.fullPath"></i> |
| | | v-if="active === item.fullPath"></i> |
| | | </span> |
| | | </template> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <el-dropdown class="avue-tags__menu"> |
| | | <el-button type="primary"> |
| | | <el-button type="primary" style="background: #409eff;border-color: #409eff"> |
| | | {{ $t('tagsView.menu') }} |
| | | <i class="el-icon-arrow-down el-icon--right"></i> |
| | | </el-button> |
| | |
| | | |
| | | /** |
| | | * 根据osd 更新信息 |
| | | * @param deviceSetting |
| | | * @param deviceSetting.value |
| | | * @param deviceInfo |
| | | * @returns |
| | | */ |
| | | export function updateDeviceSettingInfoByOsd(deviceSetting, deviceInfo) { |
| | | const { device, dock, gateway } = deviceInfo || {} |
| | | if (!deviceSetting) { |
| | | // const { device, dock, gateway } = deviceInfo.value || {} |
| | | let device = deviceInfo?? {} |
| | | if (!deviceSetting.value) { |
| | | return |
| | | } |
| | | // 夜航灯 |
| | | let nightLightsState = "" |
| | | if (isNil(device?.night_lights_state)) { |
| | | deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].editable = false |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | nightLightsState = DEFAULT_PLACEHOLDER |
| | | } else { |
| | | deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].editable = true |
| | | deviceSetting.value[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].editable = true |
| | | nightLightsState = device?.night_lights_state |
| | | if (nightLightsState === NightLightsStateEnum.CLOSE) { |
| | | deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].value = "关闭" |
| | | deviceSetting.value[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].value = "关闭" |
| | | } else if (nightLightsState === NightLightsStateEnum.OPEN) { |
| | | deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].value = "开启" |
| | | deviceSetting.value[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].value = "开启" |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } |
| | | } |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET |
| | | ].trueValue = nightLightsState |
| | | |
| | |
| | | let heightLimit = device?.height_limit |
| | | if (isNil(heightLimit) || heightLimit === 0) { |
| | | heightLimit = DEFAULT_PLACEHOLDER |
| | | deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].editable = false |
| | | deviceSetting.value[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].editable = false |
| | | } else { |
| | | deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].editable = true |
| | | deviceSetting.value[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].editable = true |
| | | } |
| | | deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].trueValue = heightLimit |
| | | deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].trueValue = heightLimit |
| | | deviceSetting.value[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].value = |
| | | heightLimit + Unit_M |
| | | |
| | | // 限远 |
| | | let distanceLimitStatus = "" |
| | | if (isNil(device?.distance_limit_status?.state)) { |
| | | distanceLimitStatus = DEFAULT_PLACEHOLDER |
| | | deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].editable = false |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.DISTANCE_LIMIT_SET |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } else { |
| | | deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].editable = true |
| | | deviceSetting.value[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].editable = true |
| | | distanceLimitStatus = device?.distance_limit_status?.state |
| | | if (distanceLimitStatus === DistanceLimitStatusEnum.UNSET) { |
| | | deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].value = "关闭" |
| | | deviceSetting.value[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].value = "关闭" |
| | | } else if (distanceLimitStatus === DistanceLimitStatusEnum.SET) { |
| | | const distanceLimit = device?.distance_limit_status?.distance_limit |
| | | if (distanceLimit) { |
| | | deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].value = |
| | | distanceLimit + Unit_M |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.DISTANCE_LIMIT_SET |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.DISTANCE_LIMIT_SET |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } |
| | | } |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.DISTANCE_LIMIT_SET |
| | | ].trueValue = distanceLimitStatus |
| | | |
| | | // 避障 |
| | | if (isNil(device?.obstacle_avoidance)) { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].trueValue = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].trueValue = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].trueValue = DEFAULT_PLACEHOLDER |
| | | } else { |
| | | const { horizon, upside, downside } = device.obstacle_avoidance || {} |
| | | if (isNil(horizon)) { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].trueValue = DEFAULT_PLACEHOLDER |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].editable = false |
| | | if (horizon === ObstacleAvoidanceStatusEnum.CLOSE) { |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].value = |
| | | "关闭" |
| | | } else if (horizon === ObstacleAvoidanceStatusEnum.OPEN) { |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].value = |
| | | "开启" |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON |
| | | ].trueValue = horizon |
| | | } |
| | | |
| | | if (isNil(upside)) { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].trueValue = DEFAULT_PLACEHOLDER |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].editable = false |
| | | if (upside === ObstacleAvoidanceStatusEnum.CLOSE) { |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].value = |
| | | "关闭" |
| | | } else if (upside === ObstacleAvoidanceStatusEnum.OPEN) { |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].value = |
| | | "开启" |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE |
| | | ].trueValue = upside |
| | | } |
| | | |
| | | if (isNil(downside)) { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].editable = false |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].trueValue = DEFAULT_PLACEHOLDER |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].editable = false |
| | | if (downside === ObstacleAvoidanceStatusEnum.CLOSE) { |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].value = |
| | | "关闭" |
| | | } else if (downside === ObstacleAvoidanceStatusEnum.OPEN) { |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].value = |
| | | deviceSetting.value[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].value = |
| | | "开启" |
| | | } else { |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].value = DEFAULT_PLACEHOLDER |
| | | } |
| | | deviceSetting[ |
| | | deviceSetting.value[ |
| | | DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE |
| | | ].trueValue = downside |
| | | } |
| | | } |
| | | return deviceSetting |
| | | return deviceSetting.value |
| | | } |
| | | |
| | | // 更新formModel |
| | |
| | | deviceSettingFormModelFromOsd, |
| | | deviceInfo |
| | | ) { |
| | | const { device, dock, gateway } = deviceInfo || {} |
| | | if (!deviceSettingFormModelFromOsd) { |
| | | // const { device, dock, gateway } = deviceInfo || {} |
| | | let device = deviceInfo?? {} |
| | | if (!deviceSettingFormModelFromOsd.value) { |
| | | return |
| | | } |
| | | // 夜航灯 |
| | |
| | | !isNil(nightLightsState) && |
| | | nightLightsState === NightLightsStateEnum.OPEN |
| | | ) { |
| | | deviceSettingFormModelFromOsd.nightLightsState = true |
| | | deviceSettingFormModelFromOsd.value.nightLightsState = true |
| | | } else { |
| | | deviceSettingFormModelFromOsd.nightLightsState = false |
| | | deviceSettingFormModelFromOsd.value.nightLightsState = false |
| | | } |
| | | |
| | | // 限高 |
| | | const heightLimit = device?.height_limit |
| | | if (isNil(heightLimit) || heightLimit === 0) { |
| | | deviceSettingFormModelFromOsd.heightLimit = 20 |
| | | deviceSettingFormModelFromOsd.value.heightLimit = 20 |
| | | } else { |
| | | deviceSettingFormModelFromOsd.heightLimit = heightLimit |
| | | deviceSettingFormModelFromOsd.value.heightLimit = heightLimit |
| | | } |
| | | |
| | | // 限远 |
| | |
| | | !isNil(distanceLimitStatus) && |
| | | distanceLimitStatus === DistanceLimitStatusEnum.SET |
| | | ) { |
| | | deviceSettingFormModelFromOsd.distanceLimitStatus.state = true |
| | | deviceSettingFormModelFromOsd.distanceLimitStatus.distanceLimit = |
| | | deviceSettingFormModelFromOsd.value.distanceLimitStatus.state = true |
| | | deviceSettingFormModelFromOsd.value.distanceLimitStatus.distanceLimit = |
| | | device?.distance_limit_status?.distance_limit || 15 |
| | | } else { |
| | | deviceSettingFormModelFromOsd.distanceLimitStatus.state = false |
| | | deviceSettingFormModelFromOsd.distanceLimitStatus.distanceLimit = 15 |
| | | deviceSettingFormModelFromOsd.value.distanceLimitStatus.state = false |
| | | deviceSettingFormModelFromOsd.value.distanceLimitStatus.distanceLimit = 15 |
| | | } |
| | | |
| | | // 避障 |
| | | if (isNil(device?.obstacle_avoidance)) { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceHorizon = false |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceUpside = false |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceDownside = false |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceHorizon = false |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceUpside = false |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceDownside = false |
| | | } else { |
| | | const { horizon, upside, downside } = device.obstacle_avoidance || {} |
| | | if (!isNil(horizon) && horizon === ObstacleAvoidanceStatusEnum.OPEN) { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceHorizon = true |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceHorizon = true |
| | | } else { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceHorizon = false |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceHorizon = false |
| | | } |
| | | if (!isNil(upside) && upside === ObstacleAvoidanceStatusEnum.OPEN) { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceUpside = true |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceUpside = true |
| | | } else { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceUpside = false |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceUpside = false |
| | | } |
| | | if (!isNil(downside) && downside === ObstacleAvoidanceStatusEnum.OPEN) { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceDownside = true |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceDownside = true |
| | | } else { |
| | | deviceSettingFormModelFromOsd.obstacleAvoidanceDownside = false |
| | | deviceSettingFormModelFromOsd.value.obstacleAvoidanceDownside = false |
| | | } |
| | | } |
| | | return deviceSettingFormModelFromOsd |
| | | return deviceSettingFormModelFromOsd.value |
| | | } |
| | |
| | | calcHeight: 20, |
| | | column: [ |
| | | { |
| | | label: '工作空间名称', |
| | | label: '设备名称',// '工作空间名称', |
| | | prop: 'workspace_name', |
| | | editDisabled: true, |
| | | searchLabelWidth: 130, |
| | |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入工作空间名称', |
| | | message: '请输入设备名称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '工作空间描述', |
| | | prop: 'workspace_desc', |
| | | labelWidth: 130, |
| | | // search: true, |
| | | searchSpan: 4, |
| | | // editDisabled: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入工作空间描述', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '平台名称', |
| | | label: '系统名称',// '平台名称', |
| | | prop: 'platform_name', |
| | | labelWidth: 130, |
| | | editDisabled: true, |
| | | rules: [ |
| | | { |
| | | required: false, |
| | | message: '请输入平台名称', |
| | | message: '请输入系统名称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | { |
| | | label: '所属单位', |
| | | prop: 'dept_id', |
| | |
| | | ], |
| | | }, |
| | | { |
| | | label: '设备描述',// '工作空间描述', |
| | | prop: 'workspace_desc', |
| | | labelWidth: 130, |
| | | // search: true, |
| | | searchSpan: 4, |
| | | // editDisabled: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入设备描述', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | { |
| | | label: '创建时间', |
| | | prop: 'create_time', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | overHidden: true, |
| | | type: 'date', |
| | | labelWidth: 130, |
| | | width: 160, |
| | |
| | | |
| | | }, |
| | | { |
| | | label: '行政区划', |
| | | label: '设备位置',// '行政区划', |
| | | prop: 'area_code', |
| | | type: 'cascader', |
| | | labelWidth: 130, |
| | |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择行政区划', |
| | | message: '请选择设备位置', |
| | | trigger: 'change', |
| | | }, |
| | | ], |
| | |
| | | :percentage="row.firmware_progress"></el-progress> |
| | | </div> |
| | | </template> |
| | | <template #domain="{ row }"> |
| | | <span class="text"> |
| | | {{ row.domain == 3 ? '机巢' : row.domain == 0 ? '无人机' : '其他' }} |
| | | </span> |
| | | </template> |
| | | <template #mode_code="{ row }"> |
| | | <span class="text" v-if="row.domain == 3" :style="row.mode_code != '-1' ? 'color: #00ee8b' : 'color: #de5e5e'"> |
| | | {{ getDockModeText(row.mode_code) }} |
| | | <span class="text" v-if="row.domain == 3 || row.domain == 0" :style="row.mode_code != '-1' ? 'color: #00ee8b' : 'color: #de5e5e'"> |
| | | {{ getModelText(row.mode_code) }} |
| | | </span> |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button type="primary" text icon="el-icon-paperclip" v-if="permission.oss_set" |
| | | @click.stop="handleOpenOssSet(scope.row, scope.index)">存储配置 |
| | | </el-button> |
| | | <el-button type="primary" text icon="el-icon-share" v-if="permission.per_share && scope.row.domain == 3" |
| | | @click.stop="handleOpenDevicePerShare(scope.row, scope.index)">机场授权 |
| | | </el-button> |
| | | |
| | | <el-button type="primary" text icon="el-icon-position" :disabled="!scope.row.status" |
| | | v-if="permission.rang_con && scope.row.domain == 3" |
| | | @click.stop="handleOpenRemoteDebugging(scope.row, scope.index)">远程调试 |
| | | </el-button> |
| | | |
| | | <el-button type="primary" text icon="el-icon-setting" v-if="permission.fly_device_offline" |
| | | @click.stop="handleDeviceOffline(scope.row)">设备下线 |
| | | </el-button> |
| | | <el-dropdown> |
| | | <el-button type="primary" text icon="el-icon-more" v-if="permission.oss_set">更 多</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" @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" |
| | | @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" |
| | | @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> |
| | | <el-dropdown-item command="d"> |
| | | <el-button type="primary" text icon="el-icon-collection" v-if="!scope.row.status" @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" |
| | | @click.stop="handleDeviceOffline(scope.row)">注销</el-button> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | <template #dropdown v-else> |
| | | <el-dropdown-menu teleported> |
| | | <el-dropdown-item command="a"> |
| | | <el-button type="primary" text icon="el-icon-circle-close" @click.stop="rowDel(scope.row, scope.index)">删除</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="a"> |
| | | <el-button type="primary" text icon="el-icon-key" v-if="permission.operate_password_set" @click.stop="handleOperatePassword(scope.row, scope.index)">操控密码设置</el-button> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </template> |
| | | |
| | | <!-- 添加行政区划显示模板 --> |
| | | <template #area_code="{ row }"> |
| | | <span>{{ row.area_name }}</span> |
| | | </template> |
| | | </avue-crud> |
| | | |
| | | <el-dialog title="操控密码设置" append-to-body v-model="operatePasswordSetBox" width="450px"> |
| | | <el-form :model="passwordForm" ref="passwordForm" label-width="80px" :rules="rules" v-loading="loadingForm"> |
| | | <el-form-item label="密码" prop="password"> |
| | | <el-input type="password" v-model="passwordForm.password" placeholder="请输入密码" show-password></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="确认密码" prop="password2"> |
| | | <el-input type="password" v-model="passwordForm.password2" placeholder="请输入确认密码" show-password></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="operatePasswordSetBox = false">取 消</el-button> |
| | | <el-button type="primary" @click="setOperatePasswordConfirm">确 定</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="操控密码查看" append-to-body v-model="operatePasswordViewBox" width="455px"> |
| | | <el-input v-model="operate_password" disabled></el-input> |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="固件升级" append-to-body v-model="firmwareBox" width="455px"> |
| | | <div>升级固件版本:{{ firmwareVersion }}</div> |
| | |
| | | |
| | | <script> |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | |
| | | import { pxToRem } from '@/utils/rem' |
| | | import { |
| | | getList, |
| | | remove, |
| | |
| | | ota, |
| | | getDeviceFirmwareList, |
| | | getDevices, |
| | | deviceOffline |
| | | deviceOffline, |
| | | devicesUpdate |
| | | } from '@/api/device/device' |
| | | import { deleteByOssId, addOrUpdate as addOrUpdateOssBind } from '@/api/device/ossBind' |
| | | import { getListPage as getOssList } from '@/api/resource/oss' |
| | |
| | | DockControlPanel, |
| | | }, |
| | | data () { |
| | | const validatePass = (rule, value, callback) => { |
| | | if (value === '') { |
| | | callback(new Error('请输入密码')) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | const validatePass2 = (rule, value, callback) => { |
| | | if (value === '') { |
| | | callback(new Error('请再次输入密码')) |
| | | } else if (value !== this.passwordForm.password) { |
| | | callback(new Error('两次输入密码不一致!')) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | return { |
| | | rules: { |
| | | password: [{ required: true, validator: validatePass, trigger: 'blur' }], |
| | | password2: [{ required: true, validator: validatePass2, trigger: 'blur' }], |
| | | }, |
| | | passwordForm: { |
| | | id: '', |
| | | password: '', |
| | | password2: '', |
| | | }, |
| | | operatePasswordSetBox: false, |
| | | operatePasswordViewBox: false, |
| | | operate_password: '', |
| | | bindOssId: null, |
| | | deviceSn: '', |
| | | ossSetBox: false, |
| | |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | delBtn: false, |
| | | selection: true, |
| | | excelBtn: false, |
| | | addBtn: false, |
| | |
| | | |
| | | column: [ |
| | | { |
| | | label: '设备类型', |
| | | prop: 'domain', |
| | | editDisabled: true, |
| | | editDisplay: false, //编辑显示 |
| | | viewDisplay: true, //查看显示 |
| | | search: false, |
| | | slot: true, |
| | | searchSpan: 4, |
| | | labelWidth: 130, |
| | | width: 120, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备类型', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '设备型号', |
| | | prop: 'device_name', |
| | | editDisabled: true, |
| | | search: true, |
| | | viewDisplay: true, //查看显示 |
| | | search: false, |
| | | searchSpan: 4, |
| | | labelWidth: 130, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入设备型号', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | width: 120, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备型号', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '设备SN', |
| | | prop: 'device_sn', |
| | | labelWidth: 130, |
| | | search: true, |
| | | width: 120, |
| | | overHidden: true, |
| | | searchSpan: 4, |
| | | editDisabled: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入设备SN', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备SN', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | // { |
| | | // label: '机巢编号', |
| | | // prop: 'machine_nest_sn', |
| | | // labelWidth: 130, |
| | | // editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: false, |
| | | // message: '请输入机巢编号', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | { |
| | | label: '机巢编号', |
| | | prop: 'machine_nest_sn', |
| | | labelWidth: 130, |
| | | editDisabled: true, |
| | | rules: [ |
| | | { |
| | | required: false, |
| | | message: '请输入机巢编号', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '设备组织名称', |
| | | label: '设备名称', |
| | | prop: 'nickname', |
| | | labelWidth: 130, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入设备组织名称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '固件版本', |
| | | prop: 'firmware_version', |
| | | labelWidth: 130, |
| | | width: 100, |
| | | editDisabled: true, |
| | | searchSpan: 4, |
| | | search: true, |
| | | overHidden: true, |
| | | editDisplay: true, //编辑显示 |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入固件版本', |
| | | message: '请输入设备名称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '固件升级', |
| | | prop: 'firmware_status', |
| | | labelWidth: 130, |
| | | width: 100, |
| | | viewDisabled: true, |
| | | addDisabled: true, |
| | | editDisabled: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入固件升级', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '所属单位', |
| | | prop: 'dept_name', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | labelWidth: 130, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入所属单位', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '所属单位', |
| | | prop: 'dept_id', |
| | | hide: true, |
| | | type: 'tree', |
| | | defaultExpandAll: true, |
| | | labelWidth: 130, |
| | | dicUrl: '/blade-system/dept/getTree', |
| | | props: { |
| | | label: 'name', |
| | | value: 'id', |
| | | }, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入所属单位', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '加入组织时间', |
| | | prop: 'bound_time', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | type: 'date', |
| | | labelWidth: 130, |
| | | width: 160, |
| | | format: 'YYYY-MM-DD HH:mm:ss', |
| | | // valueFormat: 'YYYY-MM-DD HH:mm:ss', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入在线状态', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '行政区划', |
| | | label: '设备位置',// '行政区划', |
| | | prop: 'area_name', |
| | | hide: true, |
| | | // hide: true, |
| | | overHidden: true, |
| | | editDisplay: false, //编辑显示 |
| | | viewDisplay: true, //查看显示 |
| | | viewDisplay: false, //查看显示 |
| | | labelWidth: 130, |
| | | width: 100, |
| | | }, |
| | | { |
| | | label: '行政区划', |
| | | label: '设备位置', |
| | | prop: 'area_code', |
| | | type: 'cascader', |
| | | labelWidth: 130, |
| | | searchSpan: 4, |
| | | hide: true, |
| | | search: true, |
| | | // overHidden: true, |
| | | editDisplay: true, |
| | | viewDisplay: false, |
| | | viewDisplay: true, |
| | | props: { |
| | | label: 'title', |
| | | value: 'value', |
| | |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择行政区划', |
| | | message: '请选择设备位置', |
| | | trigger: 'change', |
| | | }, |
| | | ], |
| | |
| | | } |
| | | }, |
| | | }, |
| | | // { |
| | | // label: '设备位置', |
| | | // prop: 'address', |
| | | // labelWidth: 130, |
| | | // width: 100, |
| | | // overHidden: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入设备位置', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | |
| | | { |
| | | label: '负载设备', |
| | | prop: 'payload_str', |
| | | labelWidth: 130, |
| | | width: 100, |
| | | overHidden: true, |
| | | editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入负载设备', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | // { |
| | | // label: '保险有效期', |
| | | // prop: 'insureExpiredTime', |
| | | // labelWidth: 130, |
| | | // width: 110, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入保险有效期', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | { |
| | | label: '流量剩余', |
| | | prop: 'traffic_remaining', |
| | | labelWidth: 130, |
| | | width: 100, |
| | | editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入流量剩余', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '流量到期时间', |
| | | prop: 'traffic_expire_time', |
| | | labelWidth: 130, |
| | | width: 120, |
| | | type: 'date', |
| | | format: 'YYYY-MM-DD', |
| | | editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入流量到期时间', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '固件版本', |
| | | prop: 'firmware_version', |
| | | labelWidth: 130, |
| | | width: 110, |
| | | editDisabled: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入固件版本', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '固件升级', |
| | | prop: 'firmware_status', |
| | | labelWidth: 130, |
| | | width: 100, |
| | | hide: true, |
| | | viewDisabled: true, |
| | | addDisabled: true, |
| | | editDisabled: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入固件升级', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '所属单位', |
| | | prop: 'dept_name', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | labelWidth: 130, |
| | | width: 180, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入所属单位', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '所属单位', |
| | | prop: 'dept_id', |
| | | hide: true, |
| | | type: 'tree', |
| | | defaultExpandAll: true, |
| | | search: true, |
| | | searchSpan: 4, |
| | | labelWidth: 130, |
| | | dicUrl: '/blade-system/dept/getTree', |
| | | props: { |
| | | label: 'name', |
| | | value: 'id', |
| | | }, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入所属单位', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | // { |
| | | // label: '加入组织时间', |
| | | // prop: 'bound_time', |
| | | // addDisplay: false, |
| | | // editDisplay: false, |
| | | // type: 'date', |
| | | // labelWidth: 130, |
| | | // width: 160, |
| | | // format: 'YYYY-MM-DD HH:mm:ss', |
| | | // // valueFormat: 'YYYY-MM-DD HH:mm:ss', |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入在线状态', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | |
| | | |
| | | { |
| | | hide: true, |
| | |
| | | label: '在线时间', |
| | | prop: 'login_time', |
| | | type: 'date', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | editDisplay: true, //编辑显示 |
| | | editDisabled: true, |
| | | viewDisplay: true, //查看显示 |
| | | addDisplay: true, |
| | | labelWidth: 130, |
| | | width: 160, |
| | | overHidden: true, |
| | | format: 'YYYY-MM-DD HH:mm:ss', |
| | | // valueFormat: 'YYYY-MM-DD HH:mm:ss', |
| | | startPlaceholder: '任务开始时间', |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入在线时间', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '注册时间', |
| | | prop: 'create_time', |
| | | type: 'date', |
| | | editDisplay: true, //编辑显示 |
| | | editDisabled: true, |
| | | viewDisplay: true, //查看显示 |
| | | addDisplay: true, |
| | | overHidden: true, |
| | | labelWidth: 130, |
| | | width: 160, |
| | | format: 'YYYY-MM-DD HH:mm:ss', |
| | | // valueFormat: 'YYYY-MM-DD HH:mm:ss', |
| | | startPlaceholder: '任务开始时间', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入在线时间', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | startPlaceholder: '创建时间', |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入创建时间', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | }, |
| | | { |
| | | label: '在线状态', |
| | | label: '设备状态', |
| | | prop: 'cnstatus', |
| | | hide: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: true, |
| | | viewDisplay: false, |
| | | labelWidth: 130, |
| | | }, |
| | | { |
| | | label: '在线状态', |
| | | label: '设备状态', |
| | | prop: 'status', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | labelWidth: 130, |
| | | labelWidth: 100, |
| | | hide: true, |
| | | // searchSpan: 4, |
| | | // search: true, |
| | | slot: true, |
| | | width: 100, |
| | | |
| | |
| | | ], |
| | | }, |
| | | { |
| | | label: '机场状态', |
| | | label: '设备状态', |
| | | prop: 'cnmode_code', |
| | | hide: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: true, |
| | | labelWidth: 130, |
| | | width: 110, |
| | | }, |
| | | { |
| | | label: '机场状态', |
| | | label: '设备状态', |
| | | prop: 'mode_code', |
| | | |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | labelWidth: 130, |
| | | searchSpan: 4, |
| | | search: true, |
| | | type: 'select', |
| | | dicData: [ |
| | | { label: '在线', value: 0 }, |
| | | { label: '离线', value: -1 }, |
| | | { label: '远程调试', value: 2 }, |
| | | { label: '现场调试', value: 1 }, |
| | | { label: '固件升级中', value: 3 } |
| | | ], |
| | | slot: true, |
| | | width: 100, |
| | | width: 110, |
| | | |
| | | rules: [ |
| | | { |
| | |
| | | } |
| | | }) |
| | | }, |
| | | mounted() { |
| | | |
| | | }, |
| | | methods: { |
| | | getDockModeText (value) { |
| | | return EDockModeText[value] || '' |
| | | }, |
| | | getModelText (value) { |
| | | let txt = '离线' |
| | | if (value === 0 || value === 4) { |
| | | txt = '在线' |
| | | } else if(value === 1) { |
| | | txt = '现场调试' |
| | | } else if(value === 2) { |
| | | txt = '远程调试' |
| | | } else if(value === 3) { |
| | | txt = '固件升级中' |
| | | } |
| | | return txt |
| | | }, |
| | | // 关闭所有的webscoket |
| | | closeAllWebsoket () { |
| | |
| | | |
| | | // 设备下线 |
| | | handleDeviceOffline (row) { |
| | | ElMessageBox.confirm('确定下线该设备吗?', '提示', { |
| | | ElMessageBox.confirm('确定注销该设备吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | |
| | | .then(() => { |
| | | deviceOffline(row.device_sn) |
| | | .then(res => { |
| | | ElMessage.success('下线成功') |
| | | ElMessage.success('注销成功') |
| | | |
| | | this.init() |
| | | }) |
| | | .catch(error => { |
| | | ElMessage.error('下线失败') |
| | | ElMessage.error('注销失败') |
| | | }) |
| | | }) |
| | | .catch(() => { }) |
| | |
| | | this.$nextTick(() => { |
| | | that.$refs.firmwareManage.init(row) |
| | | }) |
| | | }, |
| | | // 设备下线 |
| | | dockNotLine(row) { |
| | | let txt = row.hidden_flag === 1?'上线':'下线' |
| | | ElMessageBox.confirm(`确定${txt}该设备吗?`, '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | let hidden_flag = row.hidden_flag === 1?0:1 |
| | | devicesUpdate({id:row.id, hidden_flag:hidden_flag}) |
| | | .then(res => { |
| | | ElMessage.success('下线成功') |
| | | this.init() |
| | | }) |
| | | .catch(error => { |
| | | ElMessage.error('下线失败') |
| | | }) |
| | | }) |
| | | .catch(() => { }) |
| | | }, |
| | | // 版本回退点击事件 |
| | | rollFirmware (row) { |
| | |
| | | area_code: await this.getFullAreaCode(data.area_code), |
| | | area_name: this.form.area_name, |
| | | cnmode_code: this.getDockModeText(this.form.mode_code), |
| | | domain: data.domain === 0 ? '无人机' : data.domain === 3 ? '机巢' : '未知', |
| | | cnstatus: this.form.status === false ? '离线' : '在线', |
| | | duration_of_insurance: [data?.insure_start_time || '', data?.insure_expired_time || ''], |
| | | } |
| | |
| | | const data = res.data.data.records |
| | | resolve(data) |
| | | }) |
| | | }, |
| | | rowDel (row) { |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(row.id) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | }) |
| | | }, |
| | | // 设置无人机操作密码 |
| | | setOperatePasswordConfirm () { |
| | | var that = this |
| | | this.$refs.passwordForm.validate(valid => { |
| | | if (valid) { |
| | | this.loadingForm = true |
| | | const data = { |
| | | id: this.passwordForm.id, |
| | | operate_password: this.passwordForm.password, |
| | | } |
| | | // 提交 |
| | | operatePasswordUpdate(data).then(res => { |
| | | this.loadingForm = false |
| | | this.operatePasswordSetBox = false |
| | | that.passwordForm = {} |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | }) |
| | | } else { |
| | | console.log('error submit!!') |
| | | return false |
| | | } |
| | | }) |
| | | }, |
| | | // 操作密码设置 |
| | | handleOperatePassword (row) { |
| | | this.operatePasswordSetBox = true |
| | | this.passwordForm.id = row.id |
| | | }, |
| | | }, |
| | | } |
| | |
| | | border-color: #409eff; |
| | | } |
| | | } |
| | | :deep(.avue-crud__menu) { |
| | | display: flex; |
| | | } |
| | | .more-container { |
| | | position: relative; |
| | | } |
| | | .show-more-do { |
| | | position: absolute; |
| | | background-color: #ffffff; |
| | | // border: 1px solid #409eff; |
| | | z-index: 9999; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); |
| | | width: 140px; |
| | | font-size: 12px; |
| | | // height: 140px; |
| | | height: 190px; |
| | | right: 0; |
| | | } |
| | | |
| | | |
| | | </style> |
| | |
| | | <span class="form-label" |
| | | >{{ deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].label }}:</span |
| | | > |
| | | <a-switch |
| | | checked-children="开" |
| | | un-checked-children="关" |
| | | v-model:checked="deviceSettingFormModel.nightLightsState" |
| | | <el-switch |
| | | active-text="开" |
| | | inactive-text="关" |
| | | v-model="deviceSettingFormModel.nightLightsState" |
| | | /> |
| | | </div> |
| | | </template> |
| | | <a |
| | | @click=" |
| | | @click.stop=" |
| | | onShowPopConfirm( |
| | | deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].settingKey |
| | | ) |
| | |
| | | <template #formContent> |
| | | <div class="form-content"> |
| | | <span class="form-label" |
| | | >{{ deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].label }}:</span |
| | | >{{ deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].label }}:(m)</span |
| | | > |
| | | <a-input-number |
| | | v-model:value="deviceSettingFormModel.heightLimit" |
| | | <el-input-number |
| | | size="small" |
| | | v-model="deviceSettingFormModel.heightLimit" |
| | | :min="20" |
| | | :max="1500" |
| | | /> |
| | | m |
| | | |
| | | </div> |
| | | </template> |
| | | <a |
| | |
| | | <span class="form-label" |
| | | >{{ deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].label }}:</span |
| | | > |
| | | <a-switch |
| | | <el-switch |
| | | style="margin-right: 10px" |
| | | checked-children="开" |
| | | un-checked-children="关" |
| | | v-model:checked="deviceSettingFormModel.distanceLimitStatus.state" |
| | | active-text="开" |
| | | inactive-text="关" |
| | | v-model="deviceSettingFormModel.distanceLimitStatus.state" |
| | | /> |
| | | <a-input-number |
| | | v-model:value="deviceSettingFormModel.distanceLimitStatus.distanceLimit" |
| | | <el-input-number |
| | | size="small" |
| | | v-model="deviceSettingFormModel.distanceLimitStatus.distanceLimit" |
| | | :min="15" |
| | | :max="8000" |
| | | /> |
| | |
| | | <span class="form-label" |
| | | >{{ deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].label }}:</span |
| | | > |
| | | <a-switch |
| | | checked-children="开" |
| | | un-checked-children="关" |
| | | v-model:checked="deviceSettingFormModel.obstacleAvoidanceHorizon" |
| | | <el-switch |
| | | active-text="开" |
| | | inactive-text="关" |
| | | v-model="deviceSettingFormModel.obstacleAvoidanceHorizon" |
| | | /> |
| | | </div> |
| | | </template> |
| | |
| | | <span class="form-label" |
| | | >{{ deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].label }}:</span |
| | | > |
| | | <a-switch |
| | | checked-children="开" |
| | | un-checked-children="关" |
| | | v-model:checked="deviceSettingFormModel.obstacleAvoidanceUpside" |
| | | <el-switch |
| | | active-text="开" |
| | | inactive-text="关" |
| | | v-model="deviceSettingFormModel.obstacleAvoidanceUpside" |
| | | /> |
| | | </div> |
| | | </template> |
| | |
| | | deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].label |
| | | }}:</span |
| | | > |
| | | <a-switch |
| | | checked-children="开" |
| | | un-checked-children="关" |
| | | v-model:checked="deviceSettingFormModel.obstacleAvoidanceDownside" |
| | | <el-switch |
| | | active-text="开" |
| | | inactive-text="关" |
| | | v-model="deviceSettingFormModel.obstacleAvoidanceDownside" |
| | | /> |
| | | </div> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { defineProps, ref, watch } from 'vue'; |
| | | import { defineProps, inject, ref, watch } from 'vue'; |
| | | import { ELocalStorageKey } from '@/types' |
| | | import { cloneDeep } from 'lodash'; |
| | | import { initDeviceSetting, initDeviceSettingFormModel } from '@/types/device-setting'; |
| | | import { initDeviceSetting, initDeviceSettingFormModel, DeviceSettingKeyEnum } from '@/types/device-setting'; |
| | | import { |
| | | updateDeviceSettingInfoByOsd, |
| | | updateDeviceSettingFormModelByOsd, |
| | | } from '@/utils/device-setting'; |
| | | import { useDeviceSetting } from './use-device-setting'; |
| | | import DeviceSettingPopover from './DeviceSettingPopover.vue' |
| | | |
| | | const props = defineProps(); |
| | | // const props = defineProps(); |
| | | const props = defineProps(['sn', 'deviceInfo']) |
| | | |
| | | const deviceSetting = ref(cloneDeep(initDeviceSetting)); |
| | | const deviceSettingFormModelFromOsd = ref(cloneDeep(initDeviceSettingFormModel)); |
| | | // const deviceSetting = ref(cloneDeep(initDeviceSetting)); |
| | | // const deviceSettingFormModelFromOsd = ref(cloneDeep(initDeviceSettingFormModel)); |
| | | const deviceSettingFormModel = ref(cloneDeep(initDeviceSettingFormModel)); // 真实使用的formModel |
| | | |
| | | const deviceSetting = inject('deviceSetting') |
| | | const deviceSettingFormModelFromOsd = inject('deviceSettingFormModelFromOsd') |
| | | // 根据设备osd信息更新信息 |
| | | watch( |
| | | () => props.deviceInfo, |
| | | value => { |
| | | updateDeviceSettingInfoByOsd(deviceSetting.value, value); |
| | | updateDeviceSettingFormModelByOsd(deviceSettingFormModelFromOsd.value, value); |
| | | // console.log('9999',value) |
| | | // updateDeviceSettingInfoByOsd(deviceSetting, value); |
| | | // updateDeviceSettingFormModelByOsd(deviceSettingFormModelFromOsd, value); |
| | | // console.log('deviceInfo', value) |
| | | }, |
| | | { |
| | |
| | | async function onConfirm(settingKey) { |
| | | deviceSetting.value[settingKey].popConfirm.loading = true; |
| | | const body = genDevicePropsBySettingKey(settingKey, deviceSettingFormModel.value); |
| | | localStorage.setItem(ELocalStorageKey.WorkspaceId, props.deviceInfo.workspace_id) |
| | | await setDeviceProps(props.sn, body); |
| | | deviceSetting.value[settingKey].popConfirm.loading = false; |
| | | deviceSetting.value[settingKey].popConfirm.visible = false; |
| | |
| | | |
| | | <style lang="scss" scoped> |
| | | .device-setting-wrapper { |
| | | border-bottom: 1px solid #515151; |
| | | //border-bottom: 1px solid #515151; |
| | | |
| | | .device-setting-header { |
| | | font-size: 14px; |
| | |
| | | font-weight: 700; |
| | | } |
| | | } |
| | | .control-setting-item-right { |
| | | .el-tooltip__trigger { |
| | | color: #1C5CFF; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | <template> |
| | | <a-popover |
| | | <el-popover |
| | | :visible="state.sVisible" |
| | | trigger="click" |
| | | v-bind="$attrs" |
| | | :overlay-class-name="overlayClassName" |
| | | placement="bottom" |
| | | @visibleChange="" |
| | | v-on="$attrs" |
| | | width="200" |
| | | > |
| | | <template #content> |
| | | <template #default> |
| | | <div class="title-content"></div> |
| | | <slot name="formContent" /> |
| | | <div class="uranus-popconfirm-btns"> |
| | | <a-button size="sm" @click="onCancel"> |
| | | <el-button @click="onCancel"> |
| | | {{ cancelText || '取消' }} |
| | | </a-button> |
| | | <a-button |
| | | size="sm" |
| | | </el-button> |
| | | <el-button |
| | | :loading="loading" |
| | | type="primary" |
| | | class="confirm-btn" |
| | | @click="onConfirm" |
| | | > |
| | | {{ okText || '确定' }} |
| | | </a-button> |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | <template v-if="$slots.default"> |
| | | <template #reference> |
| | | <slot></slot> |
| | | </template> |
| | | </a-popover> |
| | | </el-popover> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { defineProps, defineEmits, reactive, watch, computed } from 'vue'; |
| | | |
| | | const props = defineProps(); |
| | | const props = defineProps(['visible', 'loading', 'disabled', 'title', 'cancelText', 'okText', 'width']); |
| | | |
| | | const emit = defineEmits(['cancel', 'confirm']); |
| | | |
| | |
| | | <!-- title --> |
| | | |
| | | <!-- setting --> |
| | | <!-- <DeviceSettingBox :sn="props.sn" :deviceInfo="props.deviceInfo"></DeviceSettingBox> --> |
| | | <DeviceSettingBox :sn="props.sn" :deviceInfo="props.deviceInfo"></DeviceSettingBox> |
| | | <!-- cmd --> |
| | | <div class="control-cmd-wrapper"> |
| | | <div class="control-cmd-header"> |
| | |
| | | import { cmdList as baseCmdList } from '@/types/device-cmd' |
| | | import { useDockControl } from './use-dock-control' |
| | | import { EDockModeCode } from '@/types/device' |
| | | import { updateDeviceSettingFormModelByOsd, updateDeviceSettingInfoByOsd } from '@/utils/device-setting'; |
| | | import { initDeviceSetting, initDeviceSettingFormModel } from '@/types/device-setting'; |
| | | import { updateDeviceCmdInfoByOsd, updateDeviceCmdInfoByExecuteInfo } from '@/utils/device-cmd' |
| | | import { setThermalCurrentPaletteStyle, setPhotoStorageSet, setVideoStorageSet, getLiveStatus, setStreamsSwitch, photoAndVideoCmd } from '@/api/device-setting' |
| | | |
| | | import DeviceSettingBox from './DeviceSettingBox.vue' |
| | | import Store from '@/store' |
| | | import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'; |
| | | import { getWebsocketUrl } from '@/utils/websocket/config'; |
| | | import EventBus from '@/utils/eventBus'; |
| | | import { cloneDeep } from 'lodash'; |
| | | |
| | | const valueStyle = ref(0) |
| | | const cameraModeValue = ref(0) |
| | | const videoValue = ref("zoom") |
| | | const photo_storage_settings = ref([]) |
| | | const video_storage_settings = ref([]) |
| | | |
| | | |
| | | |
| | | let deviceSetting = ref(cloneDeep(initDeviceSetting)); |
| | | const deviceSettingFormModelFromOsd = ref(cloneDeep(initDeviceSettingFormModel)); |
| | | |
| | | provide('deviceSetting', deviceSetting) |
| | | provide('deviceSettingFormModelFromOsd', deviceSettingFormModelFromOsd) |
| | | |
| | | // 定义一个数据videoList |
| | | const videoList = reactive([]) |
| | |
| | | watch( |
| | | () => Store.getters.deviceState, |
| | | 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 |
| | | const devices = {} |
| | |
| | | } |
| | | deviceInfo = ref(value.deviceInfo[props.deviceInfo.child_sn]) |
| | | updateDeviceCmdInfoByOsd(cmdList.value, devices) |
| | | // by cpz |
| | | updateDeviceSettingInfoByOsd(deviceSetting, value.deviceInfo[props.deviceInfo.child_sn]); |
| | | updateDeviceSettingFormModelByOsd(deviceSettingFormModelFromOsd, value.deviceInfo[props.deviceInfo.child_sn]) |
| | | } |
| | | }, |
| | | { |
| | |
| | | NightLightsStateEnum, |
| | | DistanceLimitStatusEnum, |
| | | } from '@/types/device-setting'; |
| | | import { messages } from '@/lang'; |
| | | |
| | | export function useDeviceSetting() { |
| | | // 生成参数 |
| | |
| | | // 设置设备属性 |
| | | async function setDeviceProps(sn, body) { |
| | | try { |
| | | const { code, message: msg } = await putDeviceProps(sn, body); |
| | | if (code === 0) { |
| | | return true; |
| | | } |
| | | throw msg; |
| | | } catch (e) { |
| | | ElMessage({ |
| | | message: '设备属性设置失败', |
| | | type: 'error', |
| | | await putDeviceProps(sn, body).then(res => { |
| | | if (res.data.code === 0) { |
| | | ElMessage({ |
| | | message: '设备属性设置成功!', |
| | | type: 'success', |
| | | }); |
| | | } |
| | | }); |
| | | } catch (e) { |
| | | return false; |
| | | } |
| | | } |
| | |
| | | --> |
| | | <template> |
| | | <basic-container> |
| | | <el-tabs v-model="activeName" @tab-click="handleClick"> |
| | | <airport ref="airport" /> |
| | | <!-- <el-tabs v-model="activeName" @tab-click="handleClick"> |
| | | <el-tab-pane label="机场" name="1"> |
| | | <airport ref="airport" /> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="飞行器" name="2"> |
| | | <fly ref="fly" /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-tabs> --> |
| | | </basic-container> |
| | | </template> |
| | | |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" ref="crud" @row-del="rowDel" |
| | | v-model="form" :permission="permissionList" @row-update="rowUpdate" @row-save="rowSave" :before-open="beforeOpen" |
| | | @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange" |
| | | @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad"> |
| | | <avue-crud |
| | | :option="option" |
| | | :table-loading="loading" |
| | | :data="data" |
| | | v-model:page="page" |
| | | ref="crud" |
| | | @row-del="rowDel" |
| | | v-model="form" |
| | | :permission="permissionList" |
| | | @row-update="rowUpdate" |
| | | @row-save="rowSave" |
| | | :before-open="beforeOpen" |
| | | :before-close="beforeClose" |
| | | @search-change="searchChange" |
| | | @search-reset="searchReset" |
| | | @selection-change="selectionChange" |
| | | @current-change="currentChange" |
| | | @size-change="sizeChange" |
| | | @refresh-change="refreshChange" |
| | | @on-load="onLoad" |
| | | > |
| | | <template #menu-left> |
| | | <!-- <el-button |
| | | type="danger" |
| | |
| | | {{ formatSeconds(row.processingTime) }} |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button type="primary" text icon="el-icon-guide" |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="el-icon-guide" |
| | | v-if="permission.odm_task_handle && scope.row.taskId == null" |
| | | @click.stop="atHandle(scope.row, scope.index)">立即启动 |
| | | @click.stop="atHandle(scope.row, scope.index)" |
| | | >立即启动 |
| | | </el-button> |
| | | <el-button type="primary" text icon="el-icon-refresh-right" |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="el-icon-refresh-right" |
| | | v-if="(permission.odm_task_handle && scope.row.status == 30) || scope.row.status == 50" |
| | | @click.stop="restartHandle(scope.row, scope.index)">重新启动 |
| | | @click.stop="restartHandle(scope.row, scope.index)" |
| | | >重新启动 |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList, remove, update, add, createOdmTask, restartOdmTask } from '@/api/odm/task' |
| | | import { tourStrategies } from 'element-plus' |
| | | import { mapGetters } from 'vuex' |
| | | import { getList, remove, update, add, createOdmTask, restartOdmTask } from '@/api/odm/task'; |
| | | import { tourStrategies } from 'element-plus'; |
| | | import { mapGetters } from 'vuex'; |
| | | |
| | | export default { |
| | | data () { |
| | | data() { |
| | | return { |
| | | form: {}, |
| | | query: {}, |
| | |
| | | label: '任务名称', |
| | | prop: 'taskName', |
| | | search: true, |
| | | labelWidth: 130, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | //labelWidth: 130, |
| | | searchPlaceholder: "任务名称", |
| | | searchPlaceholder: '任务名称', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | |
| | | searchLabelWidth: 100, |
| | | //width: 100, |
| | | labelWidth: 130, |
| | | searchPlaceholder: "任务类型", |
| | | searchPlaceholder: '任务类型', |
| | | dicData: [ |
| | | { |
| | | label: '航测', |
| | |
| | | value: 4, |
| | | }, |
| | | ], |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,waylineType:value.value}, () => {}); |
| | | } |
| | | change: value => { |
| | | this.searchChange({ ...this.query, waylineType: value.value }, () => {}); |
| | | }, |
| | | }, |
| | | { |
| | | label: '机场名称', |
| | | prop: 'airportName', |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | labelWidth: 130, |
| | | //search: true, |
| | | }, |
| | | { |
| | |
| | | search: true, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | searchPlaceholder: "任务状态", |
| | | searchPlaceholder: '任务状态', |
| | | labelWidth: 130, |
| | | width: 90, |
| | | dicData: [ |
| | | { label: '待启动', value: 0 }, |
| | |
| | | { label: '已完成', value: 40 }, |
| | | { label: '已取消', value: 50 }, |
| | | ], |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,status:value.value}, () => {}); |
| | | } |
| | | change: value => { |
| | | this.searchChange({ ...this.query, status: value.value }, () => {}); |
| | | }, |
| | | }, |
| | | |
| | | { |
| | |
| | | { |
| | | label: '完成时间', |
| | | prop: 'completedTime', |
| | | type: "date", |
| | | type: 'date', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | searchPlaceholder: "任务完成时间", |
| | | searchPlaceholder: '任务完成时间', |
| | | labelWidth: 130, |
| | | search: true, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 100, |
| | | //valueFormat: 'YYYY-MM-DD', |
| | | width: 160, |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,completedTime:value.value}, () => {}); |
| | | } |
| | | change: value => { |
| | | this.searchChange({ ...this.query, completedTime: value.value }, () => {}); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | } |
| | | isClickSearch: true, |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['permission']), |
| | | permissionList () { |
| | | permissionList() { |
| | | return { |
| | | viewBtn: this.validData(this.permission.odm_task_view, true), |
| | | delBtn: this.validData(this.permission.odm_task_delete, true), |
| | | // editBtn: this.validData(this.permission.workspace_edit, true), |
| | | } |
| | | }; |
| | | }, |
| | | ids () { |
| | | let ids = [] |
| | | ids() { |
| | | let ids = []; |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.id) |
| | | }) |
| | | return ids.join(',') |
| | | ids.push(ele.id); |
| | | }); |
| | | return ids.join(','); |
| | | }, |
| | | }, |
| | | methods: { |
| | | // 立即处理 |
| | | atHandle (row) { |
| | | atHandle(row) { |
| | | createOdmTask(row.waylineJobId, row.gsd).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | // 重启启动 |
| | | restartHandle (row) { |
| | | restartHandle(row) { |
| | | if (!row.taskName) { |
| | | this.$message({ |
| | | type: 'error', |
| | | message: '该航线任务已删除,无法进行重启启动!', |
| | | }) |
| | | return |
| | | }); |
| | | return; |
| | | } |
| | | restartOdmTask(row.taskId).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | // 时间格式化 |
| | | formatSeconds (value) { |
| | | formatSeconds(value) { |
| | | // 如果value不是数字或者小于0,则直接返回'00:00:00' |
| | | if (isNaN(value) || value < 0) { |
| | | return '00:00:00' |
| | | return '00:00:00'; |
| | | } |
| | | |
| | | // 计算小时、分钟和秒 |
| | | let seconds = Math.floor(value / 1000) |
| | | let minutes = Math.floor(seconds / 60) |
| | | let hours = Math.floor(minutes / 60) |
| | | let seconds = Math.floor(value / 1000); |
| | | let minutes = Math.floor(seconds / 60); |
| | | let hours = Math.floor(minutes / 60); |
| | | |
| | | // 格式化为两位数字的字符串 |
| | | seconds %= 60 |
| | | minutes %= 60 |
| | | seconds %= 60; |
| | | minutes %= 60; |
| | | |
| | | const formattedTime = `${this.padZero(hours)}:${this.padZero(minutes)}:${this.padZero( |
| | | seconds |
| | | )}` |
| | | )}`; |
| | | |
| | | // 返回格式化后的时间字符串 |
| | | return formattedTime |
| | | return formattedTime; |
| | | }, |
| | | // 函数用于在数字不足两位数时,在前面补零 |
| | | padZero (value) { |
| | | return String(value).padStart(2, '0') |
| | | padZero(value) { |
| | | return String(value).padStart(2, '0'); |
| | | }, |
| | | rowSave (row, done, loading) { |
| | | rowSave(row, done, loading) { |
| | | add(row).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | rowUpdate (row, index, done, loading) { |
| | | rowUpdate(row, index, done, loading) { |
| | | update(row).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ) |
| | | ); |
| | | }, |
| | | rowDel (row) { |
| | | rowDel(row) { |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(row.id) |
| | | return remove(row.id); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | }) |
| | | }); |
| | | }); |
| | | }, |
| | | searchReset () { |
| | | this.query = {} |
| | | this.onLoad(this.page) |
| | | searchReset() { |
| | | this.query = {}; |
| | | this.onLoad(this.page); |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | this.onLoad(this.page, params) |
| | | done() |
| | | searchChange(params, done) { |
| | | if (!this.isClickSearch) return; |
| | | |
| | | this.query = params; |
| | | this.page.currentPage = 1; |
| | | this.onLoad(this.page, params); |
| | | done(); |
| | | }, |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | selectionChange(list) { |
| | | this.selectionList = list; |
| | | }, |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | selectionClear() { |
| | | this.selectionList = []; |
| | | this.$refs.crud.toggleSelection(); |
| | | }, |
| | | handleDelete () { |
| | | handleDelete() { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message.warning('请选择至少一条数据') |
| | | return |
| | | this.$message.warning('请选择至少一条数据'); |
| | | return; |
| | | } |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(this.ids) |
| | | return remove(this.ids); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }); |
| | | this.$refs.crud.toggleSelection(); |
| | | }); |
| | | }, |
| | | beforeOpen (done, type) { |
| | | beforeOpen(done, type) { |
| | | // if (['edit', 'view'].includes(type)) { |
| | | // getDetail(this.form.id).then(res => { |
| | | // this.form = res.data.data; |
| | | // }); |
| | | // } |
| | | done() |
| | | this.isClickSearch = false; |
| | | |
| | | done(); |
| | | }, |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | |
| | | beforeClose(done, type) { |
| | | this.isClickSearch = true; |
| | | |
| | | done(); |
| | | }, |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | |
| | | currentChange(currentPage) { |
| | | this.page.currentPage = currentPage; |
| | | }, |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | sizeChange(pageSize) { |
| | | this.page.pageSize = pageSize; |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | const { releaseTimeRange } = this.query |
| | | refreshChange() { |
| | | this.onLoad(this.page, this.query); |
| | | }, |
| | | onLoad(page, params = {}) { |
| | | const { releaseTimeRange } = this.query; |
| | | |
| | | let values = { |
| | | ...params, |
| | | ...this.query, |
| | | } |
| | | }; |
| | | if (releaseTimeRange) { |
| | | values = { |
| | | ...values, |
| | | releaseTime_datege: releaseTimeRange[0], |
| | | releaseTime_datelt: releaseTimeRange[1], |
| | | } |
| | | values.releaseTimeRange = null |
| | | }; |
| | | values.releaseTimeRange = null; |
| | | } |
| | | this.loading = true |
| | | this.loading = true; |
| | | getList(page.currentPage, page.pageSize, values).then(res => { |
| | | const data = res.data.data |
| | | this.page.total = data.total |
| | | this.data = data.records |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }) |
| | | const data = res.data.data; |
| | | this.page.total = data.total; |
| | | this.data = data.records; |
| | | this.loading = false; |
| | | this.selectionClear(); |
| | | }); |
| | | }, |
| | | }, |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | |
| | | }); |
| | | // 校验手机号 |
| | | const validatePhone = () => { |
| | | const phoneRegex = /^1[3-9]\d{9}$/; |
| | | if (!phoneRegex.test(userInfo.value.phone)) { |
| | | ElMessage.error('请输入正确的手机号码'); |
| | | return false; |
| | | const phone = userInfo.value.phone |
| | | if (!phone) return true |
| | | const phoneRegex = /^1[3-9]\d{9}$/ |
| | | if (!phoneRegex.test(phone)) { |
| | | ElMessage.error('请输入正确的手机号码') |
| | | return false |
| | | } |
| | | return true; |
| | | }; |
| | | return true |
| | | } |
| | | // 校验邮箱 |
| | | const validateEmail = () => { |
| | | if (!userInfo.value.email) return true // 允许为空 |
| | |
| | | |
| | | align: 'center', |
| | | border: true, |
| | | stripe: true, |
| | | stripe: false, |
| | | searchShow: true, |
| | | searchBtnText: '搜索', |
| | | searchMenuSpan: 6, |
| | |
| | | </div> |
| | | |
| | | <!-- 表格部分 --> |
| | | <avue-crud class="ztzf-public-general-avue-crud" ref="avueCrud" v-model="tableData" :option="option" |
| | | :data="tableData" v-model:page="page" @size-change="sizeChange" @current-change="handleCurrentChange" |
| | | @refresh-change="refreshChange" :table-loading="loading" @selection-change="handleSelectionChange" |
| | | :permission="permissionList" v-if="activeTab === tab.name"> |
| | | <avue-crud |
| | | class="ztzf-public-general-avue-crud" |
| | | ref="avueCrud" |
| | | v-model="tableData" |
| | | :option="option" |
| | | :data="tableData" |
| | | v-model:page="page" |
| | | @size-change="sizeChange" |
| | | @current-change="handleCurrentChange" |
| | | @refresh-change="refreshChange" |
| | | :table-loading="loading" |
| | | @selection-change="handleSelectionChange" |
| | | :permission="permissionList" |
| | | v-if="activeTab === tab.name" |
| | | > |
| | | <template #orderNumber="{ row }"> |
| | | <el-tooltip-copy :content="row.orderNumber" :showCopyText="true" textAlign="left"> |
| | | {{ row.orderNumber }} |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="工单类型" prop="type"> |
| | | |
| | | <el-select @change="handleTypeChange" v-model="form.type" placeholder="请选择工单类型" class="full-width" > |
| | | <el-select |
| | | @change="handleTypeChange" |
| | | v-model="form.type" |
| | | placeholder="请选择工单类型" |
| | | class="full-width" |
| | | > |
| | | <el-option |
| | | v-for="item in types" |
| | | :key="item.value" |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | |
| | | <el-button type="danger" :loading="submitLoading" @click="submitForm">发布</el-button> |
| | | <el-button type="infoprimary" plain :loading="draftLoading" @click="saveDraft" |
| | | >存草稿</el-button |
| | | > |
| | | |
| | | |
| | | <el-button @click="handleCancel">取 消</el-button> |
| | | <el-button @click="handleCancel">取 消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 工单详情对话框 --> |
| | | <el-dialog class="custom-dialog" align-center v-model="detailVisible" title="工单详情" width="80%" append-to-body> |
| | | <el-dialog |
| | | class="custom-dialog" |
| | | align-center |
| | | v-model="detailVisible" |
| | | title="工单详情" |
| | | width="80%" |
| | | append-to-body |
| | | > |
| | | <div class="detail-container"> |
| | | <div class="detail-top-title"> |
| | | <div class="event-title-center event-orderNumber"> |
| | |
| | | </el-steps> |
| | | </div> |
| | | |
| | | <div class="PopUpTableScrolls"> |
| | | <div class="PopUpTableScrolls"> |
| | | <!-- 基本信息表格 --> |
| | | <el-table :show-header="false" :data="formattedDetailFields" border class="tableCss"> |
| | | <el-table-column prop="label1" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | <span |
| | | v-if="currentDetail.status === 0 &&(row.label1 === '关联算法' || row.label1 === '工单名称')" |
| | | class="required-label" |
| | | > |
| | | <span class="required-star">*</span>{{ row.label1 }} |
| | | </span> |
| | | <span v-else>{{ row.label1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <template |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label1 === '工单名称' && |
| | | hasProcessingBtnPermission() |
| | | " |
| | | > |
| | | <el-input |
| | | v-model="currentDetail.orderName" |
| | | placeholder="请输入工单名称" |
| | | class="required-input" |
| | | /> |
| | | </template> |
| | | <template |
| | | v-else-if=" |
| | | currentDetail.status === 0 && |
| | | row.label1 === '关联算法' && |
| | | hasProcessingBtnPermission() |
| | | " |
| | | > |
| | | <el-select |
| | | v-model="currentDetail.aiType" |
| | | placeholder="请选择关联算法" |
| | | class="required-input" |
| | | <el-table :show-header="false" :data="formattedDetailFields" border class="tableCss"> |
| | | <el-table-column prop="label1" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | <span |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | (row.label1 === '关联算法' || row.label1 === '工单名称') |
| | | " |
| | | class="required-label" |
| | | > |
| | | <el-option |
| | | v-for="item in algorithms2" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | <span class="required-star">*</span>{{ row.label1 }} |
| | | </span> |
| | | <span v-else>{{ row.label1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <template |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label1 === '工单名称' && |
| | | hasProcessingBtnPermission() |
| | | " |
| | | > |
| | | <el-input |
| | | v-model="currentDetail.orderName" |
| | | placeholder="请输入工单名称" |
| | | class="required-input" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | <template v-else>{{ row.value1 }}</template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="label2" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | |
| | | <span |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label2 === '工单内容' |
| | | " |
| | | class="required-label" |
| | | > |
| | | <span class="required-star">*</span>{{ row.label2 }} |
| | | </span> |
| | | <span v-else>{{ row.label2 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修改工单类型和工单内容的显示 --> |
| | | |
| | | |
| | | <template |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label2 === '工单内容' && |
| | | hasProcessingBtnPermission() |
| | | " |
| | | > |
| | | <el-input |
| | | type="textarea" |
| | | v-model="currentDetail.content" |
| | | placeholder="请输入工单内容" |
| | | class="required-input" |
| | | /> |
| | | </template> |
| | | <template v-else>{{ row.value2 }}</template> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 事件处理详情 --> |
| | | <div v-if="[3, 4].includes(currentDetail.status)" class="form-section"> |
| | | <div class="section-title"> |
| | | <!-- 处理中状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> <span class="required-star">*</span>事件处理详情 </span> |
| | | </template> |
| | | <template v-else> 事件处理详情 </template> |
| | | </div> |
| | | <!-- 处理中状态显示输入框 --> |
| | | <template v-if="currentDetail.status === 3 && hasProcessedAndOverBtnPermission()"> |
| | | <el-input |
| | | type="textarea" |
| | | v-model="currentDetail.processingDetail" |
| | | placeholder="请输入事件处理详情" |
| | | :rows="4" |
| | | style="width: 100%; margin-bottom: 10px" |
| | | /> |
| | | </template> |
| | | <!-- 已完成和已完结状态显示只读文本 --> |
| | | <template v-else> |
| | | <div class="readonly-processing-detail"> |
| | | {{ currentDetail.processingDetail }} |
| | | </div> |
| | | </template> |
| | | </div> |
| | | |
| | | <!-- 上传图片 --> |
| | | <div v-if="[3].includes(currentDetail.status)" class="form-section uploadImg"> |
| | | <div class="section-title" v-if="hasProcessedAndOverBtnPermission()"> |
| | | <!-- 已完成状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> <span class="required-star">*</span>上传图片 </span> |
| | | </template> |
| | | <template v-else> 上传图片 </template> |
| | | </div> |
| | | <el-upload |
| | | v-if="hasProcessedAndOverBtnPermission()" |
| | | ref="upload" |
| | | :action="'#'" |
| | | :auto-upload="false" |
| | | list-type="picture-card" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleUploadRemove" |
| | | :before-upload="beforeUpload" |
| | | :file-list="currentDetail.photos || []" |
| | | :limit="1" |
| | | accept="image/*" |
| | | class="detail-upload" |
| | | > |
| | | <template v-if="!currentDetail.photos || currentDetail.photos.length < 1"> |
| | | <!-- <i class="el-icon-plus">+</i> --> |
| | | <div class="el-icon-plus"> |
| | | <span>+</span> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <div class="el-upload__tip" v-if="hasProcessedAndOverBtnPermission()"> |
| | | (上传照片即可完结工单,只能上传jpg、jpeg、png照片,且不超过5M) |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 图片和地图部分 --> |
| | | <div class="media-section"> |
| | | <el-row :gutter="20"> |
| | | |
| | | <el-col :span="12"> |
| | | <div class="media-box"> |
| | | <div class="media-title">事件图片</div> |
| | | <div class="media-content"> |
| | | <el-image |
| | | v-if="currentDetail.mediaUrl" |
| | | :src="getThumbUrl(currentDetail.mediaUrl)" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]" |
| | | fit="contain" |
| | | style="width: 700px; height: 520px; cursor: pointer" |
| | | </template> |
| | | <template |
| | | v-else-if=" |
| | | currentDetail.status === 0 && |
| | | row.label1 === '关联算法' && |
| | | hasProcessingBtnPermission() |
| | | " |
| | | > |
| | | <el-select |
| | | v-model="currentDetail.aiType" |
| | | placeholder="请选择关联算法" |
| | | class="required-input" |
| | | > |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | <span>加载中...</span> |
| | | </div> |
| | | </template> |
| | | <template #error> |
| | | <div class="image-error"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | <span>加载失败</span> |
| | | </div> |
| | | </template> |
| | | </el-image> |
| | | <div v-else class="no-media">暂无图片/视频</div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="media-box"> |
| | | <!-- 根据状态显示不同的标题和内容 --> |
| | | <el-option |
| | | v-for="item in algorithms2" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | <template v-else>{{ row.value1 }}</template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="label2" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | |
| | | <template v-if="currentDetail.status === 4"> |
| | | <div class="media-title">工单处理图片</div> |
| | | <span |
| | | v-if="currentDetail.status === 0 && row.label2 === '工单内容'" |
| | | class="required-label" |
| | | > |
| | | <span class="required-star">*</span>{{ row.label2 }} |
| | | </span> |
| | | <span v-else>{{ row.label2 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修改工单类型和工单内容的显示 --> |
| | | |
| | | <template |
| | | v-if=" |
| | | currentDetail.status === 0 && |
| | | row.label2 === '工单内容' && |
| | | hasProcessingBtnPermission() |
| | | " |
| | | > |
| | | <el-input |
| | | type="textarea" |
| | | v-model="currentDetail.content" |
| | | placeholder="请输入工单内容" |
| | | class="required-input" |
| | | /> |
| | | </template> |
| | | <template v-else>{{ row.value2 }}</template> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 事件处理详情 --> |
| | | <div v-if="[3, 4].includes(currentDetail.status)" class="form-section"> |
| | | <div class="section-title"> |
| | | <!-- 处理中状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> |
| | | <span class="required-star">*</span>事件处理详情 |
| | | </span> |
| | | </template> |
| | | <template v-else> 事件处理详情 </template> |
| | | </div> |
| | | <!-- 处理中状态显示输入框 --> |
| | | <template v-if="currentDetail.status === 3 && hasProcessedAndOverBtnPermission()"> |
| | | <el-input |
| | | type="textarea" |
| | | v-model="currentDetail.processingDetail" |
| | | placeholder="请输入事件处理详情" |
| | | :rows="4" |
| | | style="width: 100%; margin-bottom: 10px" |
| | | /> |
| | | </template> |
| | | <!-- 已完成和已完结状态显示只读文本 --> |
| | | <template v-else> |
| | | <div class="readonly-processing-detail"> |
| | | {{ currentDetail.processingDetail }} |
| | | </div> |
| | | </template> |
| | | </div> |
| | | |
| | | <!-- 上传图片 --> |
| | | <div v-if="[3].includes(currentDetail.status)" class="form-section uploadImg"> |
| | | <div class="section-title" v-if="hasProcessedAndOverBtnPermission()"> |
| | | <!-- 已完成状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> <span class="required-star">*</span>上传图片 </span> |
| | | </template> |
| | | <template v-else> 上传图片 </template> |
| | | </div> |
| | | <el-upload |
| | | v-if="hasProcessedAndOverBtnPermission()" |
| | | ref="upload" |
| | | :action="'#'" |
| | | :auto-upload="false" |
| | | list-type="picture-card" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleUploadRemove" |
| | | :before-upload="beforeUpload" |
| | | :file-list="currentDetail.photos || []" |
| | | :limit="1" |
| | | accept="image/*" |
| | | class="detail-upload" |
| | | > |
| | | <template v-if="!currentDetail.photos || currentDetail.photos.length < 1"> |
| | | <!-- <i class="el-icon-plus">+</i> --> |
| | | <div class="el-icon-plus"> |
| | | <span>+</span> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <div class="el-upload__tip" v-if="hasProcessedAndOverBtnPermission()"> |
| | | (上传照片即可完结工单,只能上传jpg、jpeg、png照片,且不超过5M) |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 图片和地图部分 --> |
| | | <div class="media-section"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="media-box"> |
| | | <div class="media-title">事件图片</div> |
| | | <div class="media-content"> |
| | | <el-image |
| | | v-if="currentDetail.updatePhotoUrl" |
| | | :src="getThumbUrl(currentDetail.updatePhotoUrl)" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.updatePhotoUrl)]" |
| | | fit="fill" |
| | | v-if="currentDetail.mediaUrl" |
| | | :src="getThumbUrl(currentDetail.mediaUrl)" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]" |
| | | fit="contain" |
| | | style="width: 700px; height: 520px; cursor: pointer" |
| | | > |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | |
| | | </div> |
| | | </template> |
| | | </el-image> |
| | | <div v-else class="no-media">暂无处理图片</div> |
| | | <div v-else class="no-media">暂无图片/视频</div> |
| | | </div> |
| | | </template> |
| | | <template v-else> |
| | | <div class="media-title">地图标记事件点 |
| | | <el-popover v-if="currentDetail.status === 3 || currentDetail.status === 0" |
| | | popper-class="custom-qrcode-popover" |
| | | :width="120" |
| | | :visible="currentDetail.showQR && detailVisible" |
| | | placement="top" |
| | | title="" |
| | | trigger="click" |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="media-box"> |
| | | <!-- 根据状态显示不同的标题和内容 --> |
| | | |
| | | > |
| | | <template #reference> |
| | | <img @click.stop="handleQRCode(currentDetail)" class="QRCodeImg" src="@/assets/images/dataCenter/qrCode.svg" alt="" title="事件导航" /> |
| | | </template> |
| | | <div class="qrcode-content"> |
| | | <CreateQRcode v-if="currentDetail.showQR && detailVisible" :latAndLon="currentDetail.location"></CreateQRcode> |
| | | </div> |
| | | </el-popover> |
| | | </div> |
| | | <div class="media-content"> |
| | | <map-container v-if="detailVisible" ref="MapContainer"></map-container> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </el-col> |
| | | |
| | | |
| | | </el-row> |
| | | <template v-if="currentDetail.status === 4"> |
| | | <div class="media-title">工单处理图片</div> |
| | | <div class="media-content"> |
| | | <el-image |
| | | v-if="currentDetail.updatePhotoUrl" |
| | | :src="getThumbUrl(currentDetail.updatePhotoUrl)" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.updatePhotoUrl)]" |
| | | fit="fill" |
| | | > |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | <span>加载中...</span> |
| | | </div> |
| | | </template> |
| | | <template #error> |
| | | <div class="image-error"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | <span>加载失败</span> |
| | | </div> |
| | | </template> |
| | | </el-image> |
| | | <div v-else class="no-media">暂无处理图片</div> |
| | | </div> |
| | | </template> |
| | | <template v-else> |
| | | <div class="media-title"> |
| | | 地图标记事件点 |
| | | <el-popover |
| | | v-if="currentDetail.status === 3 || currentDetail.status === 0" |
| | | popper-class="custom-qrcode-popover" |
| | | :width="120" |
| | | :visible="currentDetail.showQR && detailVisible" |
| | | placement="top" |
| | | title="" |
| | | trigger="hover" |
| | | > |
| | | <template #reference> |
| | | <img |
| | | @mouseenter="currentDetail.showQR = true" |
| | | @mouseleave="currentDetail.showQR = false" |
| | | class="QRCodeImg" |
| | | src="@/assets/images/dataCenter/qrCode.svg" |
| | | alt="" |
| | | title="事件导航" |
| | | /> |
| | | </template> |
| | | <div class="qrcode-content"> |
| | | <CreateQRcode |
| | | v-if="currentDetail.showQR && detailVisible" |
| | | :latAndLon="currentDetail.location" |
| | | ></CreateQRcode> |
| | | </div> |
| | | </el-popover> |
| | | </div> |
| | | <div class="media-content"> |
| | | <map-container v-if="detailVisible" ref="MapContainer"></map-container> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <div class="dialog-footer1"> |
| | | <div |
| | | class="leftBtn" |
| | | :class="currentIndex === 0 ? 'disableds' : ''" |
| | | @click="leftClick" |
| | | <div class="leftBtn" :class="currentIndex === 0 ? 'disableds' : ''" @click="leftClick"> |
| | | 上一页 |
| | | </div> |
| | | <div class="btngroups"> |
| | | <template v-if="currentDetail.status === 2"> |
| | | <!-- 待审核 --> |
| | | <el-button |
| | | v-if="hasReviewBtnPermission()" |
| | | type="primary" |
| | | :loading="approveLoading" |
| | | @click="approveTicket" |
| | | >通过</el-button |
| | | > |
| | | 上一页 |
| | | </div> |
| | | <div class="btngroups"> |
| | | <template v-if="currentDetail.status === 2"> |
| | | <!-- 待审核 --> |
| | | <el-button |
| | | v-if="hasReviewBtnPermission()" |
| | | type="primary" |
| | | :loading="approveLoading" |
| | | @click="approveTicket" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | | v-if="hasReviewBtnPermission()" |
| | | type="danger" |
| | | :loading="rejectLoading" |
| | | @click="rejectTicket" |
| | | >不通过</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 0"> |
| | | <el-button |
| | | v-if="hasProcessingBtnPermission()" |
| | | type="primary" |
| | | :loading="dispatchLoading" |
| | | @click="approveAndDispatch" |
| | | >受理</el-button |
| | | > |
| | | <el-button |
| | | v-if="hasProcessingBtnPermission()" |
| | | type="danger" |
| | | :loading="rejectLoading" |
| | | @click="rejectTicket" |
| | | >不受理</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <!-- 处理中 --> |
| | | <el-button |
| | | v-if="hasProcessedAndOverBtnPermission()" |
| | | type="primary" |
| | | :loading="completeLoading" |
| | | @click="completeTicket" |
| | | >完成工单</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 4"> |
| | | <!-- 已完成 --> |
| | | <!-- <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="finalizeLoading" |
| | | <el-button |
| | | v-if="hasReviewBtnPermission()" |
| | | type="danger" |
| | | :loading="rejectLoading" |
| | | @click="rejectTicket" |
| | | >不通过</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 0"> |
| | | <el-button |
| | | v-if="hasProcessingBtnPermission()" |
| | | type="primary" |
| | | :loading="dispatchLoading" |
| | | @click="approveAndDispatch" |
| | | >受理</el-button |
| | | > |
| | | <el-button |
| | | v-if="hasProcessingBtnPermission()" |
| | | type="danger" |
| | | :loading="rejectLoading" |
| | | @click="rejectTicket" |
| | | >不受理</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <!-- 处理中 --> |
| | | <el-button |
| | | v-if="hasProcessedAndOverBtnPermission()" |
| | | type="primary" |
| | | :loading="completeLoading" |
| | | @click="completeTicket" |
| | | >完成工单</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 4"> |
| | | <!-- 已完成 --> |
| | | <!-- <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="finalizeLoading" |
| | | @click="finalizeTicket">完结工单</el-button> --> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | </div> |
| | | <div |
| | | :class="currentIndex === tableData.length - 1 ? 'disableds' : ''" |
| | | class="leftBtn" |
| | | @click="rightClick" |
| | | > |
| | | 下一页 |
| | | </div> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | </div> |
| | | <div |
| | | :class="currentIndex === tableData.length - 1 ? 'disableds' : ''" |
| | | class="leftBtn" |
| | | @click="rightClick" |
| | | > |
| | | 下一页 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | |
| | | <el-form :model="dispatchForm" :rules="dispatchRules" ref="dispatchForm" label-width="100px"> |
| | | <el-form-item label="选择部门" prop="department"> |
| | | <el-select |
| | | |
| | | v-model="dispatchForm.department" |
| | | placeholder="请选择部门" |
| | | @change="handleDispatchDepartmentChange" |
| | |
| | | </el-form-item> |
| | | <el-form-item label="选择处理人" prop="handler"> |
| | | <el-select |
| | | filterable |
| | | filterable |
| | | v-model="dispatchForm.handler" |
| | | placeholder="请选择处理人" |
| | | :disabled="!dispatchForm.department" |
| | |
| | | getStepInfo, |
| | | getReviewById, |
| | | getCreateEventJob, |
| | | } from '@/api/tickets/ticket' |
| | | import { getSFDictionaryTree } from '@/api/job/task'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel' |
| | | import geoJson from '@/assets/geoJson.json' |
| | | import { mapGetters } from 'vuex' |
| | | import { getAdcodeObj } from '@/utils/disposeData' |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue' |
| | | import getBaseConfig from '@/buildConfig/config' |
| | | import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue' |
| | | const { envName } = getBaseConfig() |
| | | function regExp (label, name) { |
| | | var reg = new RegExp(label + '=([^&]*)(&|$)', 'g') |
| | | return name.match(reg)[0].split('=')[1] |
| | | } from '@/api/tickets/ticket'; |
| | | import { getSFDictionaryTree } from '@/api/job/task'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel'; |
| | | import geoJson from '@/assets/geoJson.json'; |
| | | import { mapGetters } from 'vuex'; |
| | | import { getAdcodeObj } from '@/utils/disposeData'; |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue'; |
| | | import getBaseConfig from '@/buildConfig/config'; |
| | | import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue'; |
| | | const { envName } = getBaseConfig(); |
| | | function regExp(label, name) { |
| | | var reg = new RegExp(label + '=([^&]*)(&|$)', 'g'); |
| | | return name.match(reg)[0].split('=')[1]; |
| | | } |
| | | |
| | | export default { |
| | | components: { elTooltipCopy,CreateQRcode }, |
| | | components: { elTooltipCopy, CreateQRcode }, |
| | | name: 'TicketPage', |
| | | data() { |
| | | return { |
| | |
| | | tableData: [], |
| | | option: { |
| | | border: true, |
| | | stripe: true, |
| | | stripe: false, |
| | | selection: true, // 添加多选功能 |
| | | index: true, // 保留序号功能 |
| | | indexLabel: '序号', |
| | |
| | | { label: '处理人', prop: 'handler', width: 70 }, |
| | | { |
| | | slot: true, |
| | | hide: envName === 'jiangwu'? true : false, |
| | | hide: envName === 'jiangwu' ? true : false, |
| | | label: '复核状态', |
| | | prop: 'isReview', |
| | | width: 90, |
| | |
| | | }, |
| | | |
| | | mounted() { |
| | | |
| | | this.getAlgorithmList() |
| | | this.getAlgorithmList(); |
| | | |
| | | const href = this.$route.href; |
| | | if (this.$route?.query?.status !== undefined && this.$route?.query?.status !== null) { |
| | |
| | | this.filters.keyword = orderNumber; |
| | | this.$nextTick(() => { |
| | | this.isShowInfo = true; |
| | | const find = this.$store.state.tags.bsTagList.find(i => i.path === '/tickets/ticket') |
| | | find && (find.query = {}) |
| | | const find = this.$store.state.tags.bsTagList.find(i => i.path === '/tickets/ticket'); |
| | | find && (find.query = {}); |
| | | }); |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | { label: '任务发起人', value: this.currentDetail.creator }, |
| | | { label: '当前状态', value: this.mapStatus(this.currentDetail.status) }, |
| | | { label: '事件地址', value: this.currentDetail.address || this.currentDetail.latAndLon }, // 包含经纬度信息 |
| | | { label: '关联算法', |
| | | value: |
| | | { |
| | | label: '关联算法', |
| | | value: |
| | | this.algorithms.find(t => t.value === this.currentDetail.aiType)?.label || |
| | | this.currentDetail.aiType || |
| | | '/', |
| | | |
| | | }, |
| | | { label: '发起单位', value: this.currentDetail.department }, |
| | | { label: '发起任务时间', value: this.currentDetail.startTime }, |
| | |
| | | } |
| | | |
| | | return formattedFields; |
| | | |
| | | }, |
| | | dynamicFixedStatuses() { |
| | | // 直接使用接口返回的 stepInfos |
| | |
| | | |
| | | methods: { |
| | | handleCheck(data, { checkedKeys, checkedNodes }) { |
| | | this.checkedKeys = checkedKeys |
| | | this.checkedKeys = checkedKeys; |
| | | // 获取所有选中节点的 dictKey |
| | | const selectedDictKeys = checkedNodes.map(node => node.dictKey).filter(Boolean) |
| | | this.filters.type = selectedDictKeys |
| | | const selectedDictKeys = checkedNodes.map(node => node.dictKey).filter(Boolean); |
| | | this.filters.type = selectedDictKeys; |
| | | this.fetchTableData(); |
| | | }, |
| | | // 算法 |
| | | getAlgorithmList() { |
| | | getSFDictionaryTree({code:'SF'}).then((res) => { |
| | | if (res.data.code === 200) { |
| | | const result = res.data.data[0].children |
| | | // 过滤第一层数据 |
| | | const filteredData = result.map(item => { |
| | | // 过滤第二层数据 |
| | | const children = item.children?.map(child => ({ |
| | | ...child, |
| | | children: [] // 清空第三层数据 |
| | | })) |
| | | return { |
| | | ...item, |
| | | children: children || [] |
| | | } |
| | | }) |
| | | this.dataList = filteredData |
| | | } |
| | | }) |
| | | getSFDictionaryTree({ code: 'SF' }).then(res => { |
| | | if (res.data.code === 200) { |
| | | const result = res.data.data[0].children; |
| | | // 过滤第一层数据 |
| | | const filteredData = result.map(item => { |
| | | // 过滤第二层数据 |
| | | const children = item.children?.map(child => ({ |
| | | ...child, |
| | | children: [], // 清空第三层数据 |
| | | })); |
| | | return { |
| | | ...item, |
| | | children: children || [], |
| | | }; |
| | | }); |
| | | this.dataList = filteredData; |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | handleSFNodeClick(data) { |
| | | console.log(data.dictKey, '666666666') |
| | | this.filters.type = '' |
| | | this.filters.algorithm = '' |
| | | this.filters.type = data.dictKey |
| | | console.log(data.dictKey, '666666666'); |
| | | this.filters.type = ''; |
| | | this.filters.algorithm = ''; |
| | | this.filters.type = data.dictKey; |
| | | // 更新列表请求 |
| | | this.fetchTableData(); |
| | | }, |
| | | handleClear() { |
| | | this.dictKey = '' |
| | | this.filters.algorithm = '' |
| | | this.filters.type = '' |
| | | this.fetchTableData(); |
| | | this.dictKey = ''; |
| | | this.filters.algorithm = ''; |
| | | this.filters.type = ''; |
| | | this.fetchTableData(); |
| | | }, |
| | | handleCellClick(row, column) { |
| | | console.log(row, column.no); |
| | |
| | | this.currentDetail.processingDetail = this.currentDetail.content; |
| | | this.handleViewDetail(this.currentDetail); |
| | | |
| | | |
| | | // 如果使用地图组件,需要更新地图标记 |
| | | this.$nextTick(() => { |
| | | if (this.$refs.MapContainer && this.currentDetail.location) { |
| | |
| | | } |
| | | }); |
| | | }, |
| | | async handleQRCode (val){ |
| | | val.showQR = !val.showQR |
| | | async handleQRCode(val) { |
| | | val.showQR = !val.showQR; |
| | | }, |
| | | async loadAMapScripts() { |
| | | try { |
| | |
| | | const subAreaCode = areaCode ? areaCode.substring(0, 6) : ''; |
| | | const adcodeObj = getAdcodeObj(geoJson, 'adcode', subAreaCode); |
| | | |
| | | // console.log('区域代码:', subAreaCode); |
| | | // console.log('区域代码:', subAreaCode); |
| | | |
| | | // 直接从返回对象中获取正确的路径 |
| | | const center = adcodeObj?.payload?.objects?.collection?.geometries?.[0]?.properties?.center; |
| | |
| | | try { |
| | | const response = await getTicketInfo(); |
| | | |
| | | const { dept_data, event_type, ai_type,info } = response.data.data; |
| | | const { dept_data, event_type, ai_type, info } = response.data.data; |
| | | |
| | | this.departments = dept_data.map(item => ({ |
| | | label: item.dept_name, |
| | |
| | | |
| | | const columnType = this.findObject(this.option.column, 'type'); |
| | | columnType.dicData = this.types; |
| | | this.allAlgorithms = info |
| | | this.allAlgorithms = info; |
| | | |
| | | console.log('工单类型',this.types); |
| | | console.log('关联算法',this.allAlgorithms ); |
| | | console.log('工单类型', this.types); |
| | | console.log('关联算法', this.allAlgorithms); |
| | | // 确保算法数据的映射一致 |
| | | this.algorithms = |
| | | ai_type?.map(item => ({ |
| | |
| | | value: item.dict_key, |
| | | })) || []; |
| | | |
| | | this.algorithms2 = _.cloneDeep(this.algorithms) |
| | | this.algorithms2 = _.cloneDeep(this.algorithms); |
| | | |
| | | // 构建用户ID和名称的映射关系 |
| | | this.userNameToIdMap = {}; |
| | |
| | | }, |
| | | // 工单类型变化时触发 |
| | | handleTypeChange(typeValue) { |
| | | this.form.algorithm = [] |
| | | this.form.algorithm = []; |
| | | if (!typeValue) { |
| | | // 未选择类型时清空算法列表 |
| | | this.algorithms2 = []; |
| | | return; |
| | | } |
| | | |
| | | const matchedCategory = this.allAlgorithms.find( |
| | | category => category.dict_key === typeValue |
| | | ); |
| | | const matchedCategory = this.allAlgorithms.find(category => category.dict_key === typeValue); |
| | | |
| | | if (!matchedCategory || !matchedCategory.algorithms || matchedCategory.algorithms.length === 0) { |
| | | if ( |
| | | !matchedCategory || |
| | | !matchedCategory.algorithms || |
| | | matchedCategory.algorithms.length === 0 |
| | | ) { |
| | | // 无匹配的算法时清空 |
| | | this.algorithms2 = []; |
| | | this.$message.info('该工单类型暂无关联算法'); |
| | |
| | | label: algo.dict_value, |
| | | value: algo.dict_key, |
| | | dict_key: algo.dict_key, |
| | | dict_value: algo.dict_value |
| | | dict_value: algo.dict_value, |
| | | })); |
| | | |
| | | }, |
| | | |
| | | async fetchTableData() { |
| | |
| | | this.draftLoading = false; |
| | | } |
| | | }, |
| | | handleCancel (){ |
| | | handleCancel() { |
| | | this.resetForm(); |
| | | this.dialogVisible = false; |
| | | }, |
| | | this.dialogVisible = false; |
| | | }, |
| | | handleLocationChange(val) { |
| | | let locationValue = val.value; |
| | | if (locationValue && locationValue.length >= 2) { |
| | |
| | | isReview: '', // 重置时清空复核状态 |
| | | }; |
| | | this.page.currentPage = 1; |
| | | this.$router.replace({}); //清除url参数 |
| | | this.$router.replace({}); //清除url参数 |
| | | this.fetchTableData(); |
| | | }, |
| | | handleKeyWords(){ |
| | | this.$router.replace({}); //清除url参数 |
| | | handleKeyWords() { |
| | | this.$router.replace({}); //清除url参数 |
| | | }, |
| | | |
| | | async handleCurrentChange(val) { |
| | |
| | | |
| | | console.log('this.currentDetail', this.currentDetail); |
| | | this.detailVisible = true; |
| | | this.handleTypeChange(this.currentDetail.type) |
| | | console.log('this.currentDetail.location',this.currentDetail.location); |
| | | this.handleTypeChange(this.currentDetail.type); |
| | | console.log('this.currentDetail.location', this.currentDetail.location); |
| | | |
| | | this.$nextTick(() => { |
| | | if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) { |
| | |
| | | // 通过验证后,打开派发对话框 |
| | | this.dispatchDialogVisible = true; |
| | | |
| | | console.log('受理',this.currentDetail); |
| | | |
| | | console.log('受理', this.currentDetail); |
| | | }, |
| | | hasProcessingBtnPermission() { |
| | | // undefined 或 false 都返回 false,只有 true 返回 true |
| | |
| | | return; |
| | | } |
| | | this.dispatchLoading = true; |
| | | console.log('派发成功',this.currentDetail); |
| | | console.log('派发成功', this.currentDetail); |
| | | |
| | | this.$refs.dispatchForm.validate(async valid => { |
| | | if (valid) { |
| | |
| | | content: this.currentDetail.content, // 使用 content 替代原来的 remark |
| | | createDept: this.dispatchForm.department, // 派发部门 ID |
| | | updateUser: this.dispatchForm.handler, // 处理人 ID |
| | | aiType:this.currentDetail.aiType |
| | | aiType: this.currentDetail.aiType, |
| | | }; |
| | | console.log('派发',data); |
| | | console.log('派发', data); |
| | | |
| | | const file = this.currentDetail.file || null; // 如果没有文件,则为 null |
| | | |
| | |
| | | activated() { |
| | | this.handleReset(); |
| | | }, |
| | | |
| | | }; |
| | | </script> |
| | | <style lang="scss"> |
| | | .custom-dialog { max-height: 96vh; } |
| | | .custom-dialog { |
| | | max-height: 96vh; |
| | | } |
| | | .custom-qrcode-popover { |
| | | min-width: 120px !important; |
| | | min-width: 120px !important; |
| | | } |
| | | </style> |
| | | <style lang="scss" scoped> |
| | | |
| | | ::v-deep(.el-tabs) { |
| | | height: 100%; |
| | | display: flex; |
| | |
| | | } |
| | | .dialog-footer1 { |
| | | position: sticky; |
| | | bottom: 28px; |
| | | left: 0; |
| | | right: 0; |
| | | background: white; |
| | | z-index: 10; |
| | | padding: 16px 20px; |
| | | border-top: 1px solid #ebeef5; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | bottom: 28px; |
| | | left: 0; |
| | | right: 0; |
| | | background: white; |
| | | z-index: 10; |
| | | padding: 16px 20px; |
| | | border-top: 1px solid #ebeef5; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .el-button + .el-button { |
| | | margin-left: 12px; |
| | | } |
| | | .btngroups { |
| | | margin-left: 12px; |
| | | } |
| | | .btngroups { |
| | | margin-left: 12px; |
| | | } |
| | | .el-button { |
| | | padding: 9px 20px; |
| | | |
| | |
| | | } |
| | | |
| | | .detail-container { |
| | | padding:0 20px; |
| | | padding: 0 20px; |
| | | |
| | | .detail-top-title { |
| | | display: flex; |
| | |
| | | background-color: #999; |
| | | border-radius: 5px; |
| | | text-align: center; |
| | | line-height: 32px; |
| | | line-height: 32px; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | opacity: 0.8; |
| | | |
| | | } |
| | | |
| | | .disableds { |
| | |
| | | pointer-events: none; |
| | | opacity: 0.3 !important; |
| | | } |
| | | .PopUpTableScrolls{ |
| | | height: 600px; |
| | | overflow-y: scroll; |
| | | overflow-x: hidden; |
| | | .PopUpTableScrolls { |
| | | height: 600px; |
| | | overflow-y: scroll; |
| | | overflow-x: hidden; |
| | | } |
| | | .media-box { |
| | | width: 100%; |
| | |
| | | margin-bottom: 5px; |
| | | display: flex; |
| | | align-items: center; |
| | | .QRCodeImg{ |
| | | width: 18px; |
| | | height: 18px; |
| | | cursor: pointer; |
| | | padding-bottom: 1px; |
| | | .QRCodeImg { |
| | | width: 18px; |
| | | height: 18px; |
| | | cursor: pointer; |
| | | padding-bottom: 1px; |
| | | } |
| | | } |
| | | |
| | |
| | | line-height: 1.5; |
| | | display: block; |
| | | text-align: left; |
| | | margin-bottom: 5px; |
| | | margin-bottom: 5px; |
| | | &:first-child { |
| | | font-weight: bold; |
| | | margin-bottom: 4px; |
| | |
| | | dependencies: |
| | | ms "2.0.0" |
| | | |
| | | "decimal.js@^10.4.3": |
| | | "integrity" "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" |
| | | "resolved" "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz" |
| | | "version" "10.4.3" |
| | | decimal.js@^10.4.3: |
| | | version "10.4.3" |
| | | resolved "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz" |
| | | integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== |
| | | |
| | | "decimal@^0.0.2": |
| | | "integrity" "sha512-puX1+D5GlpXYH0kDejnu8F2jsGLKRePc7eOznNjqMbA2otl7AzvubrvvZVmOvRCHhsqeAPKNcAxHHbevsH/1qg==" |
| | | "resolved" "https://registry.npmmirror.com/decimal/-/decimal-0.0.2.tgz" |
| | | "version" "0.0.2" |
| | | decimal@^0.0.2: |
| | | version "0.0.2" |
| | | resolved "https://registry.npmmirror.com/decimal/-/decimal-0.0.2.tgz" |
| | | integrity sha512-puX1+D5GlpXYH0kDejnu8F2jsGLKRePc7eOznNjqMbA2otl7AzvubrvvZVmOvRCHhsqeAPKNcAxHHbevsH/1qg== |
| | | |
| | | "deep-equal@^1.0.0", "deep-equal@1.x": |
| | | "integrity" "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==" |
| | | "resolved" "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.1.2.tgz" |
| | | "version" "1.1.2" |
| | | deep-equal@^1.0.0, deep-equal@1.x: |
| | | version "1.1.2" |
| | | resolved "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.1.2.tgz" |
| | | integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg== |
| | | dependencies: |
| | | is-arguments "^1.1.1" |
| | | is-date-object "^1.0.5" |