From 150ba60e3436b3e6a418b0a66723938b5dc2cfb8 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Fri, 31 Jul 2026 17:17:14 +0800
Subject: [PATCH] feat:处置功能

---
 uniapps/work-app/src/api/work/index.js                                                       |   82 +
 uniapps/work-app/src/pages/work/index.vue                                                    |  643 +++++----
 uniapps/work-app/src/subPackages/workDetail/HandleWork/index.vue                             |  295 ++++
 applications/task-work-order/src/views/orderView/orderManage/eventManage/index.vue           |  231 +++
 applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue |   14 
 applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue            |    8 
 applications/task-work-order/src/views/orderView/orderManage/eventManage/OrderStepBar.vue    |  225 +++
 applications/task-work-order/src/views/orderView/orderManage/eventManage/ViewDiaLog.vue      |  343 +++++
 applications/task-work-order/src/views/orderView/orderManage/eventManage/eventManageApi.js   |   25 
 applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue       |   19 
 uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue                          |  381 ++++++
 uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue                     |  470 +++++++
 uniapps/work-app/src/subPackages/workDetail/index.vue                                        |  891 ++++++++++----
 13 files changed, 3,032 insertions(+), 595 deletions(-)

diff --git a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue
index 6ee6ffc..92039c2 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue
@@ -12,7 +12,13 @@
 			<el-row>
 				<el-col :span="24">
 					<el-form-item label="事件名称" prop="eventName">
-						<el-input class="gd-input" v-model="formData.eventName" placeholder="请输入" clearable />
+						<el-input
+							:disabled="distributeStatus === 2"
+							class="gd-input"
+							v-model="formData.eventName"
+							placeholder="请输入"
+							clearable
+						/>
 					</el-form-item>
 				</el-col>
 				<el-col :span="24">
@@ -79,6 +85,7 @@
 const userList = ref([])
 const currentRow = ref(null) // 当前线索数据
 const workOrderId = ref(null) // 工单ID
+const distributeStatus = ref(null)
 
 // 校验规则
 const rules = {
@@ -119,7 +126,7 @@
 			eventName: formData.value.eventName,
 			latitude: currentRow.value.latitude || 0,
 			longitude: currentRow.value.longitude || 0,
-			resultId: currentRow.value.id,
+			resultId: currentRow.value.resultId ? currentRow.value.resultId : currentRow.value.id,
 			workOrderId: workOrderId.value,
 		}
 		await gdTaskResultDistributeApi(params)
@@ -139,9 +146,12 @@
 
 // 打开弹框
 async function open({ row, workOrderId: orderId } = {}) {
+	console.log('333',row)
 	currentRow.value = row
 	workOrderId.value = orderId
 	formData.value = initForm()
+	formData.value.eventName = row.eventName
+	distributeStatus.value = row.distributeStatus || row.eventStatus
 }
 
 defineExpose({ open })
diff --git a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
index 7e13fa1..1eca57c 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
@@ -1,5 +1,5 @@
 <template>
-	<el-dialog class="gd-dialog" v-model="visible" title="查看" @closed="visible = false" width="1000px" destroy-on-close>
+	<el-dialog class="gd-dialog" v-model="visible" title="查看" @closed="handleClose" width="1000px" destroy-on-close>
 		<div v-loading="loading">
 			<el-table :data="list" class="gd-dialog-table">
 				<el-table-column label="线索缩略图" width="120">
@@ -60,12 +60,7 @@
 		/>
 	</el-dialog>
 
-	<VideoPlayDialog
-		ref="videoPlayDialogRef"
-		v-if="VideoShow"
-		v-model="VideoShow"
-		:playUrl="currentVideo.resultUrl"
-	/>
+	<VideoPlayDialog ref="videoPlayDialogRef" v-if="VideoShow" v-model="VideoShow" :playUrl="currentVideo.resultUrl" />
 </template>
 
 <script setup>
@@ -83,6 +78,7 @@
 const permission = computed(() => store.state.user.permission)
 console.log(permission.value.clueEvents_distribute, 'permission')
 
+const emit = defineEmits(['success'])
 const visible = defineModel()
 const loading = ref(false)
 const list = ref([])
@@ -119,11 +115,11 @@
 	if (!currentRow.value?.id) return
 	loading.value = true
 	try {
-		const res = await gdTaskResultListApi({ patrolTaskId: currentRow.value.id})
+		const res = await gdTaskResultListApi({ patrolTaskId: currentRow.value.id })
 		list.value = await Promise.all(
 			(res?.data?.data ?? []).map(async item => {
 				if (item.attachmentType !== 2) return item
-				const aiImg = await getAiImg(item.resultUrl,item.geojson)
+				const aiImg = await getAiImg(item.resultUrl, item.geojson)
 				return { ...item, aiImg }
 			})
 		)
@@ -155,6 +151,11 @@
 	await getList()
 }
 
+function handleClose() {
+	emit('success')
+	visible = false
+}
+
 defineExpose({ open })
 </script>
 
diff --git a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue
index 1d83c34..51ae432 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/clueEvents/index.vue
@@ -105,7 +105,7 @@
 			</div>
 		</div>
 
-		<ViewDiaLog ref="viewDiaLogRef" v-if="viewDiaLogVisible" v-model="viewDiaLogVisible" />
+		<ViewDiaLog ref="viewDiaLogRef" v-if="viewDiaLogVisible" v-model="viewDiaLogVisible" @success="getList" />
 	</basic-container>
 </template>
 <script setup>
@@ -118,11 +118,7 @@
 import { getDeptTree } from '@/api/system/dept'
 import ViewDiaLog from './ViewDiaLog.vue'
 import { useStore } from 'vuex'
