From 3b6179e11dbb8b8e2da9dcceda0e0e269b1459cb Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Thu, 22 Jan 2026 10:31:10 +0800
Subject: [PATCH] feat: 需求方

---
 /dev/null                                                                                              |  294 -------------------------------------------------
 applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue                     |   11 +
 applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/inspectionRequestApi.js |    2 
 applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue                |   50 ++++++-
 4 files changed, 50 insertions(+), 307 deletions(-)

diff --git a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/inspectionRequestApi.js b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/inspectionRequestApi.js
index 0123165..3d9a491 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/inspectionRequestApi.js
+++ b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/inspectionRequestApi.js
@@ -1,6 +1,6 @@
 import request from '@/axios'
 
-// 分页查询
+// 分页查询巡查page
 export const gdPatrolTaskPageApi = params => {
 	return request({
 		url: `/drone-gd/workOrder/gdPatrolTask/page`,
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
index f054c12..47e50c3 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
@@ -48,6 +48,31 @@
 						<el-table-column prop="deviceName" label="设备型号" />
 						<el-table-column prop="devicePayload" label="设备负载" />
 					</el-table>
+					<template v-if="hasPatrolTaskList">
+						<div class="detail-title" :style="{ marginTop: pxToRem(20) }">巡查任务名称</div>
+						<el-table class="setHeight" :data="patrolTaskList" row-key="id">
+							<el-table-column prop="patrolTaskName" show-overflow-tooltip label="巡查任务名称" />
+							<el-table-column prop="patrolTaskType" show-overflow-tooltip label="巡查任务类型">
+								<template v-slot="{ row }">
+									{{ getDictLabel(row.patrolTaskType, dictObj.patrolTaskType) }}
+								</template>
+							</el-table-column>
+							<el-table-column prop="taskStatus" show-overflow-tooltip label="任务状态">
+								<template v-slot="{ row }">
+									{{ getDictLabel(row.taskStatus, dictObj.taskStatus) }}
+								</template>
+							</el-table-column>
+							<el-table-column prop="executeTime" show-overflow-tooltip label="任务执行时间" />
+							<el-table-column prop="feishou" show-overflow-tooltip label="选择飞手" />
+							<el-table-column prop="deviceId" show-overflow-tooltip label="选择设备" />
+							<el-table-column label="操作" class-name="operation-btns">
+								<template v-slot="{ row }">
+									<el-link type="primary" @click="">查看</el-link>
+								</template>
+							</el-table-column>
+						</el-table>
+					</template>
+
 				</div>
 				<el-form
 					class="gd-dialog-form"
@@ -217,6 +242,7 @@
 import dayjs from 'dayjs'
 import RefuseOrderDialog from '@/views/orderView/orderManage/orderManage/RefuseOrderDialog.vue'
 import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
+import { gdPatrolTaskPageApi } from '@/views/orderView/orderManage/inspectionRequest/inspectionRequestApi'
 
 // 初始化表单数据
 const initForm = () => ({
@@ -234,6 +260,7 @@
 const rejectVisible = ref(false)
 const dictObj = inject('dictObj')
 const dateRange = ref([])
+const patrolTaskList = ref([])
 const emit = defineEmits(['success'])
 const formRef = ref(null) // 表单实例
 const formData = ref(initForm()) // 表单数据
@@ -425,22 +452,27 @@
 	})
 }
 
+const hasPatrolTaskList = computed(() => ['30','40','50','60'].includes(String(formData.value.workOrderStatus)))
+
+function gdPatrolTaskPage() {
+	gdPatrolTaskPageApi({ current: 1, size: 1000, workOrderId: formData.value.id }).then(res => {
+		patrolTaskList.value = res.data.data.records || []
+	})
+}
+
 // 打开弹框
 async function open({ mode = 'add', row } = {}) {
 	dialogMode.value = mode
 	formData.value = dialogMode.value === 'add' ? initForm() : row
 	initMap()
-	if (dialogMode.value !== 'add') {
-		await loadDetail()
-	}
-	await getDeviceList()
 	if (dialogMode.value === 'add') {
 		addPolygon()
-	} else if (dialogMode.value === 'edit') {
-		editPolygon()
 	} else {
-		viewPolygon()
+		await loadDetail()
+		hasPatrolTaskList.value && gdPatrolTaskPage()
+		dialogMode.value === 'edit' ? editPolygon() : viewPolygon()
 	}
+	await getDeviceList()
 	await nextTick()
 	syncSelection()
 }
@@ -486,7 +518,7 @@
 }
 
 .setHeight {
-	max-height: 300px;
-	min-height: 200px;
+	//max-height: 300px;
+	//min-height: 200px;
 }
 </style>
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
index 66eb64c..6a1fd8d 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
@@ -68,7 +68,7 @@
 		</el-form>
 
 		<div class="gd-table-toolbar">
-			<el-button color="#F2F3F5" @click="requester = !requester">我是{{ requester ? '需求方' : '服务方' }}</el-button>
+<!--			<el-button color="#F2F3F5" @click="requester = !requester">我是{{ requester ? '需求方' : '服务方' }}</el-button>-->
 			<el-button color="#F2F3F5" @click="previewVisible = true">预览</el-button>
 
 			<el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
@@ -144,6 +144,11 @@
 import PreviewFiles from '@/components/PreviewFiles/PreviewFiles.vue'
 import testDock from '@/assets/docx/testDocx.docx'
 import testPdf from '@/assets/pdf/testPdf.pdf'
+import { useStore } from 'vuex'
+
+const store = useStore()
+const requester = computed(() => store.state.user.userInfo?.role_id === '2014158512610869250')
+
 
 // 初始化查询参数
 const initSearchParams = () => ({
@@ -155,7 +160,7 @@
 	current: 1, // 当前页
 	size: 10, // 每页大小
 })
-const requester = ref(true)
+// const requester = ref(true)
 const searchParams = ref(initSearchParams()) // 查询参数
 const dateRange = ref([]) // 执行时间范围
 const total = ref(0) // 总条数
@@ -246,7 +251,7 @@
 
 // 获取字典
 function getDictList() {
-	getDictionaryByCode('deviceLoadDemand,workOrderType,workOrderStatus').then(res => {
+	getDictionaryByCode('deviceLoadDemand,workOrderType,workOrderStatus,patrolTaskType,taskStatus').then(res => {
 		dictObj.value = res.data.data
 	})
 }
diff --git a/applications/task-work-order/src/views/orderView/orderManage/orderManage/test.vue b/applications/task-work-order/src/views/orderView/orderManage/orderManage/test.vue
deleted file mode 100644
index 73d5851..0000000
--- a/applications/task-work-order/src/views/orderView/orderManage/orderManage/test.vue
+++ /dev/null
@@ -1,294 +0,0 @@
-<template>
-	<el-dialog  v-model="visible" :title="titleEnum[dialogMode]" :close-on-click-modal="false" width="80%">
-		<div class="bodyBox">
-			<div class="leftMap ztzf-cesium" id="mapContainer"></div>
-			<div class="rightInfo">
-				<div v-if="readonly">
-					<div>防区名称: {{ formData.zoneName }}</div>
-					<div>防区面积: {{ formatZoneArea(formData.zoneArea) }}</div>
-					<el-table :data="sceneList" row-key="id">
-						<el-table-column prop="sceneName" label="场景名称" />
-						<el-table-column prop="sceneType" label="场景类型">
-							<template v-slot="{ row }">
-								{{ getDictLabel(row.sceneType, dictObj.sceneType) }}
-							</template>
-						</el-table-column>
-					</el-table>
-				</div>
-				<el-form v-else ref="formRef" :model="formData" :rules="rules" :disabled="readonly" label-width="100px">
-					<el-row>
-						<el-col :span="24">
-							<el-form-item label="防区名称" prop="zoneName">
-								<el-input v-model="formData.zoneName" maxlength="50" placeholder="请输入" clearable />
-							</el-form-item>
-						</el-col>
-						<el-col :span="24">
-							<el-form-item label="防区面积" prop="zoneArea">{{ formatZoneArea(formData.zoneArea) }}</el-form-item>
-						</el-col>
-						<el-col :span="24">
-							<div>
-								<div>
-									关联场景
-									<el-input v-model="searchName" placeholder="请输入" clearable></el-input>
-								</div>
-								<el-form-item label="关联场景" prop="defenseSceneIds" label-width="0">
-									<el-table
-										ref="sceneTableRef"
-										:data="sceneList.filter(item => item.sceneName.includes(searchName))"
-										row-key="id"
-										@selection-change="handleSceneSelectionChange"
-									>
-										<el-table-column type="selection" width="55" :reserve-selection="true" />
-										<el-table-column prop="sceneName" label="场景名称" />
-										<el-table-column prop="sceneType" label="场景类型">
-											<template v-slot="{ row }">
-												{{ getDictLabel(row.sceneType, dictObj.sceneType) }}
-											</template>
-										</el-table-column>
-									</el-table>
-								</el-form-item>
-							</div>
-						</el-col>
-					</el-row>
-				</el-form>
-			</div>
-		</div>
-		<template #footer>
-			<el-button @click="handleCancel">{{ readonly ? '关闭' : '取消' }}</el-button>
-			<el-button v-if="!readonly" type="primary" :loading="submitting" :disabled="submitting" @click="handleSubmit">
-				确定
-			</el-button>
-		</template>
-	</el-dialog>
-</template>
-
-<script setup>
-import { computed, inject, nextTick, ref } from 'vue'
-import { ElMessage } from 'element-plus'
-import { fwDefenseZoneDetailApi, fwDefenseZoneSubmitApi } from './defenseZoneApi'
-import { fwDefenseSceneListApi } from '@/views/areaManage/sceneConfig/sceneConfigApi'
-import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils'
-import { PublicCesium } from '@/utils/cesium/publicCesium'
-import { DrawPolygon } from '@/utils/cesium/DrawPolygon'
-import { cartesian3Convert } from '@/utils/cesium/mapUtil'
-import * as turf from '@turf/turf'
-import * as Cesium from 'cesium'
-
-// 初始化表单
-const initForm = () => ({
-	defenseSceneIds: '', // 关联场景ID
-	geom: '', // 经纬度面
-	zoneArea: null, // 防区面积
-	zoneName: '', // 防区名称
-})
-
-const emit = defineEmits(['success'])
-const formRef = ref(null) // 表单实例
-const formData = ref(initForm()) // 表单数据
-const visible = defineModel() // 弹框显隐
-const dialogMode = ref('add') // 弹框模式
-const submitting = ref(false) // 提交中
-const readonly = computed(() => dialogMode.value === 'view')
-const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
-const sceneTableRef = ref(null)
-const searchName = ref('')
-const sceneList = ref([]) // 关联场景列表
-const selectedSceneRows = ref([]) // 选中场景
-const dictObj = inject('dictObj')
-let viewer
-let drawPolygonExample
-let pointList = []
-
-const rules = {
-	zoneName: fieldRules(true, 50),
-	defenseSceneIds: fieldRules(true),
-	zoneArea: fieldRules(true),
-}
-
-// 关闭弹框
-function handleCancel() {
-	visible.value = false
-}
-
-// 提交新增/编辑
-async function handleSubmit() {
-	const isValid = await formRef.value?.validate().catch(() => false)
-	if (!isValid) return
-	if (!pointList.length) {
-		ElMessage.warning('请绘制防区范围')
-		return
-	}
-	submitting.value = true
-	try {
-		const ids = selectedSceneRows.value.map(item => item.id)
-		formData.value.defenseSceneIds = ids.join(',')
-		const str = [...pointList, pointList[0]].map(item => `${item.longitude} ${item.latitude}`).join(',')
-		formData.value.geom = `POLYGON((${str}))`
-		await fwDefenseZoneSubmitApi(formData.value)
-		ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
-		visible.value = false
-		emit('success')
-	} finally {
-		submitting.value = false
-	}
-}
-
-// 加载详情
-async function loadDetail() {
-	if (!formData.value.id) return
-	const res = await fwDefenseZoneDetailApi({ id: formData.value.id })
-	formData.value = res?.data?.data ?? initForm()
-}
-
-// 获取场景列表
-async function getSceneList() {
-	const res = await fwDefenseSceneListApi({ filterSelected: 1, zoneId: formData.value.id })
-	sceneList.value = res?.data?.data ?? []
-	if (readonly.value) {
-		const ids = getSceneIdList()
-		sceneList.value = sceneList.value.filter(item => ids.includes(item.id))
-	}
-}
-
-// 获取场景ID列表
-function getSceneIdList() {
-	if (!formData.value.defenseSceneIds) return []
-	return formData.value.defenseSceneIds.split(',')
-}
-
-// 关联场景变更
-function handleSceneSelectionChange(rows) {
-	selectedSceneRows.value = rows
-	formData.value.defenseSceneIds = rows.map(item => item.id).join(',')
-}
-
-// 同步关联场景
-function syncSceneSelection() {
-	if (!sceneTableRef.value) return
-	sceneTableRef.value.clearSelection()
-	const ids = getSceneIdList()
-	const rows = []
-	sceneList.value.forEach(row => {
-		if (ids.includes(row.id)) {
-			sceneTableRef.value.toggleRowSelection(row, true)
-			rows.push(row)
-		}
-	})
-	selectedSceneRows.value = rows
-}
-
-// 格式化防区面积
-function formatZoneArea(value) {
-	if (value == null || value === '') return ''
-	return `${value}k㎡`
-}
-
-// 初始化地图实例
-function initMap() {
-	const publicCesiumInstance = new PublicCesium({
-		dom: 'mapContainer',
-		flatMode: false,
-		terrain: true,
-		layerMode: 4,
-		boundary: false,
-	})
-	viewer = publicCesiumInstance.getViewer()
-}
-
-// 绘制完成回调
-const drawFinished = async data => {
-	pointList = _.cloneDeep(data).map(item => {
-		const val = cartesian3Convert(item, viewer)
-		return { ...val, lng: val.longitude, lat: val.latitude }
-	})
-	if (!pointList.length) return
-	const polygon = turf.polygon([
-		[...pointList.map(item => [item.longitude, item.latitude]), [pointList[0].longitude, pointList[0].latitude]],
-	])
-	const areaSqm = turf.area(polygon) // 平方米
-	formData.value.zoneArea = _.round(areaSqm / 1_000_000, 2) // 平方千米
-}
-
-// 新增模式绘制
-function addPolygon() {
-	drawPolygonExample = new DrawPolygon(viewer)
-	drawPolygonExample.initHandler(viewer)
-	drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
-}
-
-// 编辑面
-function editPolygon() {
-	if (!formData.value?.geom) return
-	pointList = geomAnalysis(formData.value.geom)
-	drawPolygonExample?.destroy()
-	drawPolygonExample = new DrawPolygon(viewer)
-	let noClosedList = _.cloneDeep(pointList)
-	noClosedList.pop()
-	drawPolygonExample.initPolygon(
-		viewer,
-		noClosedList.map(item => ({ lng: item.longitude, lat: item.latitude }))
-	)
-	drawPolygonExample.subscribe('getPolygonPositions', drawFinished)
-}
-
-// 查看面
-function viewPolygon() {
-	if (!formData.value?.geom) return
-	pointList = geomAnalysis(formData.value.geom)
-	const result = pointList.map(item => [item.longitude, item.latitude]).flat()
-	const mian = viewer.entities?.add({
-		customType: 'control_group',
-		position: Cesium.Cartesian3.fromDegrees(result[0], result[1]),
-		polyline: {
-			positions: Cesium.Cartesian3.fromDegreesArray(result),
-			clampToGround: true,
-			width: 3,
-			material: Cesium.Color.RED,
-		},
-	})
-	viewer.flyTo(mian)
-}
-
-// 打开弹框
-async function open({ mode, row } = {}) {
-	dialogMode.value = mode || 'add'
-	formData.value = dialogMode.value === 'add' ? initForm() : row
-	selectedSceneRows.value = []
-	pointList = []
-	await nextTick()
-	initMap()
-	if (dialogMode.value !== 'add') {
-		await loadDetail()
-	}
-	await getSceneList()
-	if (dialogMode.value === 'add') {
-		addPolygon()
-	} else if (dialogMode.value === 'edit') {
-		editPolygon()
-	} else {
-		viewPolygon()
-	}
-	await nextTick()
-	syncSceneSelection()
-}
-
-defineExpose({
-	open,
-})
-</script>
-
-<style scoped lang="scss">
-.bodyBox {
-	display: flex;
-	height: 600px;
-	.leftMap {
-		width: 70%;
-		height: 100%;
-	}
-	.rightInfo {
-		width: 30%;
-		height: 100%;
-		overflow: auto;
-	}
-}
-</style>

--
Gitblit v1.9.3