From 446823f71c9f7b867244035433febb3d8fd66573 Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Sat, 11 Oct 2025 17:25:17 +0800
Subject: [PATCH] feat:事件工单

---
 src/api/work/index.js                |   24 ++
 src/subPackages/workDetail/index.vue |  247 ++++++++++++++++++++++++++-
 src/pages/work/index.vue             |  255 ++++++++++++++++++++++------
 3 files changed, 456 insertions(+), 70 deletions(-)

diff --git a/src/api/work/index.js b/src/api/work/index.js
new file mode 100644
index 0000000..0658350
--- /dev/null
+++ b/src/api/work/index.js
@@ -0,0 +1,24 @@
+import {request} from "@/utils/index.js";
+export const getList = (data) => {
+  return request({
+    url: '/drone-device-core/jobEvent/eventPage',
+    method: 'post',
+    data,
+  })
+}
+// 获取状态统计数据
+export const getstatusCount = (params) => {
+  return request({
+    url: '/drone-device-core/jobEvent/getstatusCount',
+    method: 'get',
+    params,
+  })
+}
+
+export const getStepInfo = (eventNum) => {
+  return request({
+    url: '/drone-device-core/jobEvent/getStepInfo',
+    method: 'get',
+    params: { eventNum }
+  })
+}
\ No newline at end of file
diff --git a/src/pages/work/index.vue b/src/pages/work/index.vue
index 8682ae9..60f780c 100644
--- a/src/pages/work/index.vue
+++ b/src/pages/work/index.vue
@@ -1,67 +1,208 @@
-<!-- 事件工单 -->
 <template>
-  <view class="min-h-screen flex flex-col items-center">
-    <image
-      class="mb-50rpx mt-200rpx h-200rpx w-200rpx"
-      src="@/static/images/logo.png"
-      width="200rpx"
-      height="200rpx"
-    />
-    <view class="flex justify-center">
-      <text class="font-size-36rpx">
-        {{ $t("home.intro") }}
-      </text>
-    </view>
-    <view class="mt-100rpx flex gap-30rpx">
-      <lang-select />
-      <view class="cursor-pointer" @click="toGithub">
-        <view class="i-mdi-github text-40rpx" />
-      </view>
-    </view>
+	<view class="flex flex-col eventTickets">
+		<view class="searchTop">
+			<up-search placeholder="请输入关键字搜索"  :animation="true"  v-model="listParams.keyword" :show-action="false"></up-search>
+			<div>111</div>
+		</view>
+		<view>
+			<up-tabs :list="tabList" @click="handleClick"></up-tabs>
+			<view class="eventBox">
+				<view class="eventItem"  v-for="(item,index) in dataList" :key="index">
+					<img :src="item.photo_url" alt="" @click="detailHandle(item)" />
+					<div class="itemTitle">{{item.event_name}}</div>
+					<div class="itemContent">
+						<div class="itemStatus">
+							<span v-if="item.status === 0" style="background-color: #ff7411;"></span>
+							<span v-else-if="item.status === 2" style="background-color: #ff472f;"></span>
+							<span v-else-if="item.status === 3" style="background-color: #ffc300;"></span>
+							<span v-else-if="item.status === 4" style="background-color: #06d957;"></span>
+							<p>{{formatDate(item.create_time) }}</p>
+						</div>
+						<div>全屏</div>
+					</div>
+				</view>
+			</view>
+		</view>
+	</view>
 
-    <!-- #ifdef MP-WEIXIN -->
-    <!-- 隐私协议组件 -->
-    <agree-privacy
-      v-model="showAgreePrivacy"
-      :disable-check-privacy="false"
-      @agree="handleAgree"
-    />
-    <!-- #endif -->
-  </view>
 </template>
 
 <script setup>
-// #ifdef MP-WEIXIN
-import { useShare } from "@/hooks";
-// #endif
 