-import {
-	getTaskTypeLabel,
-	normalizeTaskTypeOptions,
-	taskTypeCascaderProps,
-} from '../taskTypeOptions'
+import { getTaskTypeLabel, normalizeTaskTypeOptions, taskTypeCascaderProps } from '../taskTypeOptions'
 
 // 初始化查询参数
 const initSearchParams = () => ({
diff --git a/applications/task-work-order/src/views/orderView/orderManage/eventManage/OrderStepBar.vue b/applications/task-work-order/src/views/orderView/orderManage/eventManage/OrderStepBar.vue
new file mode 100644
index 0000000..4089173
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderManage/eventManage/OrderStepBar.vue
@@ -0,0 +1,225 @@
+<template>
+	<div class="timeline-wrapper">
+		<div v-for="(stage, stageIndex) in processList" :key="stage.id || stageIndex" class="stage-group">
+			<!-- 大节点 Stage Node -->
+<!--			<div class="stage-node">-->
+<!--				<div class="stage-icon" :class="{ reached: 1 === 1 }">-->
+<!--					<el-icon v-if="1 === 1"><Check /></el-icon>-->
+<!--					<span v-else class="stage-index">{{ stageIndex + 1 }}</span>-->
+<!--				</div>-->
+<!--				<span class="stage-name" :class="{ reached: true }">{{ stage.newStatusName || stage.statusName || '-' }}</span>-->
+<!--			</div>-->
+
+			<!-- 小节点 Child Nodes -->
+			<div class="child-list">
+				<template v-for="(record, recordIndex) in getStageRecords(stage)" :key="record.id || recordIndex">
+					<div class="child-node">
+						<div class="child-left">
+							<span class="child-status">
+								{{
+									record.operateContent ||
+									record.operationContent ||
+									record.disposeContent ||
+									record.content ||
+									record.remark ||
+									stage.operateContent ||
+									'-'
+								}}
+							</span>
+						</div>
+						<div class="child-dot"></div>
+						<div class="child-right">
+							<span class="child-operator">
+								{{
+									record.operateUserName ||
+									record.operatorName ||
+									record.operateUser ||
+									record.operator ||
+									record.userName ||
+									stage.operateUserName ||
+									'-'
+								}}
+							</span>
+							<span class="child-time">
+								{{ record.operateTime || record.createTime || record.updateTime || stage.operateTime || '-' }}
+							</span>
+						</div>
+					</div>
+				</template>
+				<!-- 连接线 -->
+				<div class="connector-line" :class="{ reached: 1 === 1 }"></div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import { Check } from '@element-plus/icons-vue'
+
+const props = defineProps({
+	processList: {
+		type: Array,
+		default: () => [],
+	},
+})
+
+// 获取状态对应的事件记录
+function getStageRecords(stage) {
+	if (Array.isArray(stage.child) && stage.child.length) return stage.child
+	if (Array.isArray(stage.children) && stage.children.length) return stage.children
+	if (Array.isArray(stage.records) && stage.records.length) return stage.records
+	return [stage]
+}
+</script>
+
+<style scoped lang="scss">
+.timeline-wrapper {
+	padding-left: 100px;
+	position: relative;
+
+	.stage-group {
+		position: relative;
+	}
+
+	// 大节点 - Stage Node
+	.stage-node {
+		display: flex;
+		align-items: center;
+		gap: 12px;
+
+		.stage-icon {
+			width: 28px;
+			height: 28px;
+			border-radius: 50%;
+			background: #dbdde2;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			color: #fff;
+			font-size: 14px;
+			font-weight: 600;
+			flex-shrink: 0;
+			position: relative;
+			z-index: 2;
+
+			&.reached {
+				background: #1a1a2e;
+			}
+
+			.el-icon {
+				font-size: 16px;
+			}
+
+			.stage-index {
+				font-size: 12px;
+				color: #4e5969;
+			}
+		}
+
+		.stage-name {
+			width: 70px;
+			text-align: right;
+			position: absolute;
+			left: -80px;
+			font-family: Roboto, Roboto;
+			font-weight: bold;
+			font-size: 16px;
+			color: rgba(0, 0, 0, 0.45);
+
+			&.reached {
+				color: #4c34ff;
+			}
+		}
+	}
+
+	// 小节点 - Child Nodes
+	.child-list {
+		position: relative;
+		left: -92px;
+		min-height: 80px;
+		overflow: visible;
+
+		// 连接线
+		.connector-line {
+			position: absolute;
+			left: 105px;
+			width: 1px;
+			height: calc(100% - 5px);
+			top: 50%;
+			transform: translateY(-50%);
+			background: #cccccc;
+			z-index: 1;
+
+			&.reached {
+				background: #4c34ff;
+			}
+		}
+	}
+
+	.child-node {
+		display: flex;
+		align-items: flex-start;
+		position: relative;
+		padding: 40px 0;
+
+		&:last-child::before {
+			bottom: 50%;
+		}
+
+		.child-left {
+			width: 100px;
+			flex-shrink: 0;
+			text-align: right;
+			padding-right: 20px;
+			font-family: Source Han Sans CN, Source Han Sans CN;
+			font-weight: 400;
+			font-size: 14px;
+			color: rgba(0, 0, 0, 0.85);
+
+			.child-status {
+				white-space: normal;
+				overflow-wrap: anywhere;
+			}
+		}
+
+		.child-dot {
+			width: 12px;
+			height: 12px;
+			border-radius: 50%;
+			background: #1a1a2e;
+			flex-shrink: 0;
+			position: relative;
+			z-index: 2;
+			margin-top: 4px;
+		}
+
+		.child-right {
+			flex: 1;
+			min-width: 0;
+			padding-left: 12px;
+			display: flex;
+			flex-direction: column;
+			gap: 2px;
+			position: relative;
+
+			.child-operator {
+				font-family: Source Han Sans CN, Source Han Sans CN;
+				font-weight: 400;
+				font-size: 14px;
+				color: rgba(0, 0, 0, 0.85);
+				white-space: nowrap;
+			}
+
+			.child-time {
+				position: absolute;
+				top: 30px;
+				white-space: nowrap;
+				font-family: Source Han Sans CN, Source Han Sans CN;
+				font-weight: 400;
+				font-size: 14px;
+				color: rgba(0, 0, 0, 0.45);
+			}
+		}
+	}
+}
+</style>
diff --git a/applications/task-work-order/src/views/orderView/orderManage/eventManage/ViewDiaLog.vue b/applications/task-work-order/src/views/orderView/orderManage/eventManage/ViewDiaLog.vue
new file mode 100644
index 0000000..d3a0bbb
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderManage/eventManage/ViewDiaLog.vue
@@ -0,0 +1,343 @@
+<template>
+	<el-dialog
+		class="gd-dialog eventDialog"
+		v-model="visible"
+		title="查看"
+		@closed="visible = false"
+		width="80%"
+		destroy-on-close
+	>
+		<div class="content" style="display: flex">
+			<div class="processBox">
+				<div class="detail-title">事件记录</div>
+				<div class="process">
+					<!--					<OrderStepBar :processList="statusFlows" />-->
+					<!--					<el-steps direction="vertical" :active="1 === 1" space="100">-->
+					<!--						<el-step-->
+					<!--							v-for="(item, index) in statusFlows"-->
+					<!--							@key="item.id"-->
+					<!--							:title="item.newStatusName"-->
+					<!--							:description="item.operateUserName"-->
+					<!--						></el-step>-->
+					<!--					</el-steps>-->
+					<el-steps direction="vertical" :active="statusFlows.length" space="100" finish-status="success">
+						<el-step v-for="(item, index) in statusFlows" :key="item.id">
+							<template #title>
+								<div class="step-title">
+									<span class="status-name">{{ item.newStatusName }}</span>
+									<span class="operator-name">{{ item.operateUserName }}</span>
+								</div>
+							</template>
+							<template #description>
+								<div class="step-desc">
+									<span>{{ item.operateTime }}</span>
+									<span v-if="item.remark" class="remark">{{ item.remark }}</span>
+								</div>
+							</template>
+						</el-step>
+					</el-steps>
+				</div>
+			</div>
+			<div class="leftBox">
+				<div>
+					<div class="detail-title">事件详情</div>
+					<el-row class="detail-row-view">
+						<el-col :span="12">
+							<div class="label">事件名称</div>
+							<div class="val">{{ eventInfo.eventName }}</div>
+						</el-col>
+						<el-col :span="12">
+							<div class="label">事件编号</div>
+							<div class="val">{{ eventInfo.eventNum }}</div>
+						</el-col>
+						<el-col :span="12">
+							<div class="label">事件状态</div>
+							<div class="val">{{ getStatusLabel(eventInfo.eventStatus) }}</div>
+						</el-col>
+						<el-col :span="12">
+							<div class="label">事件时间</div>
+							<div class="val">
+								{{ dayjs(eventInfo.shootTime).format('YYYY-MM-DD') }}
+							</div>
+						</el-col>
+						<el-col :span="12">
+							<div class="label">处置人员</div>
+							<div class="val">{{ eventInfo.disposeUserName }}</div>
+						</el-col>
+						<el-col :span="12">
+							<div class="label">处置部门</div>
+							<div class="val">{{ eventInfo.disposeDeptName }}</div>
+						</el-col>
+					</el-row>
+				</div>
+				<div class="img_flow">
+					<div class="imgurl">
+						<el-image
+							:src="eventInfo.eventImageUrl"
+							:preview-src-list="[eventInfo.eventImageUrl]"
+							fit="cover"
+							preview-teleported
+						/>
+					</div>
+					<div class="flow">
+						<div v-if="disposeRecords.length === 0">
+							<el-empty description="暂无数据" />
+						</div>
+						<div v-else class="flow-card" v-for="item in disposeRecords" :key="item.id">
+							<div class="flow-row1">
+								<span class="flow-name">{{ item.disposeUserName }}</span>
+								<span class="flow-status">{{ item.disposeStatusName }}</span>
+							</div>
+							<div class="flow-row2">{{ item.disposeContent }}</div>
+							<div class="flow-row3" v-if="item.attachUrl?.length">
+								<el-image
+									v-for="(url, imageIndex) in item.attachUrl"
+									:key="`${item.id || 'record'}-${imageIndex}`"
+									class="flow-img-item"
+									:src="url"
+									:preview-src-list="item.attachUrl"
+									fit="cover"
+									preview-teleported
+								/>
+								<!--								<img-->
+								<!--									v-for="(url, imageIndex) in item.attachUrl"-->
+								<!--									:key="`${item.id || 'record'}-${imageIndex}`"-->
+								<!--									class="flow-img-item"-->
+								<!--									:src="url"-->
+								<!--									alt=""-->
+								<!--								/>-->
+							</div>
+							<div class="flow-row4">{{ item.operateTime }}</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</el-dialog>
+</template>
+
+<script setup>
+import dayjs from 'dayjs'
+import { getDetailFull } from './eventManageApi'
+import OrderStepBar from './OrderStepBar.vue'
+import { ref } from 'vue'
+
+const visible = defineModel()
+const eventInfo = ref({})
+const disposeRecords = ref([])
+const statusFlows = ref([])
+
+// 获取状态文本
+const getStatusLabel = status => {
+	const map = {
+		0: '待确认',
+		1: '处置中',
+		2: '已退回',
+		3: '已处置',
+		4: '已完成',
+	}
+	return map[status] || '未知'
+}
+
+// 兼容事件记录接口中不同版本的字段名称
+function normalizeStatusFlow(item = {}) {
+	return {
+		...item,
+		newStatusName: item.newStatusName || item.statusName || item.eventStatusName || '-',
+		operateContent:
+			item.operateContent || item.operationContent || item.disposeContent || item.content || item.remark || '-',
+		operateUserName:
+			item.operateUserName || item.operatorName || item.operateUser || item.operator || item.userName || '-',
+		operateTime: item.operateTime || item.createTime || item.updateTime || '-',
+	}
+}
+
+// 打开弹框
+async function open({ row } = {}) {
+	if (!row?.id) return
+	const res = await getDetailFull({ id: row.id })
+	const detail = res?.data?.data || {}
+	eventInfo.value = detail.eventInfo || {}
+	disposeRecords.value = detail.disposeRecords || []
+	statusFlows.value = (detail.statusFlows || []).map(normalizeStatusFlow)
+}
+
+defineExpose({ open })
+</script>
+<style lang="scss">
+.eventDialog {
+	.el-dialog__body {
+		display: flex;
+		flex-direction: column;
+		.content {
+			height: 0;
+			flex: 1;
+		}
+	}
+}
+</style>
+<style scoped lang="scss">
+.content {
+	display: flex;
+	gap: 0 20px;
+	//height: 630px;
+
+	.leftBox {
+		width: 0;
+		flex: 1;
+		display: flex;
+		overflow-y: auto;
+		overflow-x: hidden;
+		flex-direction: column;
+		scrollbar-width: none;
+
+		&::-webkit-scrollbar {
+			display: none;
+		}
+
+		//.gd-cesium {
+		//	position: relative;
+		//	//overflow: hidden;
+		//	width: 100%;
+		//	height: 390px;
+		//}
+		.img_flow {
+			//border: 1px solid red;
+			display: flex;
+			justify-content: space-between;
+			height: 436px;
+			margin-top: 20px;
+			.imgurl {
+				flex: 1;
+				height: 100%;
+				img {
+					height: 100%;
+					width: 100%;
+				}
+			}
+			.flow {
+				margin-left: 10px;
+				flex: 1;
+				min-width: 0;
+				min-height: 0;
+				overflow-y: auto;
+				overflow-x: hidden;
+				scrollbar-width: none;
+
+				&::-webkit-scrollbar {
+					display: none;
+				}
+
+				.flow-card {
+					display: flex;
+					flex-direction: column;
+					gap: 8px;
+					margin-bottom: 8px;
+					padding: 12px;
+					border: 1px solid #e4e4e4;
+					border-radius: 8px;
+					background: #fff;
+					.flow-row1 {
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+					}
+					.flow-row2 {
+						font-size: 14px;
+						font-weight: 500;
+					}
+					.flow-row3 {
+						display: flex;
+						flex-wrap: wrap;
+						gap: 8px;
+						.flow-img-item {
+							width: 60px;
+							height: 60px;
+							flex: 0 0 60px;
+							border: 1px solid #e4e4e4;
+							border-radius: 4px;
+							background: #f5f5f5;
+							object-fit: cover;
+						}
+					}
+					.flow-row4 {
+						font-size: 12px;
+						color: #999;
+					}
+				}
+			}
+		}
+	}
+
+	.rightBox {
+		width: 350px;
+		display: flex;
+		flex-direction: column;
+
+		.title {
+			font-weight: 500;
+			font-size: 14px;
+			color: #272e37;
+		}
+
+		::v-deep(.el-table) {
+			tr th {
+				font-weight: normal;
+			}
+		}
+	}
+
+	.processBox {
+		display: flex;
+		flex-direction: column;
+
+		.process {
+			height: 100%;
+			padding: 12px 16px 24px 16px;
+			width: 312px;
+			border: 1px solid #e4e4e4;
+			border-radius: 8px;
+			background: #fff;
+			overflow: auto;
+		}
+	}
+
+	.step-title {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		width: 100%;
+		padding-right: 10px;
+	}
+
+	.status-name {
+		font-weight: 500;
+		color: #4c34ff;
+		font-size: 14px;
+	}
+
+	.operator-name {
+		color: #909399;
+		font-size: 13px;
+		margin-left: 20px;
+	}
+
+	.step-desc {
+		color: #999999;
+		font-size: 12px;
+	}
+
+	.remark {
+		margin-left: 12px;
+		color: #e6a23c;
+	}
+	:deep(.el-step__icon.is-text) {
+		border-color: #4c34ff;
+	}
+	:deep(.el-step__head.is-success) {
+		color: #4c34ff;
+		height: 100px;
+		border-color: #4c34ff;
+	}
+}
+</style>
diff --git a/applications/task-work-order/src/views/orderView/orderManage/eventManage/eventManageApi.js b/applications/task-work-order/src/views/orderView/orderManage/eventManage/eventManageApi.js
new file mode 100644
index 0000000..57089b7
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderManage/eventManage/eventManageApi.js
@@ -0,0 +1,25 @@
+import request from '@/axios'
+
+// 获取工单列表
+export const getGdList = params => {
+	return request({
+		url: '/drone-gd/workOrder/gdClueEvent/list',
+		method: 'get',
+		params,
+	})
+}
+export const getDetailFull = params => {
+	return request({
+		url: '/drone-gd/workOrder/gdClueEvent/detailFull',
+		method: 'get',
+		params,
+	})
+}
+// 数量统计
+export const getCount = params => {
+	return request({
+		url: '/drone-gd/workOrder/gdClueEvent/count',
+		method: 'get',
+		params,
+	})
+}
diff --git a/applications/task-work-order/src/views/orderView/orderManage/eventManage/index.vue b/applications/task-work-order/src/views/orderView/orderManage/eventManage/index.vue
new file mode 100644
index 0000000..aaf7997
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderManage/eventManage/index.vue
@@ -0,0 +1,231 @@
+<!-- 线索事件管理 -->
+<template>
+	<basic-container>
+		<el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
+			<el-form-item label="模糊搜索" prop="patrolTaskName">
+				<el-input
+					class="gd-input gray"
+					v-model="searchParams.keyword"
+					placeholder="请输入"
+					clearable
+					@clear="handleSearch"
+				/>
+			</el-form-item>
+
+			<el-form-item label="事件状态" prop="taskStatus">
+				<el-select
+					class="gd-select"
+					popper-class="gd-select-popper"
+					v-model="searchParams.eventStatus"
+					placeholder="请选择"
+					clearable
+					@change="handleSearch"
+				>
+					<el-option v-for="item in eventStatus" :key="item.label" :label="item.label" :value="item.value" />
+				</el-select>
+			</el-form-item>
+
+			<el-form-item label="执行时间" prop="executeTime">
+				<el-date-picker
+					class="gd-date-picker gray"
+					popper-class="gd-date-picker-popper"
+					v-model="dateRange"
+					type="daterange"
+					range-separator="-"
+					start-placeholder="开始日期"
+					end-placeholder="结束日期"
+					value-format="YYYY-MM-DD HH:mm:ss"
+					@change="handleSearch"
+				/>
+			</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-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="eventName" show-overflow-tooltip label="事件名称" />
+					<el-table-column prop="eventNum" show-overflow-tooltip label="事件编号" />
+					<el-table-column prop="eventStatus" show-overflow-tooltip label="事件状态">
+						<template v-slot="{ row }">
+							{{ eventStatusMap[row.eventStatus] }}
+						</template>
+					</el-table-column>
+					<el-table-column prop="shootTime" show-overflow-tooltip label="事件时间" />
+					<el-table-column prop="disposeUserName" show-overflow-tooltip label="处置人员" />
+					<el-table-column prop="disposeDeptName" show-overflow-tooltip label="处置部门" />
+					<el-table-column label="操作" class-name="operation-btns" fixed="right">
+						<template v-slot="{ row }">
+							<el-link type="primary" @click="viewDiaLogView(row)">查看</el-link>
+							<el-link v-if="row.eventStatus === 2" type="primary" @click="viewDistribute(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>
+
+		<ViewDiaLog ref="viewDiaLogRef" v-if="viewDiaLogVisible" v-model="viewDiaLogVisible" />
+
+		<DistributeDiaLog
+			ref="distributeDialogRef"
+			v-if="distributeDialogVisible"
+			v-model="distributeDialogVisible"
+			@success="getList"
+		/>
+	</basic-container>
+</template>
+<script setup>
+import { Search, RefreshRight } from '@element-plus/icons-vue'
+import { computed, onMounted, ref } from 'vue'
+import { getDictionaryByCode } from '@/api/system/dictbiz'
+import { dateRangeFormat, getDictLabel } from '@ztzf/utils'
+// import { getDictListApi } from '@/api/zkxt'
+import { getGdList } from './eventManageApi'
+import { getDeptTree } from '@/api/system/dept'
+import ViewDiaLog from './ViewDiaLog.vue'
+import { useStore } from 'vuex'
+import { getTaskTypeLabel, normalizeTaskTypeOptions, taskTypeCascaderProps } from '../taskTypeOptions'
+import DistributeDiaLog from '@/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue'
+
+// 初始化查询参数
+const initSearchParams = () => ({
+	eventStatus: '',
+	keyword: '',
+	current: 1, // 当前页
+	size: 10, // 每页大小
+	startTime: '',
+	endTime: '',
+	onlyMine: 0,
+})
+const distributeDialogVisible = ref(false)
+const searchParams = ref(initSearchParams()) // 查询参数
+const dateRange = ref([]) // 执行时间范围
+const total = ref(0) // 总条数
+const loading = ref(true) // 列表加载中
+const list = ref([]) // 列表数据
+const queryParamsRef = ref(null) // 查询表单实例
+const viewDiaLogRef = ref(null)
+const distributeDialogRef = ref(null)
+const viewDiaLogVisible = ref(false)
+const deptTree = ref([]) // 部门树
+const treeProps = {
+	label: 'name',
+	children: 'children',
+}
+const dictObj = ref({
+	workOrderType: [], // 巡查任务类型
+	taskStatus: [], // 巡查任务状态
+})
+
+provide('dictObj', dictObj)
+provide('deptTree', deptTree)
+provide('treeProps', treeProps)
+
+// 事件状态
+const eventStatus = ref([
+	{ label: '待确认', value: 0 },
+	{ label: '处置中', value: 1 },
+	{ label: '已退回', value: 2 },
+	{ label: '已处置', value: 3 },
+	{ label: '已完成', value: 4 },
+])
+
+// 事件状态映射
+const eventStatusMap = computed(() => {
+	const map = {}
+	eventStatus.value.forEach(item => {
+		map[item.value] = item.label
+	})
+	return map
+})
+
+// 获取列表
+async function getList() {
+	const range = dateRangeFormat(dateRange.value)
+	loading.value = true
+	try {
+		const res = await getGdList({
+			...searchParams.value,
+			startTime: range[0],
+			endTime: range[1],
+		})
+		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()
+	dateRange.value = []
+	searchParams.value.current = 1
+	getList()
+}
+
+// 查看弹框
+function viewDiaLogView(row) {
+	viewDiaLogVisible.value = true
+	nextTick(() => {
+		viewDiaLogRef.value?.open({ row })
+	})
+}
+
+// 分发
+function viewDistribute(row) {
+	distributeDialogVisible.value = true
+	nextTick(() => {
+		distributeDialogRef.value?.open({ row })
+	})
+}
+
+// 获取字典
+function getDictList() {
+	getDictionaryByCode('workOrderType,taskStatus').then(res => {
+		dictObj.value = res.data.data
+	})
+	// getDictListApi('task_inspection_type').then(res => {
+	// 	workOrderTypeXT.value = normalizeTaskTypeOptions(res.data.data || [])
+	// })
+}
+
+const store = useStore()
+const userInfo = computed(() => store.state.user.userInfo)
+
+// 获取部门树
+function getDeptTreeFun() {
+	getDeptTree(userInfo.value.dept_id).then(res => {
+		deptTree.value = res.data.data
+	})
+}
+
+onMounted(() => {
+	getList()
+	getDictList()
+	getDeptTreeFun()
+})
+</script>
+<style scoped lang="scss"></style>
diff --git a/uniapps/work-app/src/api/work/index.js b/uniapps/work-app/src/api/work/index.js
index ca93e1a..569e4a9 100644
--- a/uniapps/work-app/src/api/work/index.js
+++ b/uniapps/work-app/src/api/work/index.js
@@ -1,5 +1,8 @@
 import { request } from "@/utils/requestGd/index.js"
 import website from '@/config/website'
+import { getEnvObj } from '@/utils/index.js'
+import { useUserStore } from '@/store/index.js'
+import { Base64 } from 'js-base64'
 
 
 // 工单用户登录接口
@@ -59,8 +62,79 @@
 // 分享缓存数据
 export const shareCacheApi = (data) => {
   return request({
-    url: '/drone-gd/workOrder/gdPatrolTask/share-cache-data',
-    method: 'post',
-    data,
-  })
+		url: '/drone-gd/workOrder/gdPatrolTask/share-cache-data',
+		method: 'post',
+		data,
+	})
+}
+
+// 新增处置记录
+export const addDisposeRecord = data => {
+	return request({
+		url: '/drone-gd/workOrder/gdClueEvent/addDisposeRecord',
+		method: 'post',
+		data,
+	})
+}
+
+// 更新状态
+export const updateStatus = data => {
+	return request({
+		url: '/drone-gd/workOrder/gdClueEvent/updateStatus',
+		method: 'post',
+		data,
+	})
+}
+
+
+
+// 获取处置记录列表
+export const getDisposeRecords = params => {
+	return request({
+		url: '/drone-gd/workOrder/gdClueEvent/disposeRecords',
+		method: 'get',
+		params,
+	})
+}
+
+// 上传文件
+export const uploadFileAPI = filePath => {
+	let baseURL = getEnvObj().VITE_API_BASE_URL_GD
+	// #ifdef H5
+	if (import.meta.env.VITE_APP_PROXY === 'true') {
+		baseURL = import.meta.env.VITE_API_PREFIX_GD
+	}
+	// #endif
+	const userInfo = useUserStore()?.$state?.userInfo || {}
+	const accessToken = userInfo.gd_access_token
+	const areaCode = userInfo.detail?.areaCode
+	const header = {
+		'Blade-Requested-With': 'BladeHttpRequest',
+		Authorization: `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`,
+	}
+	if (accessToken) header['Blade-Auth'] = `bearer ${accessToken}`
+	if (areaCode) header.areaCode = areaCode
+
+	return new Promise((resolve, reject) => {
+		uni.uploadFile({
+			url: `${baseURL.replace(/\/$/, '')}/blade-resource/oss/endpoint/put-file`,
+			filePath,
+			name: 'file',
+			header,
+			success: response => {
+				try {
+					const responseData = typeof response.data === 'string' ? JSON.parse(response.data) : response.data
+					const status = Number(responseData?.error_code ?? responseData?.code ?? response.statusCode)
+					if (![0, 200].includes(status)) {
+						reject(responseData)
+						return
+					}
+					resolve(responseData)
+				} catch (error) {
+					reject(error)
+				}
+			},
+			fail: reject,
+		})
+	})
 }
diff --git a/uniapps/work-app/src/pages/work/index.vue b/uniapps/work-app/src/pages/work/index.vue
index 31499da..205c21e 100644
--- a/uniapps/work-app/src/pages/work/index.vue
+++ b/uniapps/work-app/src/pages/work/index.vue
@@ -1,18 +1,23 @@
 <template>
-  <div class="eventTickets" :style="{ paddingTop: topMargin + 'px' }">
-
-    <div class="searchTop">
-      <up-search placeholder="请输入关键字搜索"  :animation="true"  v-model="listParams.keyword" :show-action="false" @search="handleSearch" @clear="handleClear"></up-search>
-    </div>
-    <div class="listBox">
-      <div class="tabs-container">
-        <up-tabs :list="tabList" @click="handleClick"></up-tabs>
-      </div>
-<!-- @scrolltolower="loadMore" -->
-      <scroll-view class="eventBox" scroll-y :lower-threshold="80" >
-        <div class="eventList">
-          <div class="eventItem"  v-for="(item,index) in dataList" :key="index">
-            <image
+	<div class="eventTickets" :style="{ paddingTop: topMargin + 'px' }">
+		<div class="searchTop">
+			<up-search
+				placeholder="请输入关键字搜索"
+				:animation="true"
+				v-model="listParams.keyword"
+				:show-action="false"
+				@search="handleSearch"
+				@clear="handleClear"
+			></up-search>
+		</div>
+		<div class="listBox">
+			<div class="tabs-container">
+				<up-tabs :scrollable="true" :list="tabList" @click="handleClick"></up-tabs>
+			</div>
+			<scroll-view class="eventBox" scroll-y :lower-threshold="80" @scrolltolower="loadMore">
+				<div class="eventList">
+					<div class="eventItem" v-for="(item, index) in dataList" :key="index">
+						<image
 							v-if="[1, 2].includes(item.attachmentType)"
 							:src="item?.aiImg || item?.eventImageUrl"
 							mode="aspectFill"
@@ -21,88 +26,112 @@
 						<div v-if="item.attachmentType === 3" class="videoBox" @click="detailHandle(item)">
 							<div class="playIcon"></div>
 						</div>
-            <div class="informationDisplay">
+						<div class="informationDisplay">
 							<div class="itemTitle">{{ item.eventName }}</div>
-              <div class="itemContent">{{ formatDate(item.createTime) }}</div>
-            </div>
-          </div>
-        </div>
+							<div class="itemContent">{{ formatDate(item.createTime) }}</div>
+						</div>
+					</div>
+				</div>
 
-        <!-- 暂无数据提示 -->
-        <div class="noData" v-if="!loading && dataList.length === 0">
-          <text>暂无数据</text>
-        </div>
+				<!-- 暂无数据提示 -->
+				<div class="noData" v-if="!loading && dataList.length === 0">
+					<text>暂无数据</text>
+				</div>
 
-        <!-- 加载提示 -->
-        <div class="loadingMore">
-          <text v-if="loading">加载中...</text>
-
-        </div>
-      </scroll-view>
-    </div>
+				<!-- 加载提示 -->
+				<div class="loadingMore">
+					<text v-if="loading">加载中...</text>
+					<text v-else-if="!hasMore">没有更多了</text>
+				</div>
+			</scroll-view>
+		</div>
 		<canvas
 			canvas-id="ai-image-canvas"
 			id="ai-image-canvas"
 			class="ai-image-canvas"
 			:style="{ width: canvasSize.width + 'px', height: canvasSize.height + 'px' }"
 		></canvas>
-
-  </div>
-
+	</div>
 </template>
 
 <script setup>
-
 import { getCurrentInstance, nextTick } from 'vue'
 import { useUserStore } from '@/store/index.js'
-import {getGdList,getstatusCount} from '@/api/work/index.js'
-import dayjs from 'dayjs';
-import { getStatusBarHeight } from '@/utils/common';
+import { getGdList, getstatusCount } from '@/api/work/index.js'
+import dayjs from 'dayjs'
+import { getStatusBarHeight } from '@/utils/common'
 
 const canvasOwner = getCurrentInstance()?.proxy
 const userStore = useUserStore()
 const userInfo = userStore.userInfo
 const dataList = ref([])
-const currentTab=ref('all')
+const currentTab = ref('all')
 const loading = ref(false)
 const hasMore = ref(true)
 const tabList = ref([
-  {
-    name: '全部工单',
-    key: 'all',
-    badge: {
-      value: 0,
-      showZero: true
-    },
-
-  },
-  {
-    name: '我的工单',
-    key: 'myTickets',
-    badge: {
-      value: 0,
-      showZero: true
-    }
-  }
-
-
+	{
+		name: '全部工单',
+		key: 'all',
+		badge: {
+			value: 0,
+			showZero: true,
+		},
+	},
+	{
+		name: '我的工单',
+		key: 'myTickets',
+		badge: {
+			value: 0,
+			showZero: true,
+		},
+	},
+	{
+		name: '处置中',
+		key: 'disposing',
+		badge: {
+			value: 0,
+			showZero: true,
+		},
+	},
+	{
+		name: '已处置',
+		key: 'handled',
+		badge: {
+			value: 0,
+			showZero: true,
+		},
+	},
+	{
+		name: '已完成',
+		key: 'completed',
+		badge: {
+			value: 0,
+			showZero: true,
+		},
+	},
 ])
-const formatDate = (dateString) => {
-  return dayjs(dateString).format('MM/DD HH:mm');
-};
+// tab key 与事件状态码映射
+const tabStatusMap = {
+	disposing: 1,
+	handled: 3,
+	completed: 4,
+}
+const formatDate = dateString => {
+	return dayjs(dateString).format('MM/DD HH:mm')
+}
 const listParams = ref({
-
-  current: 1,
-  size: 12,
-  source: 1,
-  department:'',
-  keyword:''
-
+	current: 1,
+	size: 12,
+	source: 1,
+	department: '',
+	keyword: '',
+	eventStatus: '',
 })
-const mockGeojson = "[{\"score\":0.89990234375,\"bbox\":{\"x_cen\":195.5,\"y_cen\":326.5,\"width\":117.0,\"height\":265.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"},{\"score\":0.89306640625,\"bbox\":{\"x_cen\":1194.5,\"y_cen\":559.5,\"width\":115.0,\"height\":261.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"},{\"score\":0.88720703125,\"bbox\":{\"x_cen\":179.0,\"y_cen\":955.5,\"width\":124.0,\"height\":249.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"},{\"score\":0.88330078125,\"bbox\":{\"x_cen\":1198.5,\"y_cen\":260.5,\"width\":115.0,\"height\":285.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"},{\"score\":0.84716796875,\"bbox\":{\"x_cen\":204.5,\"y_cen\":71.5,\"width\":115.0,\"height\":143.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"},{\"score\":0.83203125,\"bbox\":{\"x_cen\":186.0,\"y_cen\":657.5,\"width\":114.0,\"height\":269.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"},{\"score\":0.78662109375,\"bbox\":{\"x_cen\":1205.5,\"y_cen\":49.5,\"width\":117.0,\"height\":99.0},\"class_name\":\"car\",\"algorithmId\":\"e71116098eeb1d60cfebd04d30653b151\"}]"
+const mockGeojson =
+	'[{"score":0.89990234375,"bbox":{"x_cen":195.5,"y_cen":326.5,"width":117.0,"height":265.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"},{"score":0.89306640625,"bbox":{"x_cen":1194.5,"y_cen":559.5,"width":115.0,"height":261.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"},{"score":0.88720703125,"bbox":{"x_cen":179.0,"y_cen":955.5,"width":124.0,"height":249.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"},{"score":0.88330078125,"bbox":{"x_cen":1198.5,"y_cen":260.5,"width":115.0,"height":285.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"},{"score":0.84716796875,"bbox":{"x_cen":204.5,"y_cen":71.5,"width":115.0,"height":143.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"},{"score":0.83203125,"bbox":{"x_cen":186.0,"y_cen":657.5,"width":114.0,"height":269.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"},{"score":0.78662109375,"bbox":{"x_cen":1205.5,"y_cen":49.5,"width":117.0,"height":99.0},"class_name":"car","algorithmId":"e71116098eeb1d60cfebd04d30653b151"}]'
 const canvasSize = ref({
 	width: 1,
-	height: 1
+	height: 1,
 })
 
 const parseAiFrame = aiFrameSource => {
@@ -125,26 +154,29 @@
 			fail: error => {
 				console.log(error)
 				resolve(null)
-			}
+			},
 		})
 	})
 
 const canvasToTempFilePath = (width, height) =>
 	new Promise(resolve => {
-		uni.canvasToTempFilePath({
-			canvasId: 'ai-image-canvas',
-			width,
-			height,
-			destWidth: width,
-			destHeight: height,
-			fileType: 'jpg',
-			quality: 0.92,
-			success: res => resolve(res.tempFilePath),
-			fail: error => {
-				console.log(error)
-				resolve('')
-			}
-		}, canvasOwner)
+		uni.canvasToTempFilePath(
+			{
+				canvasId: 'ai-image-canvas',
+				width,
+				height,
+				destWidth: width,
+				destHeight: height,
+				fileType: 'jpg',
+				quality: 0.92,
+				success: res => resolve(res.tempFilePath),
+				fail: error => {
+					console.log(error)
+					resolve('')
+				},
+			},
+			canvasOwner
+		)
 	})
 
 const drawAiImage = async (url, aiFrameSource) => {
@@ -200,202 +232,224 @@
 }
 
 const getDataList = () => {
-  if (loading.value || !hasMore.value) return
+	if (loading.value || !hasMore.value) return
 
-  loading.value = true
-  const params = {
-    current: listParams.value.current,
-    size: listParams.value.size,
-    keyword:listParams.value.keyword,
-    onlyMine:currentTab.value=== 'myTickets' ? 1 : 0
-  }
-  getGdList(params).then(async res => {
-    const response = res.data.data
-		const list = []
-		for (const item of response) {
-			// const aiImg = await drawAiImage(item.eventImageUrl, mockGeojson)
-			if (item.attachmentType !== 2) {
-				list.push(item)
-			}else{
-				const aiImg = await drawAiImage(item.eventImageUrl, item.geojson)
-				list.push({ ...item, aiImg })
+	loading.value = true
+	const params = {
+		current: listParams.value.current,
+		size: listParams.value.size,
+		keyword: listParams.value.keyword,
+		onlyMine: currentTab.value === 'myTickets' ? 1 : 0,
+		eventStatus: listParams.value.eventStatus,
+	}
+	getGdList(params)
+		.then(async res => {
+			const resData = res.data.data
+			const response = resData.records
+			const list = []
+			for (const item of response) {
+				// const aiImg = await drawAiImage(item.eventImageUrl, mockGeojson)
+				if (item.attachmentType !== 2) {
+					list.push(item)
+				} else {
+					const aiImg = await drawAiImage(item.eventImageUrl, item.geojson)
+					list.push({ ...item, aiImg })
+				}
 			}
-		}
-		dataList.value = list
-    // 根据当前页码决定是替换还是追加数据
-    // if (listParams.value.current === 1) {
-    //   dataList.value = response
-    // } else {
-    //   dataList.value = [...dataList.value, ...response]
-    // }
-
-    // // 判断是否还有更多数据
-    // if (response.length < listParams.value.size || response.current >= response.pages) {
-    //   hasMore.value = false
-    // } else {
-    //   hasMore.value = true
-    // }
-  }).finally(() => {
-    loading.value = false
-  })
-}
-const getstatusCountData=()=>{
-  const params={
-    keyword:listParams.value.keyword,
-  }
-	getstatusCount(params).then(res=>{
-		const response = res.data.data
-		 const {  totalCount,myCount } = response
-		tabList.value.forEach(tab=>{
-
-			if(tab.key === 'all'){
-        tab.badge.value = (totalCount || 0).toString()
-        tab.badge.showZero = true
-
-			}else if(tab.key === 'myTickets'){
-				tab.badge.value = (myCount || 0).toString()
-        tab.badge.showZero = true
+			// 根据当前页码决定是替换还是追加数据
+			if (listParams.value.current === 1) {
+				dataList.value = list
+			} else {
+				dataList.value = [...dataList.value, ...list]
+			}
+			// 判断是否还有更多数据
+			if (list.length < listParams.value.size || resData.current >= resData.pages) {
+				hasMore.value = false
+			} else {
+				hasMore.value = true
 			}
 		})
-
+		.finally(() => {
+			loading.value = false
+		})
+}
+const getstatusCountData = () => {
+	const params = {
+		keyword: listParams.value.keyword,
+	}
+	getstatusCount(params).then(res => {
+		const response = res.data.data
+		const { totalCount, myCount, disposingCount, disposedCount, completedCount } = response
+		tabList.value.forEach(tab => {
+			if (tab.key === 'all') {
+				tab.badge.value = (totalCount || 0).toString()
+				tab.badge.showZero = true
+			} else if (tab.key === 'myTickets') {
+				tab.badge.value = (myCount || 0).toString()
+				tab.badge.showZero = true
+			} else if (tab.key === 'disposing') {
+				tab.badge.value = (disposingCount || 0).toString()
+				tab.badge.showZero = true
+			} else if (tab.key === 'handled') {
+				tab.badge.value = (disposedCount || 0).toString()
+				tab.badge.showZero = true
+			} else if (tab.key === 'completed') {
+				tab.badge.value = (completedCount || 0).toString()
+				tab.badge.showZero = true
+			}
+		})
 	})
 }
 
-const handleClick = (item) => {
-  currentTab.value = item.key
+const handleClick = item => {
+	currentTab.value = item.key
+	listParams.value.eventStatus = tabStatusMap[item.key] ?? ''
 
-  listParams.value.current = 1
-  hasMore.value = true
-  dataList.value = []
-  getDataList()
+	listParams.value.current = 1
+	hasMore.value = true
+	dataList.value = []
+	getDataList()
 }
 const loadMore = () => {
-  if (loading.value || !hasMore.value) return
-  listParams.value.current++
-  getDataList()
+	if (loading.value || !hasMore.value) return
+	listParams.value.current++
+	getDataList()
 }
 
-const detailHandle = (val) => {
-  uni.navigateTo({
-    url: `/subPackages/workDetail/index?id=${val.id}` + (val.aiImg ? `&aiImg=${val.aiImg}` : ''),
-  })
+const detailHandle = val => {
+	uni.navigateTo({
+		url: `/subPackages/workDetail/index?id=${val.id}` + (val.aiImg ? `&aiImg=${val.aiImg}` : ''),
+	})
 }
 
 // 搜索功能
 const handleSearch = () => {
-  listParams.value.current = 1
-  hasMore.value = true
-  dataList.value = []
-  getDataList()
-  getstatusCountData()
+	listParams.value.current = 1
+	hasMore.value = true
+	dataList.value = []
+	getDataList()
+	getstatusCountData()
 }
 // 清除搜索
 const handleClear = () => {
-  listParams.value.keyword = ''
-  listParams.value.current = 1
-  hasMore.value = true
-  dataList.value = []
-  getDataList()
-  getstatusCountData()
+	listParams.value.keyword = ''
+	listParams.value.current = 1
+	hasMore.value = true
+	dataList.value = []
+	getDataList()
+	getstatusCountData()
 }
 const topMargin = getStatusBarHeight()
 onShow(() => {
-  listParams.value.current = 1
-  hasMore.value = true
-  dataList.value = []
-  getDataList()
-  getstatusCountData()
+	listParams.value.current = 1
+	hasMore.value = true
+	dataList.value = []
+	getDataList()
+	getstatusCountData()
 })
 </script>
 
 <style scoped lang="scss">
 .eventTickets {
-  padding: 0 20rpx;
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-  box-sizing: border-box;
-  width: 100%;
-  overflow-x: hidden;
-  .searchTop {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    padding-right: 24rpx;
-    width: 100%;
-    height: 108rpx;
-    :deep(){
-      .u-search__content{
-        background: #fff !important;
-      }
-      .u-search__content__input{
-        background: #fff !important;
-      }
-    }
-  }
-  :deep(){
+	padding: 0 20rpx;
+	display: flex;
+	flex-direction: column;
+	height: 100%;
+	box-sizing: border-box;
+	width: 100%;
+	overflow-x: hidden;
+	.searchTop {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding-right: 24rpx;
+		width: 100%;
+		height: 108rpx;
+		:deep() {
+			.u-search__content {
+				background: #fff !important;
+			}
+			.u-search__content__input {
+				background: #fff !important;
+			}
+		}
+	}
+	:deep() {
+		.u-tabs__wrapper__nav__line {
+			// width: 80rpx !important;
+			background: #1d6fe9 !important;
+		}
+		.u-badge {
+			background-color: #1d6fe9 !important;
+			margin-top: -14px !important;
+			margin-left: -5px !important;
+		}
+	}
+	tabs-container {
+		display: flex;
+		align-items: center;
+		height: 98rpx;
+		width: 100%;
+		overflow-x: auto; // 横向滚动
+		overflow-y: hidden;
+		white-space: nowrap; // 防止换行
+		-webkit-overflow-scrolling: touch; // 移动端平滑滚动
 
-    .u-tabs__wrapper__nav__line{
-      // width: 80rpx !important;
-      background: #1D6FE9 !important;
-    }
-    .u-badge {
-      background-color: #1d6fe9 !important;
-      margin-top: -14px !important;
-      margin-left: -5px !important;
-    }
-  }
+		// 隐藏滚动条(可选)
+		&::-webkit-scrollbar {
+			height: 0;
+			display: none;
+		}
+	}
 
+	// 子元素不压缩
+	.tabs-container > * {
+		flex-shrink: 0;
+	}
+	.listBox {
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		flex: 1;
+		width: 100%;
+		box-sizing: border-box;
+	}
+	.eventBox {
+		padding: 20rpx 0;
+		overflow-y: auto;
+		overflow-x: hidden;
+		height: 0;
+		flex-grow: 1;
+		align-content: flex-start;
+		width: 100%;
+		box-sizing: border-box;
+	}
 
-  .tabs-container{
-    display: flex;
-    justify-content: center;
-    height: 98rpx;
-  }
-  .listBox {
-    position: relative;
-    display: flex;
-    flex-direction: column;
-    flex: 1;
-    width: 100%;
-    box-sizing: border-box;
-  }
-  .eventBox {
-    padding: 20rpx 0;
-    overflow-y: auto;
-    overflow-x: hidden;
-    height: 0;
-    flex-grow: 1;
-    align-content: flex-start;
-    width: 100%;
-    box-sizing: border-box;
-  }
+	.eventList {
+		display: flex;
+		flex-wrap: wrap;
+		gap: 20rpx;
+		width: 100%;
+		box-sizing: border-box;
+		justify-content: space-between;
 
-  .eventList {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 20rpx;
-    width: 100%;
-    box-sizing: border-box;
-    justify-content: space-between;
+		.eventItem {
+			width: calc(50% - 10rpx);
+			background-color: #fff;
+			border-radius: 12rpx;
+			overflow: hidden;
+			position: relative;
+			box-sizing: border-box;
+			max-width: 100%;
 
-    .eventItem {
-      width: calc(50% - 10rpx);
-      background-color: #fff;
-      border-radius: 12rpx;
-      overflow: hidden;
-      position: relative;
-      box-sizing: border-box;
-      max-width: 100%;
-
-      image,
+			image,
 			.videoBox {
-        width: 100%;
-        height: 208rpx;
-        border-radius: 12rpx;
-        overflow: hidden;
+				width: 100%;
+				height: 208rpx;
+				border-radius: 12rpx;
+				overflow: hidden;
 				display: block;
-      }
+			}
 			.videoBox {
 				background: linear-gradient(135deg, #eef4ff 0%, #dfe8f8 100%);
 				display: flex;
@@ -422,61 +476,60 @@
 					border-left: 22rpx solid #fff;
 				}
 			}
-      .informationDisplay{
-        width: 100%;
-        position: absolute;
-        bottom: 3px;
-        background: rgba(11,11,11,0.35);
-        border-radius: 0rpx 0rpx 12rpx 12rpx;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        padding: 10rpx 14rpx;
+			.informationDisplay {
+				width: 100%;
+				position: absolute;
+				bottom: 3px;
+				background: rgba(11, 11, 11, 0.35);
+				border-radius: 0rpx 0rpx 12rpx 12rpx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 10rpx 14rpx;
 				box-sizing: border-box;
-        .itemTitle {
-          flex: 1;
+				.itemTitle {
+					flex: 1;
 					min-width: 0;
-          font-family: Source Han Sans CN, Source Han Sans CN;
-          font-weight: 500;
-          font-size: 24rpx;
-          color: #FFFFFF;
-          white-space: nowrap;
-          overflow: hidden;
-          text-overflow: ellipsis;
-        }
-
-        .itemContent {
-          font-family: Source Han Sans CN, Source Han Sans CN;
-          font-weight: 400;
-          font-size: 24rpx;
-          color: #FFFFFF;
-          margin-left: 12rpx;
+					font-family: Source Han Sans CN, Source Han Sans CN;
+					font-weight: 500;
+					font-size: 24rpx;
+					color: #ffffff;
 					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
 
-        }
-      }
-    }
-  }
+				.itemContent {
+					font-family: Source Han Sans CN, Source Han Sans CN;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #ffffff;
+					margin-left: 12rpx;
+					white-space: nowrap;
+				}
+			}
+		}
+	}
 
-  .loadingMore {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 80rpx;
-    font-size: 28rpx;
-    color: #999;
-    width: 100%;
-  }
+	.loadingMore {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		height: 80rpx;
+		font-size: 28rpx;
+		color: #999;
+		width: 100%;
+	}
 
-  .noData {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 300rpx;
-    font-size: 28rpx;
-    color: #999;
-    width: 100%;
-  }
+	.noData {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		height: 300rpx;
+		font-size: 28rpx;
+		color: #999;
+		width: 100%;
+	}
 
 	.ai-image-canvas {
 		position: fixed;
diff --git a/uniapps/work-app/src/subPackages/workDetail/HandleWork/index.vue b/uniapps/work-app/src/subPackages/workDetail/HandleWork/index.vue
new file mode 100644
index 0000000..09db68c
--- /dev/null
+++ b/uniapps/work-app/src/subPackages/workDetail/HandleWork/index.vue
@@ -0,0 +1,295 @@
+<template>
+	<view class="handle-work-page">
+		<u-navbar title="处置记录" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick"></u-navbar>
+
+		<!-- 把上传处置放在滚动区域外面,固定在头部 -->
+		<view class="upload_handle" @click="uploadHadle">+上传处置</view>
+
+		<scroll-view class="record-scroll" scroll-y :lower-threshold="80" @scrolltolower="loadMore">
+			<view class="record-list">
+				<view class="record-card" v-for="(item, index) in recordList" :key="index">
+					<!-- 第一行:名称 + 状态 -->
+					<view class="card-row-top">
+						<text class="card-name">{{ item.disposeUserName }}</text>
+						<text class="card-status" :class="statusClass(item.disposeStatus)">
+							{{ getStatusLabel(item.disposeStatus) }}
+						</text>
+					</view>
+					<!-- 第二行:标题 -->
+					<view class="card-title">
+						<text>{{ item.disposeContent }}</text>
+					</view>
+					<!-- 第三行:图片列表 -->
+					<view class="card-images" v-if="item.attachUrl && item.attachUrl.length">
+						<image
+							v-for="(img, imgIdx) in item.attachUrl"
+							:key="imgIdx"
+							:src="img"
+							mode="aspectFill"
+							class="card-image"
+							@click="previewImage(item.attachUrl, imgIdx)"
+						/>
+					</view>
+					<!-- 第四行:日期 -->
+					<view class="card-row-bottom">
+						<text class="card-date">{{ formatDate(item.operateTime) }}</text>
+					</view>
+				</view>
+			</view>
+
+			<!-- 暂无数据 -->
+			<view class="noData" v-if="!loading && recordList.length === 0">
+				<text>暂无处置记录</text>
+			</view>
+			<!-- 加载提示 -->
+			<view class="loadingMore">
+				<text v-if="loading">加载中...</text>
+				<text v-else-if="!hasMore && recordList.length > 0">没有更多了</text>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import dayjs from 'dayjs'
+import { getDisposeRecords } from '@/api/work/index.js'
+
+const eventId = ref('')
+const eventStatus = ref('')
+const recordList = ref([])
+const loading = ref(false)
+const hasMore = ref(true)
+const listParams = ref({
+	current: 1,
+	size: 3,
+})
+
+// 获取状态文本
+const getStatusLabel = status => {
+	const map = {
+		0: '待确认',
+		1: '处置中',
+		2: '已退回',
+		3: '已处置',
+		4: '已完成',
+	}
+	return map[status] || '未知'
+}
+
+// 状态样式类名
+const statusClass = status => {
+	if (status === 1) return 'status-processing'
+	if (status === 3) return 'status-handled'
+	if (status === 4) return 'status-completed'
+	return ''
+}
+
+// 格式化日期
+const formatDate = dateString => {
+	if (!dateString) return ''
+	return dayjs(dateString).format('YYYY-MM-DD HH:mm')
+}
+
+// 读取工单标识
+onLoad(options => {
+	eventId.value = options?.id ?? ''
+	eventStatus.value = options?.eventStatus ?? ''
+	getRecordList()
+})
+
+onShow(() => {
+	getRecordList()
+})
+
+// 获取处置记录列表
+const getRecordList = async () => {
+	if (loading.value || !hasMore.value) return
+	loading.value = true
+	const res = await getDisposeRecords({ eventId: eventId.value })
+	recordList.value = res.data.data
+	loading.value = false
+}
+
+function uploadHadle() {
+	uni.navigateTo({
+		url: `/subPackages/workDetail/HandleWorking/index?id=${eventId.value}&eventStatus=${eventStatus.value}`,
+	})
+}
+
+// 加载更多
+const loadMore = () => {
+	if (loading.value || !hasMore.value) return
+	listParams.value.current++
+	getRecordList()
+}
+
+// 图片预览
+const previewImage = (attachments, index) => {
+	uni.previewImage({
+		urls: attachments,
+		current: index,
+	})
+}
+
+// 返回按钮点击事件
+const onBackClick = () => {
+	uni.navigateBack()
+}
+</script>
+
+<style scoped lang="scss">
+.handle-work-page {
+	padding-top: 88rpx;
+	:deep() {
+		.u-navbar__content {
+			background: url('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png')
+				no-repeat !important;
+			background-size: 100% !important;
+			height: 88rpx !important;
+		}
+	}
+
+	display: flex;
+	flex-direction: column;
+	height: 100vh; // 新增:占满全屏
+	background: #f6f6f6;
+	box-sizing: border-box;
+
+	:deep(.u-navbar) {
+		position: fixed !important;
+		top: 0;
+		left: 0;
+		right: 0;
+		z-index: 100;
+	}
+
+	:deep(.u-navbar__content) {
+		height: 88rpx !important;
+	}
+}
+
+// 上传处置按钮 - 移到滚动区域外面
+.upload_handle {
+	height: 80rpx; // 改大一点,方便点击
+	display: flex;
+	align-items: center;
+	justify-content: flex-end;
+	padding-right: 24rpx;
+	margin: 60rpx 0 12rpx 0; // 上下间距
+	color: #1d6fe9;
+	font-size: 28rpx;
+	flex-shrink: 0; // 防止被压缩
+	background: #f6f6f6; // 背景色,避免和滚动区域混在一起
+}
+
+.record-scroll {
+	flex: 1; // 占满剩余高度
+	// padding-top: 24rpx;
+	padding: 0 24rpx 24rpx 24rpx; // 左右下内边距
+	box-sizing: border-box;
+}
+
+.record-list {
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
+	padding-bottom: 10rpx;
+}
+
+.record-card {
+	background: #ffffff;
+	border-radius: 12rpx;
+	padding: 24rpx;
+	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
+}
+
+.card-row-top {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 16rpx;
+}
+
+.card-name {
+	font-family: Source Han Sans CN, Source Han Sans CN;
+	font-weight: 500;
+	font-size: 28rpx;
+	color: #222324;
+}
+
+.card-status {
+	font-family: Source Han Sans CN, Source Han Sans CN;
+	font-weight: 400;
+	font-size: 24rpx;
+	padding: 4rpx 16rpx;
+	border-radius: 6rpx;
+	color: #ffffff;
+	background: #999;
+
+	&.status-processing {
+		background: #1d6fe9;
+	}
+	&.status-handled {
+		background: #e6a23c;
+	}
+	&.status-completed {
+		background: #00b578;
+	}
+}
+
+.card-title {
+	font-family: Source Han Sans CN, Source Han Sans CN;
+	font-weight: 400;
+	font-size: 30rpx;
+	color: #222324;
+	line-height: 1.6;
+	margin-bottom: 16rpx;
+	word-break: break-all;
+}
+
+.card-images {
+	display: flex;
+	gap: 12rpx;
+	margin-bottom: 16rpx;
+	overflow: hidden;
+}
+
+.card-image {
+	width: 160rpx;
+	height: 160rpx;
+	border-radius: 8rpx;
+	flex-shrink: 0;
+}
+
+.card-row-bottom {
+	display: flex;
+	justify-content: flex-end;
+}
+
+.card-date {
+	font-family: Source Han Sans CN, Source Han Sans CN;
+	font-weight: 400;
+	font-size: 24rpx;
+	color: #999;
+}
+
+.noData {
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	height: 400rpx;
+	font-size: 28rpx;
+	color: #999;
+}
+
+.loadingMore {
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	height: 80rpx;
+	font-size: 28rpx;
+	color: #999;
+}
+</style>
diff --git a/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue
new file mode 100644
index 0000000..e668b0d
--- /dev/null
+++ b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue
@@ -0,0 +1,470 @@
+<template>
+	<view class="handle-page">
+		<u-navbar title="待办处置" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick"></u-navbar>
+
+		<scroll-view class="form-scroll" scroll-y>
+			<view class="form-section description-section">
+				<view class="section-header">
+					<text class="section-title">处置描述</text>
+				</view>
+				<view class="description-wrapper">
+					<textarea
+						v-model="formData.disposeContent"
+						class="description-input"
+						maxlength="140"
+						placeholder="请输入"
+						placeholder-class="description-placeholder"
+						:show-confirm-bar="false"
+					/>
+					<text class="word-count">{{ descriptionLength }}/140</text>
+				</view>
+			</view>
+
+			<!--			<view class="form-section status-section">-->
+			<!--				<text class="section-title">处置中</text>-->
+			<!--				<switch class="status-switch" :checked="formData.isHandling" color="#00b578" @change="handleStatusChange" />-->
+			<!--			</view>-->
+
+			<view class="form-section upload-section">
+				<view class="section-header upload-header">
+					<text class="section-title">附件上传</text>
+				</view>
+				<!--				<button class="select-file-btn" @click="handleChooseFile">选择文件</button>-->
+				<u-button color="#1D6FE9" class="select-file-btn" :disabled="uploading" @click="handleChooseFile">
+					{{ uploading ? '上传中...' : '选择文件' }}
+				</u-button>
+
+				<view v-if="attachmentList.length" class="attachment-list">
+					<view v-for="(file, index) in attachmentList" :key="`${file.path}-${index}`" class="attachment-item">
+						<view class="file-info">
+							<text class="file-name">{{ file.name }}</text>
+							<text v-if="file.size" class="file-size">{{ formatFileSize(file.size) }}</text>
+						</view>
+						<text class="remove-file-btn" @click.stop="handleRemoveFile(index)">×</text>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+
+		<view class="action-footer">
+			<u-button color="#AEAEAE" class="custom-style" @click="handleCancel">取消</u-button>
+			<u-button color="#1D6FE9" class="custom-style" :disabled="submitting || uploading" @click="handleSubmit">
+				{{ submitting ? '提交中...' : '确定' }}
+			</u-button>
+		</view>
+	</view>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import { backGdApi, addDisposeRecord, uploadFileAPI } from '@/api/work/index.js'
+
+const MAX_FILE_COUNT = 9
+const eventId = ref('')
+const eventStatus = ref(null)
+const submitting = ref(false)
+const uploading = ref(false)
+const attachmentList = ref([])
+const formData = ref({
+	disposeContent: '',
+	isHandling: true,
+})
+const navbarTitleStyle = {
+	color: '#ffffff',
+	fontSize: '34rpx',
+	fontWeight: '500',
+}
+
+// 计算处置描述字数
+const descriptionLength = computed(() => formData.value.disposeContent.length)
+
+// 读取当前工单标识
+onLoad(options => {
+	eventId.value = options?.id ?? ''
+})
+
+// 返回上一页
+function handleBack() {
+	uni.navigateBack()
+}
+
+// 切换处置状态
+// function handleStatusChange(event) {
+// 	formData.value.isHandling = event.detail.value
+// }
+
+// 提取文件名称
+function getFileName(filePath = '') {
+	const normalizedPath = filePath.replace(/\\/g, '/')
+	return decodeURIComponent(normalizedPath.split('/').pop() || '未命名文件')
+}
+
+// 上传单个已选择文件
+async function uploadSelectedFile(file) {
+	const response = await uploadFileAPI(file.path)
+	const link = response?.data?.link || response?.data?.url || response?.link
+	if (!link) throw new Error('上传接口未返回文件地址')
+	return { ...file, link }
+}
+
+// 处理已选择文件
+async function handleChooseSuccess(result) {
+	const selectedFiles = result.tempFiles?.length
+		? result.tempFiles
+		: (result.tempFilePaths ?? []).map(path => ({ path }))
+	const availableCount = MAX_FILE_COUNT - attachmentList.value.length
+	const normalizedFiles = selectedFiles
+		.slice(0, availableCount)
+		.map(file => {
+			const path = file.path || file.tempFilePath || ''
+			return {
+				name: file.name || getFileName(path),
+				path,
+				size: Number(file.size) || 0,
+			}
+		})
+		.filter(file => file.path)
+	if (!normalizedFiles.length) return
+
+	uploading.value = true
+	uni.showLoading({ title: '上传中...', mask: true })
+	let failedCount = 0
+	try {
+		const uploadResults = await Promise.all(
+			normalizedFiles.map(async file => {
+				try {
+					return { success: true, file: await uploadSelectedFile(file) }
+				} catch {
+					return { success: false, file }
+				}
+			})
+		)
+		const uploadedFiles = uploadResults.filter(item => item.success).map(item => item.file)
+		failedCount = uploadResults.length - uploadedFiles.length
+		attachmentList.value.push(...uploadedFiles)
+	} finally {
+		uni.hideLoading()
+		uploading.value = false
+	}
+	uni.showToast({
+		title: failedCount ? `${failedCount}个文件上传失败` : '上传成功',
+		icon: failedCount ? 'none' : 'success',
+	})
+}
+
+// 处理选择文件失败
+function handleChooseFail(error) {
+	if (error?.errMsg?.includes('cancel')) return
+	uni.showToast({ title: '选择文件失败', icon: 'none' })
+}
+
+// 选择附件
+function handleChooseFile() {
+	if (uploading.value) return
+	const availableCount = MAX_FILE_COUNT - attachmentList.value.length
+	if (availableCount <= 0) {
+		uni.showToast({ title: `最多选择${MAX_FILE_COUNT}个附件`, icon: 'none' })
+		return
+	}
+	const options = {
+		count: availableCount,
+		type: 'all',
+		success: handleChooseSuccess,
+		fail: handleChooseFail,
+	}
+
+	// #ifdef H5
+	uni.chooseFile(options)
+	// #endif
+
+	// #ifdef MP-WEIXIN
+	uni.chooseMessageFile(options)
+	// #endif
+
+	// #ifdef APP-PLUS
+	uni.chooseImage({ ...options, sourceType: ['album', 'camera'] })
+	// #endif
+}
+
+// 移除附件
+function handleRemoveFile(index) {
+	attachmentList.value.splice(index, 1)
+}
+
+// 格式化文件大小
+function formatFileSize(size) {
+	if (size < 1024) return `${size} B`
+	if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`
+	return `${(size / 1024 / 1024).toFixed(1)} MB`
+}
+
+// 取消处置
+function handleCancel() {
+	uni.navigateBack()
+}
+
+// 提交处置信息
+async function handleSubmit() {
+	if (uploading.value) {
+		uni.showToast({ title: '请等待附件上传完成', icon: 'none' })
+		return
+	}
+	const disposeContent = formData.value.disposeContent.trim()
+	if (!disposeContent) {
+		uni.showToast({ title: '请输入处置描述', icon: 'none' })
+		return
+	}
+	if (!eventId.value) {
+		uni.showToast({ title: '工单信息缺失', icon: 'none' })
+		return
+	}
+
+	submitting.value = true
+	try {
+		await addDisposeRecord({
+			eventId: eventId.value,
+			recordType: 1,
+			disposeContent: formData.value.disposeContent,
+			targetEventStatus: eventStatus.value == 1 ? 3 : eventStatus.value,
+			updateEventStatus: true,
+			attachUrl: attachmentList.value.map(file => file.link),
+			// operateTime: '2026-07-30 14:00:00',
+			// eventStatus: formData.value.isHandling ? '1' : '3',
+			// handleDesc,
+			// attachmentList: attachmentList.value.map(file => ({
+			// 	attachName: file.name,
+			// 	filePath: file.path,
+			// })),
+		})
+		uni.showToast({ title: '提交成功', icon: 'success' })
+		setTimeout(() => {
+			submitting.value = false
+			uni.navigateBack()
+			// uni.navigateTo({
+			// 	url: `/subPackages/workDetail/HandleWork/index?id=${eventId.value}`,
+			// })
+		}, 1200)
+	} catch {
+		submitting.value = false
+		uni.showToast({ title: '提交失败,请重试', icon: 'none' })
+	}
+}
+
+// 返回按钮点击事件
+const onBackClick = () => {
+	uni.navigateBack()
+}
+
+onLoad(options => {
+	console.log(options, '9090')
+	eventId.value = options?.id || ''
+	eventStatus.value = options?.eventStatus || ''
+})
+</script>
+
+<style scoped lang="scss">
+.handle-page {
+	padding-top: 88rpx;
+	:deep() {
+		.u-navbar__content {
+			background: url('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png')
+				no-repeat !important;
+			background-size: 100% !important;
+			height: 88rpx !important;
+		}
+	}
+
+	display: flex;
+	flex-direction: column;
+	box-sizing: border-box;
+	height: calc(100vh);
+	//padding-top: 88rpx;
+	//background: #111827;
+	//color: #f5f7fa;
+
+	//:deep(.u-navbar__content) {
+	//	height: 88rpx !important;
+	//	background: #151c29 !important;
+	//}
+}
+
+.form-scroll {
+	box-sizing: border-box;
+	height: 0;
+	flex: 1;
+	padding: 60rpx 24rpx 24rpx;
+}
+
+.form-section {
+	box-sizing: border-box;
+	margin-bottom: 20rpx;
+	background: #ffffff;
+	border: 1rpx solid rgba(255, 255, 255, 0.03);
+}
+
+.section-header {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	height: 82rpx;
+	padding: 0 22rpx;
+	border-bottom: 1rpx solid #eeeeee;
+}
+
+.section-title {
+	font-size: 30rpx;
+	font-weight: 400;
+	color: #222324;
+}
+
+.description-wrapper {
+	position: relative;
+}
+
+.word-count {
+	position: absolute;
+	right: 22rpx;
+	bottom: 16rpx;
+	font-size: 24rpx;
+	color: #999;
+}
+
+.description-input {
+	display: block;
+	box-sizing: border-box;
+	width: 100%;
+	height: 350rpx;
+	padding: 24rpx 22rpx;
+	font-size: 30rpx;
+	line-height: 1.6;
+	color: #222324;
+	background: transparent;
+}
+
+:deep(.description-placeholder) {
+	color: #999;
+}
+
+.status-section {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	height: 104rpx;
+	padding: 0 20rpx 0 22rpx;
+}
+
+.status-switch {
+	transform: scale(0.84);
+	transform-origin: right center;
+}
+
+.upload-section {
+	padding-bottom: 22rpx;
+}
+
+.upload-header {
+	margin-bottom: 0;
+}
+
+.select-file-btn {
+	width: 210rpx;
+	height: 70rpx;
+	margin: 0;
+	font-size: 28rpx;
+	line-height: 70rpx;
+	//color: #ffffff;
+	//background: #409eff;
+	//border-radius: 4rpx;
+}
+
+.select-file-btn::after,
+.action-btn::after {
+	border: 0;
+}
+
+.custom-style {
+	width: 276rpx;
+	height: 76rpx;
+	font-family: 'Source Han Sans CN';
+	font-weight: 400;
+	font-size: 28rpx;
+}
+
+.attachment-list {
+	padding: 10rpx 22rpx 0;
+}
+
+.attachment-item {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	min-height: 70rpx;
+	border-bottom: 1rpx solid #eeeeee;
+}
+
+.file-info {
+	display: flex;
+	align-items: center;
+	width: 0;
+	flex: 1;
+}
+
+.file-name {
+	overflow: hidden;
+	font-size: 26rpx;
+	color: #222324;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.file-size {
+	margin-left: 14rpx;
+	font-size: 22rpx;
+	color: #999;
+	white-space: nowrap;
+}
+
+.remove-file-btn {
+	width: 56rpx;
+	font-size: 42rpx;
+	line-height: 56rpx;
+	color: #999;
+	text-align: right;
+}
+
+.action-footer {
+	display: flex;
+	align-items: center;
+	gap: 28rpx;
+	box-sizing: border-box;
+	padding: 22rpx 28rpx calc(22rpx + env(safe-area-inset-bottom));
+	//background: #111827;
+}
+
+.action-btn {
+	height: 82rpx;
+	margin: 0;
+	flex: 1;
+	font-size: 30rpx;
+	line-height: 80rpx;
+	color: #ffffff;
+	border-radius: 6rpx;
+}
+
+.cancel-btn {
+	color: #00b578;
+	background: transparent;
+	border: 2rpx solid #00b578;
+}
+
+.confirm-btn {
+	background: #00b578;
+	border: 2rpx solid #00b578;
+}
+
+.confirm-btn[disabled] {
+	color: rgba(255, 255, 255, 0.72);
+	background: #087b58;
+}
+</style>
diff --git a/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue
new file mode 100644
index 0000000..61781f5
--- /dev/null
+++ b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue
@@ -0,0 +1,381 @@
+<script setup>
+import { onLoad } from '@dcloudio/uni-app'
+
+onLoad(options => {
+	console.log(options, '9090')
+	// eventId.value = options?.id || ''
+	// eventStatus.value = options?.eventStatus || ''
+})
+</script>
+<template>
+	<div class="workDetailContainer">
+		<!-- 自定义导航栏 -->
+		<u-navbar title="工单详情" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick">
+			<template #right>
+				<div v-if="isH5" class="tapShare-icon"><img src="/static/images/work/share.svg" @click="onShareClick" /></div>
+				<div v-else class="share-btn" @click="onShareClick"></div>
+			</template>
+		</u-navbar>
+		<div class="detailTop">打发打发打发打发</div>
+	</div>
+</template>
+
+<style lang="scss" scoped>
+	.workDetailContainer {
+		// 添加导航栏高度的padding-top,避免内容被遮挡
+		padding-top: 88rpx;
+		:deep() {
+			.u-navbar__content {
+				background: url('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png')
+				no-repeat !important;
+				background-size: 100% !important;
+				height: 88rpx !important;
+			}
+		} // 分享按钮样式
+		.share-btn {
+			// #ifdef APP-PLUS
+			width: 40rpx;
+			height: 40rpx;
+			background-image: url('/static/images/work/share.svg');
+			background-size: contain;
+			background-repeat: no-repeat;
+			background-position: center;
+			// #endif
+		}
+		.tapShare-icon {
+			width: 40rpx;
+			height: 40rpx;
+			img {
+				width: 40rpx;
+				height: 40rpx;
+			}
+		}
+		.detailTop {
+			// #ifdef APP-PLUS
+			padding-top: 60rpx;
+			// #endif
+			.image-container {
+				position: relative;
+				width: 100%;
+				height: 410rpx;
+
+				.detailImage {
+					width: 100%;
+					height: 100%;
+					display: block;
+					object-fit: cover;
+				}
+				// 轮播图容器
+				:deep(.u-swiper) {
+					// 指示器容器 - 修改为居中对齐
+					.u-swiper__indicator {
+						position: absolute;
+						left: 50%;
+						transform: translateX(-50%);
+						bottom: 20rpx;
+						display: flex;
+						justify-content: center;
+						align-items: center;
+						z-index: 10;
+					}
+					.u-swiper-indicator__wrapper__dot--active {
+						width: 5px !important;
+					}
+				}
+			}
+		}
+
+		.worderContainer {
+			padding: 0 24rpx;
+			padding-bottom: 4rpx;
+			background: #f6f6f6;
+			margin-top: 20rpx;
+			height: calc(100vh - 530rpx);
+			overflow: auto;
+		}
+		.workOrderContent {
+			margin-top: 30epx;
+			background-color: #fff;
+			border-radius: 12rpx;
+			padding: 20rpx;
+			margin-bottom: 34rpx;
+			.workOrderTitle {
+				font-family: Source Han Sans CN, Source Han Sans CN;
+				font-weight: bold;
+				font-size: 32rpx;
+				color: #222324;
+			}
+			.workOrderContainer {
+				.orderRow {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					min-height: 96rpx;
+					border-bottom: 1px solid #f5f5f5;
+					color: #7b7b7b;
+					.rowTitle {
+						font-family: Source Han Sans CN, Source Han Sans CN;
+						font-weight: 400;
+						font-size: 30rpx;
+						color: #222324;
+						white-space: nowrap;
+					}
+					.rowAddress {
+						font-family: Source Han Sans CN, Source Han Sans CN;
+						font-weight: 400;
+						font-size: 28rpx;
+						color: #1d6fe9;
+						text-decoration: underline;
+						text-align: right;
+
+						padding-top: 1px;
+						padding-left: 5px;
+						padding-right: 2px;
+					}
+					.status-picker {
+						.picker-value {
+							font-family: Source Han Sans CN, Source Han Sans CN;
+							font-weight: 400;
+							font-size: 28rpx;
+							color: #1d6fe9;
+							display: flex;
+							align-items: center;
+							gap: 8rpx;
+						}
+						.picker-arrow {
+							font-size: 20rpx;
+							color: #999;
+						}
+					}
+				}
+			}
+		}
+
+		.actionButton {
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			box-sizing: border-box;
+			width: 100%;
+			height: 61px;
+			padding: 0 24rpx;
+
+			border-radius: 6px 6px 6px 6px;
+
+			.btngroups {
+				display: flex;
+				align-items: center;
+				width: 100%;
+				min-width: 0;
+				:deep(.u-button) {
+					width: 0 !important;
+					min-width: 0;
+					margin: 0 !important;
+					flex: 1;
+					height: 76rpx !important;
+				}
+				&:not(.three-actions) {
+					:deep(.u-button + .u-button) {
+						margin-left: 20rpx !important;
+					}
+				}
+				&.three-actions {
+					justify-content: center;
+					:deep(.u-button) {
+						width: 210rpx !important;
+						flex: 0 0 210rpx;
+					}
+					:deep(.u-button:last-child) {
+						margin-left: 20rpx !important;
+					}
+				}
+			}
+		}
+	}
+
+	.complete-modal-overlay {
+		position: fixed;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		z-index: 10000;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		box-sizing: border-box;
+		padding: 40rpx;
+		background: rgba(0, 0, 0, 0.55);
+	}
+
+	.complete-modal {
+		box-sizing: border-box;
+		width: 620rpx;
+		max-width: 100%;
+		padding: 32rpx;
+		background: #ffffff;
+		border-radius: 12rpx;
+	}
+
+	.complete-modal-title {
+		margin-bottom: 28rpx;
+		font-size: 32rpx;
+		font-weight: 500;
+		color: #222324;
+		text-align: center;
+	}
+
+	.complete-input-wrapper {
+		position: relative;
+		box-sizing: border-box;
+		height: 220rpx;
+		padding-bottom: 38rpx;
+		background: #f6f7f9;
+		border: 1rpx solid #e5e7eb;
+		border-radius: 6rpx;
+	}
+
+	.complete-input {
+		box-sizing: border-box;
+		width: 100%;
+		height: 100%;
+		padding: 20rpx;
+		font-size: 28rpx;
+		line-height: 1.5;
+		color: #222324;
+	}
+
+	.complete-word-count {
+		position: absolute;
+		right: 16rpx;
+		bottom: 10rpx;
+		font-size: 22rpx;
+		color: #999999;
+	}
+
+	.complete-modal-actions {
+		display: flex;
+		gap: 24rpx;
+		margin-top: 30rpx;
+	}
+
+	.complete-action-btn {
+		height: 76rpx;
+		margin: 0;
+		flex: 1;
+		font-size: 28rpx;
+		line-height: 76rpx;
+		border-radius: 6rpx;
+	}
+
+	.complete-action-btn::after {
+		border: 0;
+	}
+
+	.complete-cancel-btn {
+		color: #666666;
+		background: #f1f2f4;
+	}
+
+	.complete-confirm-btn {
+		color: #ffffff;
+		background: #1d6fe9;
+	}
+
+	.complete-action-btn[disabled] {
+		opacity: 0.65;
+	}
+
+	/* 分享弹出层样式 */
+	.share-modal-overlay {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background-color: rgba(0, 0, 0, 0.6);
+		display: flex;
+		justify-content: flex-end;
+		align-items: flex-end;
+		z-index: 9999;
+	}
+
+	.share-modal-content {
+		background-color: #fff;
+		border-radius: 20rpx 20rpx 0 0;
+		padding: 30rpx;
+		width: 100%;
+		max-height: 80vh;
+		overflow-y: auto;
+	}
+
+	.share-modal-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 30rpx;
+	}
+
+	.share-modal-title {
+		font-size: 36rpx;
+		font-weight: bold;
+		color: #222324;
+		text-align: center;
+		flex: 1;
+	}
+
+	.share-modal-close {
+		font-size: 60rpx;
+		color: #999;
+		line-height: 40rpx;
+	}
+
+	.share-modal-body {
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-around;
+		padding-bottom: 30rpx;
+	}
+
+	.share-modal-footer {
+		display: flex;
+		justify-content: space-around;
+		padding-top: 30rpx;
+		border-top: 1px solid #f0f0f0;
+	}
+
+	.share-item {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		margin: 20rpx;
+		width: 120rpx;
+	}
+
+	.share-icon {
+		width: 90rpx;
+		height: 90rpx;
+		border-radius: 50%;
+		margin-bottom: 15rpx;
+		background-size: contain;
+		background-repeat: no-repeat;
+		background-position: center;
+	}
+
+	.share-icon.wechat {
+		background-image: url('@/static/images/work/wechat.svg');
+	}
+
+	.share-icon.moments {
+		background-image: url('@/static/images/work/moments.svg');
+	}
+
+	.share-icon.link {
+		background-image: url('@/static/images/work/link.svg');
+	}
+	.share-name {
+		font-size: 24rpx;
+		color: #666;
+		margin-top: 10rpx;
+	}
+</style>
diff --git a/uniapps/work-app/src/subPackages/workDetail/index.vue b/uniapps/work-app/src/subPackages/workDetail/index.vue
index b1b1c57..9488846 100644
--- a/uniapps/work-app/src/subPackages/workDetail/index.vue
+++ b/uniapps/work-app/src/subPackages/workDetail/index.vue
@@ -4,7 +4,7 @@
 		<!-- 自定义导航栏 -->
 		<u-navbar title="工单详情" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick">
 			<template #right>
-        <div v-if="isH5" class="tapShare-icon"><img src="/static/images/work/share.svg"  @click="onShareClick"/></div>
+				<div v-if="isH5" class="tapShare-icon"><img src="/static/images/work/share.svg" @click="onShareClick" /></div>
 				<div v-else class="share-btn" @click="onShareClick"></div>
 			</template>
 		</u-navbar>
@@ -24,184 +24,390 @@
 				></u-swiper>
 			</div>
 		</div>
-    <!-- 工单内容 -->
-    <div class="worderContainer">
-      <div class="workOrderContent">
-        <div class="workOrderTitle">工单内容</div>
-        <div class="workOrderContainer">
-          <div class="orderRow">
-            <div class="rowTitle">工单名称</div>
-            <div>{{ workDetailData.eventName }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">工单编号</div>
-            <div>{{ workDetailData.eventNum }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">工单处置人</div>
-            <div>{{ workDetailData.disposeUserName }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">处置部门</div>
-            <div>{{ workDetailData.disposeDeptName }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">拍摄时间</div>
-            <div>{{ workDetailData.shootTime }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">分发人员</div>
-            <div>{{ workDetailData.distributeUserName }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">分发部门</div>
-            <div>{{ workDetailData.distributeDeptName }}</div>
-          </div>
+		<!-- 工单内容 -->
+		<div class="worderContainer">
+			<div class="workOrderContent">
+				<div class="workOrderTitle">工单内容</div>
+				<div class="workOrderContainer">
+					<div class="orderRow">
+						<div class="rowTitle">工单名称</div>
+						<div>{{ workDetailData.eventName }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">工单编号</div>
+						<div>{{ workDetailData.eventNum }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">工单状态</div>
+						<template v-if="[1, 3].includes(workDetailData.eventStatus)">
+							<picker
+								mode="selector"
+								:range="statusOptions"
+								range-key="name"
+								:value="statusPickerIndex"
+								@change="onStatusChange"
+								class="status-picker"
+							>
+								<div class="picker-value">
+									{{ currentStatusLabel || '请选择' }}
+									<text class="picker-arrow">▼</text>
+								</div>
+							</picker>
+						</template>
+						<div v-else>{{ getStatusLabel(workDetailData.eventStatus) }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">工单处置人</div>
+						<div>{{ workDetailData.disposeUserName }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">处置部门</div>
+						<div>{{ workDetailData.disposeDeptName }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">拍摄时间</div>
+						<div>{{ workDetailData.shootTime }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">分发人员</div>
+						<div>{{ workDetailData.distributeUserName }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">分发部门</div>
+						<div>{{ workDetailData.distributeDeptName }}</div>
+					</div>
 
-          <div class="orderRow">
-            <div class="rowTitle">分发时间</div>
-            <div>{{ workDetailData.distributeTime }}</div>
-          </div>
-          <div class="orderRow">
-            <div class="rowTitle">工单位置</div>
-            <div class="rowAddress" @click="jumpMap(workDetailData)">{{ workDetailData.eventLocation }}</div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <!-- 操作按钮 -->
-    <div class="actionButton" >
-      <div class="btngroups" v-if="workDetailData.eventStatus !== 3">
-        <up-button type="primary"  color="#AEAEAE" text="退回" @click="rejectTicket"></up-button>
-        <up-button type="primary" color="#1D6FE9" text="确认" @click="confirmTheTicket"></up-button>
-      </div>
-      <div class="btngroups" v-if="workDetailData.eventStatus === 3">
-        <up-button type="primary" color="#1D6FE9" text="已确认" @click="confirmedHandle"></up-button>
-      </div>
-    </div>
-    <!-- 分享弹出层 -->
-    <div v-if="showShareModal" class="share-modal-overlay" @click="onShareModalClose">
-      <div class="share-modal-content" @click.stop>
-        <div class="share-modal-header">
-          <div class="share-modal-title">分享到</div>
-          <!-- <div class="share-modal-close" @click="onShareModalClose">×</div> -->
-        </div>
-        <div class="share-modal-body">
-<!--          <div class="share-item" @click="shareToWechat">-->
-<!--            <div class="share-icon wechat"></div>-->
-<!--            <div class="share-name">微信好友</div>-->
-<!--          </div>-->
-<!--          <div class="share-item" @click="shareToMoments">-->
-<!--            <div class="share-icon moments"></div>-->
-<!--            <div class="share-name">朋友圈</div>-->
-<!--          </div>-->
-          <div class="share-item" @click="copyLink">
-            <div class="share-icon link"></div>
-            <div class="share-name">复制链接</div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
+					<div class="orderRow">
+						<div class="rowTitle">分发时间</div>
+						<div>{{ workDetailData.distributeTime }}</div>
+					</div>
+					<div class="orderRow">
+						<div class="rowTitle">工单位置</div>
+						<div class="rowAddress" @click="jumpMap(workDetailData)">{{ workDetailData.eventLocation }}</div>
+					</div>
+				</div>
+			</div>
+			<!-- 操作按钮 -->
+			<div class="actionButton">
+				<div class="btngroups" v-if="workDetailData.eventStatus === 0">
+					<up-button type="primary" color="#AEAEAE" text="退回" @click="rejectTicket"></up-button>
+					<up-button type="primary" color="#1D6FE9" text="待确认" @click="confirmTheTicket"></up-button>
+				</div>
+				<div class="btngroups" v-if="workDetailData.eventStatus === 1">
+					<up-button type="primary" color="#1D6FE9" text="处置记录" @click="handlelogs"></up-button>
+					<up-button type="primary" color="#1D6FE9" text="上传处置" @click="uploadHandle"></up-button>
+				</div>
+				<div class="btngroups" v-if="workDetailData.eventStatus === 3">
+					<up-button type="primary" color="#1D6FE9" text="处置记录" @click="handlelogs"></up-button>
+					<up-button type="primary" color="#1D6FE9" text="继续上传处置" @click="uploadHandle"></up-button>
+					<up-button type="primary" color="#1D6FE9" text="完成" @click="confirmedHandle"></up-button>
+				</div>
+				<div class="btngroups" v-if="workDetailData.eventStatus === 4">
+					<up-button type="primary" color="#1D6FE9" text="处置记录" @click="handlelogs"></up-button>
+				</div>
+			</div>
+		</div>
+
+		<!-- 完成情况弹窗 -->
+		<view v-if="showCompleteModal" class="complete-modal-overlay" @click="closeCompleteModal">
+			<view class="complete-modal" @click.stop>
+				<view class="complete-modal-title">填写完成情况</view>
+				<view class="complete-input-wrapper">
+					<textarea
+						v-model="completeContent"
+						class="complete-input"
+						maxlength="200"
+						placeholder="请输入完成情况"
+						:show-confirm-bar="false"
+					/>
+					<text class="complete-word-count">{{ completeContent.length }}/200</text>
+				</view>
+				<view class="complete-modal-actions">
+					<button class="complete-action-btn complete-cancel-btn" :disabled="completing" @click="closeCompleteModal">
+						取消
+					</button>
+					<button class="complete-action-btn complete-confirm-btn" :disabled="completing" @click="submitComplete">
+						{{ completing ? '提交中...' : '确认' }}
+					</button>
+				</view>
+			</view>
+		</view>
+		<!-- 分享弹出层 -->
+		<div v-if="showShareModal" class="share-modal-overlay" @click="onShareModalClose">
+			<div class="share-modal-content" @click.stop>
+				<div class="share-modal-header">
+					<div class="share-modal-title">分享到</div>
+					<!-- <div class="share-modal-close" @click="onShareModalClose">×</div> -->
+				</div>
+				<div class="share-modal-body">
+					<!--          <div class="share-item" @click="shareToWechat">-->
+					<!--            <div class="share-icon wechat"></div>-->
+					<!--            <div class="share-name">微信好友</div>-->
+					<!--          </div>-->
+					<!--          <div class="share-item" @click="shareToMoments">-->
+					<!--            <div class="share-icon moments"></div>-->
+					<!--            <div class="share-name">朋友圈</div>-->
+					<!--          </div>-->
+					<div class="share-item" @click="copyLink">
+						<div class="share-icon link"></div>
+						<div class="share-name">复制链接</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
 </template>
 
 <script setup>
 // import { getShowImg, getSmallImg } from '@/utils/util'
-import {getGddetailedData,backGdApi,shareCacheApi} from '/src/api/work/index.js'
+import { getGddetailedData, backGdApi, shareCacheApi, updateStatus } from '/src/api/work/index.js'
 import { getWebViewUrl } from '@/utils/index.js'
 import WebViewPlus from '@/components/WebViewPlus.vue'
+import { onShow } from '@dcloudio/uni-app'
 
 const eventNum = ref('')
 // 工单内容
 const workDetailData = ref({})
 // 环境判断
 const isH5 = ref(false)
-const sWebViewRef = ref(null);
-const viewUrl = ref("");
-onLoad(async options => {
-  eventNum.value = options.id
-  await getDataList(options.id,options.aiImg)
-  checkEnvironment()
-  viewUrl.value = getWebViewUrl("/workDetail", { workDetailData: JSON.stringify(workDetailData.value) });
+const sWebViewRef = ref(null)
+const viewUrl = ref('')
+const showCompleteModal = ref(false)
+const completeContent = ref('')
+const completing = ref(false)
+
+// 状态选项列表
+const statusOptions = [
+	{ name: '处置中', value: 1 },
+	{ name: '已处置', value: 3 },
+	// { name: '已完成', value: 4 },
+]
+// 当前选中状态的索引
+const statusPickerIndex = computed(() => {
+	const status = workDetailData.value?.eventStatus
+	return statusOptions.findIndex(item => item.value === status)
 })
-const getDataList = async (val,aiImg) => {
-  const params = {
-    id: val,
-  }
-  const res = await getGddetailedData(params)
-  const response = res.data.data
-  workDetailData.value = {...response,aiImg}
+// 当前状态文本
+const currentStatusLabel = computed(() => {
+	const option = statusOptions.find(item => item.value === workDetailData.value?.eventStatus)
+	return option?.name || ''
+})
+
+onLoad(async options => {
+	eventNum.value = options.id
+	await getDataList(options.id, options.aiImg)
+	checkEnvironment()
+	viewUrl.value = getWebViewUrl('/workDetail', { workDetailData: JSON.stringify(workDetailData.value) })
+})
+
+onShow(() => {
+	getDataList(eventNum.value)
+})
+
+const getDataList = async (val, aiImg) => {
+	const params = {
+		id: val,
+	}
+	const res = await getGddetailedData(params)
+	const response = res.data.data
+	workDetailData.value = { ...response, aiImg }
 }
+
+// 获取状态文本
+const getStatusLabel = status => {
+	const map = {
+		0: '待确认',
+		1: '处置中',
+		2: '已退回',
+		3: '已处置',
+		4: '已完成',
+	}
+	return map[status] || '未知'
+}
+
+// 切换状态
+const onStatusChange = e => {
+	const index = e.detail.value
+	const selectedOption = statusOptions[index]
+	if (!selectedOption) return
+
+	const id = workDetailData.value.id
+
+	if (workDetailData.value.eventStatus === 1 && selectedOption.value === 3) {
+		// 跳转上传处置页面
+		uni.navigateTo({
+			url: `/subPackages/workDetail/HandleWorking/index?id=${workDetailData.value.id}&eventStatus=${selectedOption.value}`,
+		})
+	}
+
+	if (workDetailData.value.eventStatus === 3 && selectedOption.value === 1) {
+		updateStatus({
+			eventId: workDetailData.value.id,
+			targetStatus: 1,
+		}).then(res => {
+			workDetailData.value.eventStatus = selectedOption.value
+		})
+	}
+
+	// console.log(selectedOption, '3333')
+	// backGdApi({ eventId: id, eventStatus: String(selectedOption.value) })
+	// 	.then(res => {
+	// 		uni.showToast({
+	// 			title: '状态更新成功',
+	// 			icon: 'success',
+	// 			duration: 1500,
+	// 		})
+	// 		workDetailData.value.eventStatus = selectedOption.value
+	// 	})
+	// 	.catch(() => {
+	// 		uni.showToast({
+	// 			title: '状态更新失败',
+	// 			icon: 'none',
+	// 		})
+	// 	})
+}
+
 // 检查运行环境
 const checkEnvironment = () => {
-  const systemInfo = uni.getSystemInfoSync()
-  // #ifdef APP-PLUS
-  isH5.value = false
-  // #endif
+	const systemInfo = uni.getSystemInfoSync()
+	// #ifdef APP-PLUS
+	isH5.value = false
+	// #endif
 
-  // #ifdef H5
-  isH5.value = true
-  // #endif
+	// #ifdef H5
+	isH5.value = true
+	// #endif
 
-  // console.log('当前环境:', isH5.value ? 'H5' : 'App')
+	// console.log('当前环境:', isH5.value ? 'H5' : 'App')
 }
 // 图片预览
 const previewImage = index => {
-  if (getImageList.value.length === 0) return
-  const currentIndex = typeof index === 'number' ? index : 0
-  uni.previewImage({
-    urls: getImageList.value,
-    current: currentIndex,
-  })
+	if (getImageList.value.length === 0) return
+	const currentIndex = typeof index === 'number' ? index : 0
+	uni.previewImage({
+		urls: getImageList.value,
+		current: currentIndex,
+	})
 }
 const getImageList = computed(() => {
-  const imageArr = []
-  const detail = workDetailData.value
-  if (detail.eventImageUrl) {
-    imageArr.push(detail.aiImg || detail.eventImageUrl)
-  }
-  return imageArr
+	const imageArr = []
+	const detail = workDetailData.value
+	if (detail.eventImageUrl) {
+		imageArr.push(detail.aiImg || detail.eventImageUrl)
+	}
+	return imageArr
 })
 // 跳转地图
 const jumpMap = item => {
-  // const contactStr = encodeURIComponent(JSON.stringify(item))
-    const contactStr = JSON.stringify(item)
-  uni.navigateTo({
-    url: `/subPackages/workDetail/mapWork/index?eventNum=${contactStr}`,
-  })
+	// const contactStr = encodeURIComponent(JSON.stringify(item))
+	const contactStr = JSON.stringify(item)
+	uni.navigateTo({
+		url: `/subPackages/workDetail/mapWork/index?eventNum=${contactStr}`,
+	})
 }
 // 退回
 const rejectTicket = () => {
-  const id = workDetailData.value.id
-  backGdApi({eventId : id,eventStatus:'0'}).then(res => {
-    uni.showToast({
-      title: '退回成功',
-      icon: 'success',
-      duration: 1500
-    })
-    setTimeout(() => {
-      uni.navigateBack()
-    })
-  })
-
+	// const id = workDetailData.value.id
+	// backGdApi({ eventId: id, eventStatus: '0' }).then(res => {
+	// 	uni.showToast({
+	// 		title: '退回成功',
+	// 		icon: 'success',
+	// 		duration: 1500,
+	// 	})
+	// 	setTimeout(() => {
+	// 		uni.navigateBack()
+	// 	})
+	// })
+	updateStatus({
+		eventId: workDetailData.value.id,
+		targetStatus: 2,
+	}).then(res => {
+		uni.showToast({
+			title: '退回成功',
+			icon: 'success',
+			duration: 1500,
+		})
+		setTimeout(() => {
+			uni.navigateBack()
+		})
+	})
 }
 // 确认工单
 const confirmTheTicket = () => {
-  const id = workDetailData.value.id
-  backGdApi({eventId : id,eventStatus:'1'}).then(res => {
-    uni.showToast({
-      title: '确认成功',
-      icon: 'success',
-      duration: 1500
-    })
-    setTimeout(() => {
-      uni.navigateBack()
-    })
-  })
+	// const id = workDetailData.value.id
+	// backGdApi({ eventId: id, eventStatus: '1' }).then(res => {
+	// 	uni.showToast({
+	// 		title: '确认成功',
+	// 		icon: 'success',
+	// 		duration: 1500,
+	// 	})
+	// 	setTimeout(() => {
+	// 		uni.navigateBack()
+	// 	})
+	// })
+	updateStatus({
+		eventId: workDetailData.value.id,
+		targetStatus: 1,
+	}).then(res => {
+		uni.showToast({
+			title: '确认成功',
+			icon: 'success',
+			duration: 1500,
+		})
+		setTimeout(() => {
+			// uni.navigateBack()
+			workDetailData.value.eventStatus = 1
+		})
+	})
 }
-// 已确认
+
+// 处置记录 - 跳转至处置记录页面
+function handlelogs() {
+	uni.navigateTo({
+		url: `/subPackages/workDetail/HandleWork/index?id=${workDetailData.value.id}&eventStatus=${workDetailData.value.eventStatus}`,
+	})
+}
+// 上传处置记录
+function uploadHandle() {
+	uni.navigateTo({
+		url: `/subPackages/workDetail/HandleWorking/index?id=${workDetailData.value.id}&eventStatus=${workDetailData.value.eventStatus}`,
+	})
+}
+
+// 打开完成情况弹窗
 const confirmedHandle = () => {
-  uni.navigateBack()
+	completeContent.value = ''
+	showCompleteModal.value = true
+}
+
+// 关闭完成情况弹窗
+const closeCompleteModal = () => {
+	if (completing.value) return
+	showCompleteModal.value = false
+}
+
+// 提交完成情况
+const submitComplete = async () => {
+	const operateContent = completeContent.value.trim()
+	if (!operateContent) {
+		uni.showToast({ title: '请输入完成情况', icon: 'none' })
+		return
+	}
+	completing.value = true
+	try {
+		await updateStatus({
+			eventId: workDetailData.value.id,
+			targetStatus: 4,
+			operateContent,
+		})
+		uni.showToast({ title: '操作成功', icon: 'success' })
+		setTimeout(() => {
+			uni.navigateBack()
+		}, 1000)
+	} catch {
+		completing.value = false
+		uni.showToast({ title: '操作失败,请重试', icon: 'none' })
+	}
 }
 // 分享模态框状态
 const showShareModal = ref(false)
@@ -228,8 +434,8 @@
 
 // 复制链接
 const copyLink = async () => {
-  const res = await shareCacheApi(workDetailData.value)
-  const shareUrl = getWebViewUrl("/workDetail", { workDetailData: JSON.stringify(res.data.data) })
+	const res = await shareCacheApi(workDetailData.value)
+	const shareUrl = getWebViewUrl('/workDetail', { workDetailData: JSON.stringify(res.data.data) })
 	try {
 		await uni.setClipboardData({
 			data: shareUrl,
@@ -279,7 +485,7 @@
 			type: 0,
 			title: workDetailData.value.event_name || '工单详情',
 			summary: '查看工单详情',
-      href: getWebViewUrl("/workDetail", { workDetailData: JSON.stringify(workDetailData.value) }),
+			href: getWebViewUrl('/workDetail', { workDetailData: JSON.stringify(workDetailData.value) }),
 			imageUrl: workDetailData.value.eventImageUrl,
 			success: () => {
 				uni.showToast({ title: '分享成功', icon: 'success' })
@@ -313,152 +519,280 @@
 
 // 返回按钮点击事件
 const onBackClick = () => {
-  uni.navigateBack()
+	uni.navigateBack()
 }
 
 // 监听导航栏右侧按钮点击事件(兼容原来的配置)
 const onNavigationBarButtonTap = e => {
-  if (e.index === 0) {
-    onShareClick()
-  }
+	if (e.index === 0) {
+		onShareClick()
+	}
 }
 </script>
 <style lang="scss" scoped>
 .workDetailContainer {
-  // 添加导航栏高度的padding-top,避免内容被遮挡
-  padding-top: 88rpx;
-  :deep(){
-  .u-navbar__content{
-    background: url("https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png")  no-repeat !important;
-    background-size: 100%!important;
-    height: 88rpx !important;
-  }
-}  // 分享按钮样式
-  .share-btn {
-    // #ifdef APP-PLUS
-    width: 40rpx;
-    height: 40rpx;
-    background-image: url('/static/images/work/share.svg');
-    background-size: contain;
-    background-repeat: no-repeat;
-    background-position: center;
-    // #endif
-  }
-  .tapShare-icon {
-    width: 40rpx;
-    height: 40rpx;
-    img {
-      width: 40rpx;
-      height: 40rpx;
-    }
-  }
-  .detailTop {
-  // #ifdef APP-PLUS
-  padding-top: 60rpx;
-  // #endif
-    .image-container {
-      position: relative;
-      width: 100%;
-      height: 410rpx;
+	// 添加导航栏高度的padding-top,避免内容被遮挡
+	padding-top: 88rpx;
+	:deep() {
+		.u-navbar__content {
+			background: url('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png')
+				no-repeat !important;
+			background-size: 100% !important;
+			height: 88rpx !important;
+		}
+	} // 分享按钮样式
+	.share-btn {
+		// #ifdef APP-PLUS
+		width: 40rpx;
+		height: 40rpx;
+		background-image: url('/static/images/work/share.svg');
+		background-size: contain;
+		background-repeat: no-repeat;
+		background-position: center;
+		// #endif
+	}
+	.tapShare-icon {
+		width: 40rpx;
+		height: 40rpx;
+		img {
+			width: 40rpx;
+			height: 40rpx;
+		}
+	}
+	.detailTop {
+		// #ifdef APP-PLUS
+		padding-top: 60rpx;
+		// #endif
+		.image-container {
+			position: relative;
+			width: 100%;
+			height: 410rpx;
 
-      .detailImage {
-        width: 100%;
-        height: 100%;
-        display: block;
-        object-fit: cover;
-      }
-      // 轮播图容器
-      :deep(.u-swiper) {
-        // 指示器容器 - 修改为居中对齐
-        .u-swiper__indicator {
-          position: absolute;
-          left: 50%;
-          transform: translateX(-50%);
-          bottom: 20rpx;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-          z-index: 10;
-        }
-        .u-swiper-indicator__wrapper__dot--active {
-          width: 5px !important;
-        }
-      }
+			.detailImage {
+				width: 100%;
+				height: 100%;
+				display: block;
+				object-fit: cover;
+			}
+			// 轮播图容器
+			:deep(.u-swiper) {
+				// 指示器容器 - 修改为居中对齐
+				.u-swiper__indicator {
+					position: absolute;
+					left: 50%;
+					transform: translateX(-50%);
+					bottom: 20rpx;
+					display: flex;
+					justify-content: center;
+					align-items: center;
+					z-index: 10;
+				}
+				.u-swiper-indicator__wrapper__dot--active {
+					width: 5px !important;
+				}
+			}
+		}
+	}
 
-    }
-  }
+	.worderContainer {
+		padding: 0 24rpx;
+		padding-bottom: 4rpx;
+		background: #f6f6f6;
+		margin-top: 20rpx;
+		height: calc(100vh - 530rpx);
+		overflow: auto;
+	}
+	.workOrderContent {
+		margin-top: 30epx;
+		background-color: #fff;
+		border-radius: 12rpx;
+		padding: 20rpx;
+		margin-bottom: 34rpx;
+		.workOrderTitle {
+			font-family: Source Han Sans CN, Source Han Sans CN;
+			font-weight: bold;
+			font-size: 32rpx;
+			color: #222324;
+		}
+		.workOrderContainer {
+			.orderRow {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				min-height: 96rpx;
+				border-bottom: 1px solid #f5f5f5;
+				color: #7b7b7b;
+				.rowTitle {
+					font-family: Source Han Sans CN, Source Han Sans CN;
+					font-weight: 400;
+					font-size: 30rpx;
+					color: #222324;
+					white-space: nowrap;
+				}
+				.rowAddress {
+					font-family: Source Han Sans CN, Source Han Sans CN;
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #1d6fe9;
+					text-decoration: underline;
+					text-align: right;
 
-  .worderContainer {
-    padding: 0 24rpx;
-    padding-bottom: 4rpx;
-    background: #f6f6f6;
-    margin-top: 20rpx;
-  }
-  .workOrderContent {
-    margin-top: 30epx;
-    background-color: #fff;
-    border-radius: 12rpx;
-    padding: 20rpx;
-    margin-bottom: 34rpx;
-    .workOrderTitle {
-      font-family: Source Han Sans CN, Source Han Sans CN;
-      font-weight: bold;
-      font-size: 32rpx;
-      color: #222324;
-    }
-    .workOrderContainer {
-      .orderRow {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        min-height: 96rpx;
-        border-bottom: 1px solid #f5f5f5;
-        color: #7b7b7b;
-        .rowTitle {
-          font-family: Source Han Sans CN, Source Han Sans CN;
-          font-weight: 400;
-          font-size: 30rpx;
-          color: #222324;
-          white-space: nowrap;
-        }
-        .rowAddress {
-          font-family: Source Han Sans CN, Source Han Sans CN;
-          font-weight: 400;
-          font-size: 28rpx;
-          color: #1d6fe9;
-          text-decoration: underline;
-          text-align: right;
+					padding-top: 1px;
+					padding-left: 5px;
+					padding-right: 2px;
+				}
+				.status-picker {
+					.picker-value {
+						font-family: Source Han Sans CN, Source Han Sans CN;
+						font-weight: 400;
+						font-size: 28rpx;
+						color: #1d6fe9;
+						display: flex;
+						align-items: center;
+						gap: 8rpx;
+					}
+					.picker-arrow {
+						font-size: 20rpx;
+						color: #999;
+					}
+				}
+			}
+		}
+	}
 
-          padding-top: 1px;
-          padding-left: 5px;
-          padding-right: 2px;
-        }
-      }
-    }
-  }
+	.actionButton {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		box-sizing: border-box;
+		width: 100%;
+		height: 61px;
+		padding: 0 24rpx;
 
-  .actionButton {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    width: 100%;
-    height: 61px;
+		border-radius: 6px 6px 6px 6px;
 
-    border-radius: 6px 6px 6px 6px;
+		.btngroups {
+			display: flex;
+			align-items: center;
+			width: 100%;
+			min-width: 0;
+			:deep(.u-button) {
+				width: 0 !important;
+				min-width: 0;
+				margin: 0 !important;
+				flex: 1;
+				height: 76rpx !important;
+			}
+			&:not(.three-actions) {
+				:deep(.u-button + .u-button) {
+					margin-left: 20rpx !important;
+				}
+			}
+			&.three-actions {
+				justify-content: center;
+				:deep(.u-button) {
+					width: 210rpx !important;
+					flex: 0 0 210rpx;
+				}
+				:deep(.u-button:last-child) {
+					margin-left: 20rpx !important;
+				}
+			}
+		}
+	}
+}
 
-    .btngroups {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      :deep(.u-button) {
-        width: 276rpx !important;
-        height: 76rpx !important;
-        &:last-child {
-          margin-left: 30rpx;
-        }
-      }
-    }
-  }
+.complete-modal-overlay {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 10000;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+	padding: 40rpx;
+	background: rgba(0, 0, 0, 0.55);
+}
+
+.complete-modal {
+	box-sizing: border-box;
+	width: 620rpx;
+	max-width: 100%;
+	padding: 32rpx;
+	background: #ffffff;
+	border-radius: 12rpx;
+}
+
+.complete-modal-title {
+	margin-bottom: 28rpx;
+	font-size: 32rpx;
+	font-weight: 500;
+	color: #222324;
+	text-align: center;
+}
+
+.complete-input-wrapper {
+	position: relative;
+	box-sizing: border-box;
+	height: 220rpx;
+	padding-bottom: 38rpx;
+	background: #f6f7f9;
+	border: 1rpx solid #e5e7eb;
+	border-radius: 6rpx;
+}
+
+.complete-input {
+	box-sizing: border-box;
+	width: 100%;
+	height: 100%;
+	padding: 20rpx;
+	font-size: 28rpx;
+	line-height: 1.5;
+	color: #222324;
+}
+
+.complete-word-count {
+	position: absolute;
+	right: 16rpx;
+	bottom: 10rpx;
+	font-size: 22rpx;
+	color: #999999;
+}
+
+.complete-modal-actions {
+	display: flex;
+	gap: 24rpx;
+	margin-top: 30rpx;
+}
+
+.complete-action-btn {
+	height: 76rpx;
+	margin: 0;
+	flex: 1;
+	font-size: 28rpx;
+	line-height: 76rpx;
+	border-radius: 6rpx;
+}
+
+.complete-action-btn::after {
+	border: 0;
+}
+
+.complete-cancel-btn {
+	color: #666666;
+	background: #f1f2f4;
+}
+
+.complete-confirm-btn {
+	color: #ffffff;
+	background: #1d6fe9;
+}
+
+.complete-action-btn[disabled] {
+	opacity: 0.65;
 }
 
 /* 分享弹出层样式 */
@@ -544,7 +878,6 @@
 .share-icon.moments {
 	background-image: url('@/static/images/work/moments.svg');
 }
-
 
 .share-icon.link {
 	background-image: url('@/static/images/work/link.svg');

--
Gitblit v1.9.3