From dcf2e7336d9d88cbb00f6f66fcf5253470eff0fb Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Thu, 29 Jan 2026 09:18:39 +0800
Subject: [PATCH] feat:提交设备调度
---
applications/task-work-order/src/views/orderView/equipmentResource/index.vue | 237 ++++++++++++++++
applications/task-work-order/src/views/orderView/equipmentResource/FormDiaLog.vue | 603 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 840 insertions(+), 0 deletions(-)
diff --git a/applications/task-work-order/src/views/orderView/equipmentResource/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/equipmentResource/FormDiaLog.vue
new file mode 100644
index 0000000..420fcdd
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/equipmentResource/FormDiaLog.vue
@@ -0,0 +1,603 @@
+<!-- 设备资源弹窗 -->
+<template>
+ <el-dialog
+ v-model="dialogVisible"
+ :title="dialogTitle"
+ class="gd-dialog"
+ destroy-on-close
+ :close-on-click-modal="false"
+ >
+ <el-row class="detail-row-view" v-if="dialogType === 'view'">
+ <el-col :span="12">
+ <div class="label">设备类型</div>
+ <div class="val">{{ getDictLabel(formData.deviceType, deviceTypeOptions) }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">设备型号</div>
+ <div class="val">{{ formData.deviceName }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">设备名称</div>
+ <div class="val">{{ formData.nickname }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">负载设备</div>
+ <div class="val">{{ getDictLabel(formData.devicePayload, devicePayloadOptions) }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">设备状态</div>
+ <div class="val">{{ getDictLabel(formData.modeCode, dictObj.modeCode) }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">设备SN</div>
+ <div class="val">{{ formData.deviceSn }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">设备位置</div>
+ <div class="val">{{ formData.latitude }}, {{ formData.longitude }}</div>
+ </el-col>
+ </el-row>
+
+ <el-form
+ ref="formRef"
+ :model="formData"
+ :rules="rules"
+ class="gd-form"
+ label-width="160px"
+ v-else
+ >
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="设备类型" prop="deviceType">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="formData.deviceType"
+ placeholder="请选择"
+ :disabled="dialogType === 'view'"
+ >
+ <el-option
+ v-for="item in deviceTypeOptions"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="设备型号" prop="deviceName">
+ <el-input
+ class="gd-input"
+ v-model="formData.deviceName"
+ placeholder="请输入"
+ :disabled="dialogType === 'view'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="设备名称" prop="nickname">
+ <el-input
+ class="gd-input"
+ v-model="formData.nickname"
+ placeholder="请输入"
+ :disabled="dialogType === 'view'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="负载设备" prop="devicePayload">
+ <el-radio-group
+ v-model="formData.devicePayload"
+ :disabled="dialogType === 'view'"
+ >
+ <el-radio
+ v-for="item in devicePayloadOptions"
+ :key="item.dictKey"
+ :label="item.dictKey"
+ >
+ {{ item.dictValue }}
+ </el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="设备状态" prop="modeCode">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="formData.modeCode"
+ placeholder="请选择"
+ :disabled="dialogType === 'view'"
+ >
+ <el-option
+ v-for="item in modeCodeOptions"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="设备SN" prop="deviceSn">
+ <el-input
+ class="gd-input"
+ v-model="formData.deviceSn"
+ placeholder="请输入"
+ :disabled="dialogType === 'view'"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="设备位置" prop="deviceLocation">
+ <el-button class="address-btn" @click="selectLocation">
+ {{ formData.longitude }}, {{ formData.latitude }}
+ </el-button>
+ </el-form-item>
+ </el-col>
+ <!-- <el-col :span="12">
+ <el-form-item label="所属部门" prop="departmentId">
+ <el-tree-select
+ class="gd-select"
+ popper-class="gd-tree-select-popper"
+ v-model="formData.departmentId"
+ :data="deptTree"
+ :props="treeProps"
+ node-key="id"
+ check-strictly
+ clearable
+ @change="handleSearch"
+ />
+ </el-form-item>
+ </el-col> -->
+ </el-row>
+ </el-form>
+ <!-- <div style="width: 100%; height: 400px;">
+ <CommonCesiumMap
+ ref="mapRef"
+ class="gd-cesium"
+ :active="dialogVisible"
+ :flat-mode="false"
+ :terrain="true"
+ :layer-mode="4"
+ :boundary="false"
+ :zoomToBoundary="false"
+ @ready="readyMap"
+ />
+ </div> -->
+ <template #footer>
+ <el-button color="#F2F3F5" v-if="dialogType !== 'view'" @click="handleClose">取消</el-button>
+ <el-button
+ v-if="dialogType !== 'view'"
+ type="primary"
+ color="#4C34FF"
+ @click="handleSubmit"
+ >
+ 确定
+ </el-button>
+ </template>
+ </el-dialog>
+ <el-dialog v-model="visible1"
+ title="选择设备位置"
+ class="gd-dialog"
+ destroy-on-close
+ :close-on-click-modal="false"
+ @close="positionClosed"
+ >
+ <div style="width: 100%; height: 600px;">
+ <CommonCesiumMap
+ ref="mapRef"
+ class="gd-cesium"
+ :active="visible1"
+ :flat-mode="false"
+ :terrain="true"
+ :layer-mode="4"
+ :boundary="false"
+ :zoomToBoundary="false"
+ @ready="mapReady"
+ />
+ </div>
+
+ <template #footer>
+ <el-button color="#F2F3F5" @click="handleMapCancel">取消</el-button>
+ <el-button color="#4C34FF" type="primary" @click="handleMapConfirm">确定</el-button>
+ </template>
+ </el-dialog>
+</template>
+<script setup>
+import { ref, reactive, computed, watch, inject, nextTick } from 'vue'
+import { submitExternalEquipment } from './equipmentResourceApi'
+import { ElMessage } from 'element-plus'
+import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
+import * as Cesium from 'cesium'
+import axios from 'axios'
+import _ from 'lodash'
+import { getDictLabel,fieldRules } from '@ztzf/utils'
+
+const props = defineProps({
+ modelValue: {
+ type: Boolean,
+ default: false
+ },
+ dialogType: {
+ type: String,
+ default: 'add', // add, edit, view
+ validator: (value) => ['add', 'edit', 'view'].includes(value)
+ },
+ equipmentData: {
+ type: Object,
+ default: () => ({})
+ }
+})
+
+const dictObj = inject('dictObj')
+
+const visible1 = ref(false) // 弹框显隐
+const mapRef = ref(null)
+const tempLocation = ref({ longitude: null, latitude: null })
+
+
+
+const deptTree = ref([]) // 部门树
+const treeProps = {
+ label: 'name',
+ children: 'children',
+}
+
+// 设备类型(0机场,1无人机)
+const modeCodeOptions = ref([
+ { dictKey: 0, dictValue: '在线' },
+ { dictKey: 1, dictValue: '离线' }
+])
+
+// 设备类型(0机场,1无人机)
+const deviceTypeOptions = ref([
+ { dictKey: 0, dictValue: '机场' },
+ { dictKey: 1, dictValue: '无人机' }
+])
+
+// 设备负载(0红外,1喇叭,2闪光灯)
+const devicePayloadOptions = ref([
+ { dictKey: '红外', dictValue: '红外' },
+ { dictKey: '喇叭', dictValue: '喇叭' },
+ { dictKey: '闪光灯', dictValue: '闪光灯' }
+])
+
+const emit = defineEmits(['update:modelValue', 'confirm'])
+
+const dialogVisible = computed({
+ get: () => props.modelValue,
+ set: (value) => emit('update:modelValue', value)
+})
+
+const dialogTitle = computed(() => {
+ switch (props.dialogType) {
+ case 'add':
+ return '添加'
+ case 'edit':
+ return '编辑'
+ case 'view':
+ return '查看'
+ default:
+ return '设备'
+ }
+})
+
+const formRef = ref(null)
+const initForm = () => ({
+ childSn: '', // 子设备(一般用途是机场下面的无人机)
+ deviceName: '', // 设备型号
+ devicePayload: '', // 设备负载(红外,喇叭,闪光灯)
+ deviceSn: '', // 设备编码
+ deviceType: null, // 设备类型(0机场,1无人机)
+ firmwareVersion: '', // 固件版本
+ insureExpiredTime: '', // 保险过期时间yyyy-MM-dd HH:mm:ss
+ latitude: 0, // 当前纬度
+ longitude: 0, // 当前经度
+ modeCode: null, // 设备状态:{0:"在线",1:"离线"}
+ nickname: '', // 设备昵称
+ trafficExpireTime: '', // 流量到期时间yyyy-MM-dd HH:mm:ss
+ trafficRemaining: '', // 剩余流量(单位:GB)
+ address: '', // 设备位置
+})
+
+const formData = ref(initForm())
+
+
+const rules = {
+ deviceType: fieldRules(true),
+ deviceModel: fieldRules(true, 50),
+ deviceName: fieldRules(true, 50),
+ deviceSn: fieldRules(true, 50),
+ deviceType: fieldRules(true),
+ modeCode: fieldRules(true),
+ nickname: fieldRules(true, 50),
+}
+
+// const rules = {
+// deviceType: [
+// { required: true, message: '请选择', trigger: 'change' }
+// ],
+// deviceModel: [
+// { required: true, message: '请输入', trigger: 'blur' }
+// ],
+// deviceName: [
+// { required: true, message: '请输入', trigger: 'blur' }
+// ],
+// deviceStatus: [
+// { required: true, message: '请选择', trigger: 'change' }
+// ],
+// deviceSn: [
+// { required: true, message: '请输入', trigger: 'blur' }
+// ]
+// }
+
+let viewer
+let map
+let redPointEntity
+let leftClickBound = false
+function setMapPoint (longitude, latitude) {
+ if (!viewer || longitude == null || latitude == null) return
+ if (!redPointEntity) {
+ redPointEntity = viewer.entities.add({
+ position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
+ point: {
+ color: Cesium.Color.RED,
+ pixelSize: 10,
+ },
+ label: {
+ text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`,
+ font: '14px',
+ fillColor: Cesium.Color.WHITE,
+ backgroundColor: Cesium.Color.BLACK.withAlpha(0.6),
+ backgroundPadding: new Cesium.Cartesian2(5, 5),
+ pixelOffset: new Cesium.Cartesian2(0, -20),
+ showBackground: true,
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+ verticalOrigin: Cesium.VerticalOrigin.CENTER,
+ outlineWidth: 1,
+ outlineColor: Cesium.Color.WHITE,
+ eyeOffset: new Cesium.Cartesian3(0, 0, -20),
+ },
+ })
+ } else {
+ redPointEntity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
+ redPointEntity.label.text = `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`
+ }
+}
+
+async function selectLocation () {
+ visible1.value = true
+ if (viewer) return
+ await nextTick()
+ map = mapRef.value?.getMap()
+ viewer = map?.viewer || null
+ if (viewer && !leftClickBound) {
+ map.publicCesium?.addLeftClickEvent?.(null, LeftClickEvent)
+ leftClickBound = true
+ }
+ if (formData.value.longitude != null && formData.value.latitude != null) {
+ tempLocation.value = { longitude: formData.value.longitude, latitude: formData.value.latitude }
+ setMapPoint(formData.value.longitude, formData.value.latitude)
+ }
+}
+
+async function getLocationName () {
+ const tk = import.meta.env.VITE_APP_TDT_TOKEN
+ const { latitude, longitude } = tempLocation.value
+ const http = axios.create({ withCredentials: false })
+ const res = await http({
+ url: `https://api.tianditu.gov.cn/geocoder?postStr={'lon':${longitude},'lat':${latitude},'ver':1}&tk=${tk}`,
+ method: 'get',
+ })
+ formData.value.address = res.data.result.formatted_address
+}
+
+function handleMapConfirm () {
+ if (tempLocation.value.longitude != null && tempLocation.value.latitude != null) {
+ formData.value.longitude = _.round(tempLocation.value.longitude, 6)
+ formData.value.latitude = _.round(tempLocation.value.latitude, 6)
+ getLocationName()
+ }
+ visible1.value = false
+}
+
+function handleMapCancel () {
+ tempLocation.value = { longitude: null, latitude: null }
+ visible1.value = false
+}
+
+function LeftClickEvent (click) {
+ const pos = click.position // Cartesian2 屏幕坐标
+ // 屏幕坐标 -> 椭球面坐标(不考虑地形/模型)
+ const cartesian3 = viewer.camera.pickEllipsoid(pos, viewer.scene.globe.ellipsoid)
+ if (!cartesian3) {
+ return { longitude: 112, latitude: 23 }
+ }
+ // 椭球面坐标 -> 经纬度
+ const carto = Cesium.Cartographic.fromCartesian(cartesian3)
+ const longitude = Cesium.Math.toDegrees(carto.longitude)
+ const latitude = Cesium.Math.toDegrees(carto.latitude)
+ tempLocation.value = { longitude, latitude }
+ // 添加红点(全局仅保留一个)并渲染经纬度标签
+ if (!redPointEntity) {
+ redPointEntity = viewer.entities.add({
+ position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
+ point: {
+ color: Cesium.Color.RED,
+ pixelSize: 10,
+ },
+ label: {
+ text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`,
+ font: '14px',
+ fillColor: Cesium.Color.WHITE, // 文字颜色:白色
+ backgroundColor: Cesium.Color.BLACK.withAlpha(0.6), //背景颜色
+ backgroundPadding: new Cesium.Cartesian2(5, 5), // 水平/垂直内边距(像素)
+ pixelOffset: new Cesium.Cartesian2(0, -20), // 可选:微调位置
+ showBackground: true, // 确保背景显示(某些版本需要)
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+ verticalOrigin: Cesium.VerticalOrigin.CENTER,
+ outlineWidth: 1,
+ outlineColor: Cesium.Color.WHITE,
+ eyeOffset: new Cesium.Cartesian3(0, 0, -20), // 负值更靠近相机(显示在前)
+ },
+ })
+ } else {
+ redPointEntity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude)
+ redPointEntity.label.text = `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`
+ }
+}
+
+function positionClosed () {
+ // 清除地图相关数据
+ if (viewer && leftClickBound) {
+ map.publicCesium?.removeLeftClickEvent?.(null, LeftClickEvent)
+ leftClickBound = false
+ }
+ redPointEntity = null
+ viewer = null
+}
+
+// 监听设备数据变化,更新表单
+watch(
+ () => props.equipmentData,
+ (newData) => {
+ if (newData) {
+ Object.assign(formData.value, newData)
+ } else {
+ formData.value = initForm()
+ }
+ },
+ { deep: true, immediate: true }
+)
+
+// 处理关闭
+function handleClose() {
+ dialogVisible.value = false
+ positionClosed()
+ resetForm()
+}
+
+// 重置表单
+function resetForm() {
+ formRef.value?.resetFields()
+ // 重置为默认值
+ Object.assign(formData.value, {
+ childSn: '', // 子设备(一般用途是机场下面的无人机)
+ deviceName: '', // 设备型号f
+ devicePayload: '', // 设备负载(红外,喇叭,闪光灯)
+ deviceSn: '', // 设备编码
+ deviceType: null, // 设备类型(0机场,1无人机)
+ firmwareVersion: '', // 固件版本
+ insureExpiredTime: '', // 保险过期时间yyyy-MM-dd HH:mm:ss
+ latitude: 0, // 当前纬度
+ longitude: 0, // 当前经度
+ modeCode: null, // 设备状态:{0:"在线",1:"离线"}
+ nickname: '', // 设备昵称
+ trafficExpireTime: '', // 流量到期时间yyyy-MM-dd HH:mm:ss
+ trafficRemaining: '', // 剩余流量(单位:GB)
+ address: '', // 设备位置
+ departmentId: '', // 所属部门
+ })
+}
+
+// 处理提交
+async function handleSubmit() {
+ const isValid = await formRef.value?.validate()
+ if (!isValid) {
+ return
+ }
+
+ try {
+ if (props.dialogType === 'add') {
+ await submitExternalEquipment(formData.value)
+ ElMessage.success('添加成功')
+ } else if (props.dialogType === 'edit') {
+ await submitExternalEquipment(formData.value)
+ ElMessage.success('编辑成功')
+ }
+ emit('confirm')
+ dialogVisible.value = false
+ resetForm()
+ } catch (error) {
+ ElMessage.error('操作失败')
+ }
+}
+
+// 地图加载完毕
+function mapReady() {
+ mapRef.value.flyBoundary()
+}
+
+// 初始化地图实例
+function initMap() {
+ if (viewer) return
+ const map = mapRef.value?.getMap()
+ viewer = map?.viewer || null
+}
+</script>
+<style scoped lang="scss">
+.gd-form {
+ .el-form-item {
+ margin-bottom: 20px;
+ }
+}
+.command-page-map-view-dialog {
+ margin: 0;
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ width: 80%;
+ height: 812px;
+ background: #1A1A2A;
+ border-radius: 6px;
+ border: 1px solid #2E2E46;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+
+ .el-dialog__header,
+ .el-dialog__footer {
+ margin: 0;
+ padding: 0;
+ }
+
+ .el-dialog__footer {
+ margin-top: 20px;
+ text-align: center;
+
+ .el-button {
+ margin: 0 10px;
+ }
+ }
+
+ .el-dialog__body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ min-height: 600px;
+ padding: 0;
+
+ .dialog-container {
+ display: flex;
+ height: 100%;
+
+ .left-container {
+ width: 100%;
+ height: 100%;
+
+ .leftMap {
+ width: 100%;
+ height: 100%;
+ min-height: 600px;
+ }
+ }
+ }
+ }
+}
+
+</style>
\ No newline at end of file
diff --git a/applications/task-work-order/src/views/orderView/equipmentResource/index.vue b/applications/task-work-order/src/views/orderView/equipmentResource/index.vue
new file mode 100644
index 0000000..4fc6958
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/equipmentResource/index.vue
@@ -0,0 +1,237 @@
+<!-- 设备资源管理 -->
+<template>
+ <basic-container>
+ <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
+ <el-form-item label="设备名称" prop="nickname">
+ <el-input
+ class="gd-input gray"
+ v-model="searchParams.nickname"
+ placeholder="请输入设备名称"
+ clearable
+ @clear="handleSearch"
+ />
+ </el-form-item>
+
+ <el-form-item label="设备类型" prop="deviceType">
+ <el-select
+ class="gd-select gray"
+ popper-class="gd-select-popper"
+ v-model="searchParams.deviceType"
+ placeholder="请选择"
+ clearable
+ @change="handleSearch"
+ >
+ <el-option
+ v-for="item in deviceTypeOptions"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+
+ <el-form-item label="设备状态" prop="modeCode">
+ <el-select
+ class="gd-select gray"
+ popper-class="gd-select-popper"
+ v-model="searchParams.modeCode"
+ placeholder="请选择"
+ clearable
+ @change="handleSearch"
+ >
+ <el-option
+ v-for="item in dictObj.modeCode"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+
+ <el-form-item class="gd-search-actions">
+ <el-button :icon="RefreshRight" @click="resetForm"></el-button>
+ <el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+ </el-form-item>
+ </el-form>
+
+ <div class="gd-table-toolbar">
+ <el-button :icon="Plus" color="#4C34FF" type="primary" @click="addEquipment">新增</el-button>
+ </div>
+
+ <div class="gd-table-container" v-loading="loading">
+ <div class="gd-table-content gd-table-content-bg">
+ <el-table class="gd-table" :data="list">
+ <el-table-column type="index" width="64" label="序号" />
+ <el-table-column prop="deviceType" show-overflow-tooltip label="设备类型">
+ <template v-slot="{ row }">
+ {{ row.deviceType === '1' ? '无人机' : '机场' }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="deviceName" show-overflow-tooltip label="设备型号" />
+ <el-table-column prop="nickname" show-overflow-tooltip label="设备名称" />
+ <el-table-column prop="devicePayload" show-overflow-tooltip label="负载设备" />
+ <el-table-column prop="modeCode" show-overflow-tooltip label="设备状态">
+ <template v-slot="{ row }">
+ {{ getDictLabel(row.modeCode, dictObj.modeCode) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="deviceSn" show-overflow-tooltip label="设备SN" />
+ <el-table-column show-overflow-tooltip label="设备位置" >
+ <template v-slot="{ row }">
+ {{ row.latitude ? (row.latitude + ', ' + row.longitude) : '未定位' }}
+ </template>
+ </el-table-column>
+ <!-- <el-table-column prop="firmwareVersion" show-overflow-tooltip label="固件版本" /> -->
+ <el-table-column prop="deviceDeptName" show-overflow-tooltip label="所属部门" />
+ <el-table-column label="操作" class-name="operation-btns" width="180">
+ <template v-slot="{ row }">
+ <el-link @click="viewEquipment(row)">查看</el-link>
+ <el-link type="primary" @click="editEquipment(row)">编辑</el-link>
+ <el-link type="danger" @click="deleteEquipment(row)">删除</el-link>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <div class="gd-pagination-parent">
+ <el-pagination
+ popper-class="gd-select-popper"
+ v-model:current-page="searchParams.current"
+ v-model:page-size="searchParams.size"
+ layout="total, prev, pager, next, sizes"
+ :total="total"
+ @change="getList"
+ />
+ </div>
+ </div>
+
+ <!-- 设备资源弹窗 -->
+ <EquipmentResourceDialog
+ ref="equipmentResourceDialogRef"
+ v-model="dialogVisible"
+ :dialog-type="dialogType"
+ :equipment-data="equipmentData"
+ @confirm="handleConfirm"
+ />
+ </basic-container>
+</template>
+<script setup>
+import { Search, RefreshRight, Plus } from '@element-plus/icons-vue'
+import { onMounted, ref, nextTick } from 'vue'
+import { getDictionaryByCode } from '@/api/system/dictbiz'
+import { getDictLabel } from '@ztzf/utils'
+import { getEquipmentPage, removeEquipment } from './equipmentResourceApi'
+import EquipmentResourceDialog from './FormDiaLog.vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+// 初始化查询参数
+const initSearchParams = () => ({
+ nickname: '', // 设备名称
+ deviceType: '', // 设备类型
+ modeCode: '', // 设备状态
+ current: 1, // 当前页
+ size: 10, // 每页大小
+})
+const searchParams = ref(initSearchParams()) // 查询参数
+const total = ref(0) // 总条数
+const loading = ref(true) // 列表加载中
+const list = ref([]) // 列表数据
+const queryParamsRef = ref(null) // 查询表单实例
+const equipmentResourceDialogRef = ref(null)
+const dialogVisible = ref(false)
+const dialogType = ref('add') // add, edit, view
+const equipmentData = ref({})
+
+// 设备类型(0机场,1无人机)
+const deviceTypeOptions = ref([
+ { dictKey: 0, dictValue: '机场' },
+ { dictKey: 1, dictValue: '无人机' }
+])
+
+
+const dictObj = ref({
+ modeCode: []
+})
+
+provide('dictObj', dictObj)
+
+// 获取列表
+async function getList() {
+ loading.value = true
+ try {
+ const res = await getEquipmentPage(searchParams.value)
+ list.value = res?.data?.data?.records ?? []
+ total.value = res?.data?.data?.total ?? 0
+ } finally {
+ loading.value = false
+ }
+}
+
+// 查询
+function handleSearch() {
+ searchParams.value.current = 1
+ getList()
+}
+
+// 重置查询
+function resetForm() {
+ queryParamsRef.value?.resetFields()
+ searchParams.value.current = 1
+ getList()
+}
+
+// 添加设备
+function addEquipment() {
+ dialogType.value = 'add'
+ equipmentData.value = {}
+ dialogVisible.value = true
+}
+
+// 查看设备
+function viewEquipment(row) {
+ dialogType.value = 'view'
+ equipmentData.value = { ...row }
+ dialogVisible.value = true
+}
+
+// 编辑设备
+function editEquipment(row) {
+ dialogType.value = 'edit'
+ equipmentData.value = { ...row }
+ dialogVisible.value = true
+}
+
+// 删除设备
+async function deleteEquipment(row) {
+ const tips = row ? '该条' : '选中的项'
+ await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', {
+ type: 'warning',
+ customClass: 'gd-confirm-custom',
+ confirmButtonClass: 'gd-confirm-button',
+ cancelButtonClass: 'gd-confirm-cancel-button',
+ })
+ const ids = row ? row.id : selectedIds.value.join(',')
+ await removeEquipment({ ids: ids })
+ ElMessage.success('删除成功')
+ getList()
+}
+
+// 处理弹窗确认
+function handleConfirm() {
+ dialogVisible.value = false
+ getList()
+}
+
+// 获取字典
+function getDictList() {
+ getDictionaryByCode('modeCode').then(res => {
+ dictObj.value = res.data.data
+ })
+}
+
+onMounted(() => {
+ getDictList()
+ getList()
+})
+</script>
+<style scoped lang="scss"></style>
\ No newline at end of file
--
Gitblit v1.9.3