-// #ifdef MP-WEIXIN
-// 分享使用示例
-const { onShareAppMessage, onShareTimeline } = useShare({
-  title: "首页",
-  path: "pages/tab/map/index",
-  imageUrl: "",
-});
-onShareAppMessage();
-onShareTimeline();
-// #endif
+import {getList,getstatusCount} from '/src/api/work/index.js'
+	import dayjs from 'dayjs';
+	const dataList = ref([])
+	const keyword = ref('')
+	const tabList = ref([{
+			name: '我的工单',
+			key: 'myTickets',
+			badge: {
+				value: 1
+			}
+		},
+		{
+			name: '全部状态',
+			key: 'all',
+			badge: {
+				value: 2
+			},
+			status: null
+		},
+		{
+			name: '待审核',
+			key: 'pending',
+			badge: {
+				value: 3
+			},
+			status: '2'
+		},
+		{
+			name: '待处理',
+			key: 'processing',
+			badge: {
+				value: 4
+			},
+			status: '0'
+		},
+		{
+			name: '处理中',
+			key: 'inProgress',
+			badge: {
+				value: 5
+			},
+			status: '3'
+		},
+		{
+			name: '已完成',
+			key: 'completed',
+			badge: {
+				value: 6
+			},
+			status: '4'
+		}
+	])
+	const formatDate = (dateString) => {
+		return dayjs(dateString).format('MM/DD HH:mm');
+	};
+	const listParams = ref({
+		status: null,
+		current: 1,
+		size: 9999,
+		source: 1,
+		department:'',
+		keyword:''
 
-const title = ref();
-title.value = import.meta.env.VITE_APP_TITLE;
+	})
+	const getDataList = () => {
+		const params = {
+			current: 1,
+			size: 9999,
+			source: 1,
+			status:listParams.value.status,
+			event_name:listParams.value.keyword
+		}
+		getList(params).then(res => {
+		
+			const response = res.data.data.records
+			dataList.value = response
+		})
+	}
+		const getstatusCountData=()=>{
+			getstatusCount().then(res=>{
+				const response = res.data.data
+				 const { statusCount, totalCount, userCount } = response
+				tabList.value.forEach(tab=>{
+			
+					if(tab.key === 'all'){
+						tab.badge.value = totalCount || 0
 
-const showAgreePrivacy = ref(false);
+					}else if(tab.key === 'myTickets'){
+						tab.badge.value = userCount || 0
+					}else{
+						tab.badge.value=statusCount[String(tab.status)] || 0
+					}
+				})
+			
+			})
+		}
 
-// 同意隐私协议
-function handleAgree() {
-  console.log("同意隐私政策");
-}
-
-// 打开github
-function toGithub() {
-  if (window?.open) {
-    window.open("https://github.com/oyjt/uniapp-vue3-template");
-  } else {
-    uni.$u.toast("请使用浏览器打开");
-  }
-}
+	const handleClick = (item) => {
+	listParams.value.status = item.status
+		getDataList()
+	}
+	const detailHandle = (val) => {
+		uni.navigateTo({
+			url: `/subPackages/workDetail/index?eventNum=${val.event_num}`,
+		})
+	}
+	onShow(() => {
+		getDataList()
+		getstatusCountData()
+	})
 </script>
+
+<style scoped lang="scss">
+	.eventTickets {
+		padding: 0 10px;
+
+		.searchTop {
+			display: flex;
+			align-items: center;
+			margin-top: 10px;
+		}
+
+		:deep(.u-badge) {
+			background-color: #1d6fe9 !important;
+		}
+
+		.eventBox {
+			display: flex;
+			flex-wrap: wrap;
+			gap: 10px;
+			padding: 10px 0;
+			background-color: #ebeff2;
+
+			.eventItem {
+				width: calc(50% - 5px);
+				background-color: #fff;
+				border-radius: 5px;
+				overflow: hidden;
+
+				img {
+					width: 100%;
+					height: 100px;
+					border-radius: 5px;
+					overflow: hidden;
+				}
+
+				.itemTitle {
+					padding: 0 5px;
+					 white-space: nowrap; 
+					overflow: hidden; 
+					text-overflow: ellipsis; 
+				}
+
+				.itemContent {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					padding: 5px;
+
+					.itemStatus {
+						display: flex;
+						align-items: center;
+
+						span {
+							display: inline-block;
+							width: 10px;
+							height: 10px;
+							border-radius: 50%;
+							margin-right: 5px;
+						}
+					}
+
+				}
+			}
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/src/subPackages/workDetail/index.vue b/src/subPackages/workDetail/index.vue
index 7a6c92d..dedac24 100644
--- a/src/subPackages/workDetail/index.vue
+++ b/src/subPackages/workDetail/index.vue
@@ -1,18 +1,239 @@
-<!--
- * @Author       : yuan
- * @Date         : 2025-09-29 13:52:16
- * @LastEditors  : yuan
- * @LastEditTime : 2025-09-29 13:53:32
- * @FilePath     : \src\subPackages\workDetail\index.vue
- * @Description  :
- * Copyright 2025 OBKoro1, All Rights Reserved.
- * 2025-09-29 13:52:16
--->
 <!-- 工单详情 - 包含待审核、待处理、处理中、已完成 -->
 <template>
-  <view> 基础 </view>
+	<view class="workDetailContainer">
+		<div class="detailTop">
+			<div class="image-container">
+				<u-image class="detailImage" :src="workDetailData.photo_url" mode="cover" width="100%" height="200px"
+					@click="previewImage(workDetailData.photo_url)"></u-image>
+				<div class="detailTitle">
+					<div class="titleText">
+						<p>{{workDetailData.event_name}}</p>
+						<p>{{workDetailData.create_time}}</p>
+					</div>
+				</div>
+			</div>
+		</div>
+		<!-- 步骤条 -->
+		<div class="stepContainer">
+		  <up-steps :current="currentStep" direction="column">
+		      <up-steps-item 
+		        v-for="(step, index) in stepTitles" 
+		        :key="index"
+		      >
+		        <template #title>
+		          <div class="horizontal-step">
+		            <span class="step-title">{{ step.title }}</span>
+		            <div class="step-desc" v-if="stepResponse[index]">
+		              <span>{{ stepResponse[index].name || '' }}</span>
+		              <span>{{ stepResponse[index].create_time || '' }}</span>
+		            </div>
+		          </div>
+		        </template>
+		      </up-steps-item>
+		    </up-steps>
+		</div>
+		<!-- 工单内容 -->
+		<div class="workOrderContent">
+			<div class="workOrderTitle">工单内容</div>
+			<div class="workOrderContainer">
+				<div>工单名称:{{workDetailData.event_name}}</div>
+				<div>工单类型:{{workDetailData.$type}}</div>
+				<div>关联任务:{{workDetailData.job_name}}</div>
+				<div>工单创建人:{{workDetailData.creator}}</div>
+				<div>事件地址:{{workDetailData.address}}</div>
+				<div>关联算法:{{workDetailData.ai_types}}</div>
+				<div>发起部门:{{workDetailData.dept_name}}</div>
+				<div>发起任务时间:{{workDetailData.create_time}}</div>
+				<div>工单内容:{{workDetailData.remark}}</div>
+			</div>
+		</div>
+		<!-- 操作按钮 -->
+		<div class="actionButton">
+			<div class="leftBtn" @click="leftClick">
+				上一页
+			</div>
+			<div class="btngroups">
+				<up-button type="primary" text="通过"></up-button>
+				<up-button type="error" text="不通过"></up-button>
+			</div>
+			<div class="leftBtn" @click="rightClick">
+				下一页
+			</div>
+		</div>
+
+	</view>
 </template>
 
-<script setup></script>
+<script setup>
+	import {getStepInfo,getList} from '/src/api/work/index.js'
+	const eventNum = ref('');
+	const currentStatus = ref('')
+	const stepResponse = ref([]);
+	const currentStep = ref(0);
+	// 工单内容
+	const workDetailData = ref({})
+	const stepTitles  =ref([
+		{
+			title: '待审核',
+			status: '2'
+		},
+		{
+			title: '待处理',
+			status: '0'
+		},
+		
+		{
+			title: '处理中',
+			status: '3'
+		},{
+			title: '已完成',
+			status: '4'
+		}
+	])
+	onLoad(async (options) => {
+	  eventNum.value = options.eventNum;
+	  await getDataList(eventNum.value); 
+	  await getStepInfoData(eventNum.value); 
+	});
+	const getDataList = async (val) => {
+	  const params = {
+	    current: 1,
+	    size: 9999,
+	    source: 1,  
+	    event_name: val
+	  }
+	  const res = await getList(params);
+	  const response = res.data.data.records;
+	  workDetailData.value = response[0];
+	  currentStatus.value = workDetailData.value.status;
+	  
+	}
+	// 步骤条
+	const calculateCurrentStep = (status) => {
+	  const statusToStep = {
+	    '2': 0,  // 待审核 -> 第0步
+	    '0': 1,  // 待处理 -> 第1步
+	    '3': 2,  // 处理中 -> 第2步
+	    '4': 3   // 已完成 -> 第3步
+	  }
+	  return statusToStep[String(status)] || 0 
+	}
+	const getStepInfoData = async (val) => {
+	  const res = await getStepInfo(val);
+	  stepResponse.value = res.data.data;
+	  currentStep.value = calculateCurrentStep(currentStatus.value);
+	}
+	// 图片预览
+	const previewImage = (url) => {
+		uni.previewImage({
+			urls: [url],
+			current: 0
+		});
+	};
+</script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+	.workDetailContainer {
+		padding: 0 10px;
+
+		.detailTop {
+			.image-container {
+				position: relative;
+				width: 100%;
+				height: 200px;
+
+				.detailImage {
+					width: 100%;
+					height: 100%;
+					display: block;
+					object-fit: cover
+				}
+
+				.detailTitle {
+					position: absolute;
+					left: 0;
+					bottom: 0;
+					    width: 100%; 
+				}
+
+				.titleText {
+					display: flex;
+					width: 100%;
+					justify-content: space-between;
+					align-items: center;
+				}
+			}
+		}
+
+		.stepContainer {
+			margin-top: 10px;
+			display: flex;
+			background-color: aquamarine;
+			border-radius: 5px;
+			padding: 10px;
+			 .horizontal-step {
+			    display: flex;
+			    align-items: center;
+			    gap: 12px;
+			    
+			    .step-title {
+			      min-width: 60px; 
+			    }
+			    
+			    .step-desc {
+			      display: flex;
+				  justify-content: space-around;
+			      gap: 8px;
+			      // color: #666;
+			      font-size: 14px;
+			    }
+			  }
+
+		}
+
+		
+		.actionButton{
+			display: flex;
+			justify-content: space-between;
+		margin-bottom: 10px;
+			.btngroups {
+				display: flex;
+				justify-content: space-between;
+				.u-button {
+				   padding: 9px 20px;
+				     height: 32px;
+				     &:last-child {
+				         margin-left: 12px;
+				         margin-right: 12px;
+				       }
+				}
+			}
+			.leftBtn {
+			  width: 70px;
+			  height: 32px;
+			  background-color: #999;
+			  border-radius: 5px;
+			  text-align: center;
+			  line-height: 32px;
+			  color: #fff;
+			  cursor: pointer;
+			  opacity: 0.8;
+			}
+			.disableds {
+			  background: #999 !important;
+			  cursor: not-allowed !important;
+			  pointer-events: none;
+			  opacity: 0.3 !important;
+			}
+		}
+		.workOrderContent {
+			margin-top: 15px;
+			.workOrderContainer {
+				div {
+					margin-bottom: 10px;
+				}
+			}
+		}
+		
+	}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3