Jelajahi Sumber

Merge branch 'master' of http://222.243.138.146:2000/ygtx/gxt_app

# Conflicts:
#	pages/order/detail/restartIndex.uvue
wuhb 2 bulan lalu
induk
melakukan
77fcc8d805

+ 3 - 0
.hbuilderx/launch.json

@@ -13,6 +13,9 @@
             "default" : {
                 "launchtype" : "local"
             },
+            "h5" : {
+                "launchtype" : "local"
+            },
             "provider" : "aliyun",
             "type" : "uniCloud"
         }

+ 5 - 5
manifest.json

@@ -1,5 +1,5 @@
 {
-	"name": "工效通APP",
+	"name": "工效通",
 	"appid": "__UNI__1050C07",
 	"description": "工效通任务管理平台",
 	"versionName": "1.3.5",
@@ -63,10 +63,10 @@
 				"uni-push": {}
 			},
 			"icons": {
-				"hdpi": "",
-				"xhdpi": "",
-				"xxhdpi": "",
-				"xxxhdpi": ""
+				"hdpi": "C:/project/ygtx-gxt/gxt_app/static/images/splash/72.png",
+				"xhdpi": "C:/project/ygtx-gxt/gxt_app/static/images/splash/96.png",
+				"xxhdpi": "C:/project/ygtx-gxt/gxt_app/static/images/splash/144.png",
+				"xxxhdpi": "C:/project/ygtx-gxt/gxt_app/static/images/splash/192.png"
 			},
 			"splashScreens": {
 				"default": {

+ 32 - 1
pages/order/detail/acceptIndex.uvue

@@ -39,10 +39,14 @@
 					    <text class="info-label">下发时间</text>
 					    <text class="info-value">{{ detailData.assignTime ?? '' }}</text>
 					</view>
-					<view class="info-item" v-if="detailData.orderType == 2">
+					<view class="info-item" v-if="detailData.orderType == 2 && detailData.misNo != null">
 					    <text class="info-label">MIS工单编码</text>
 					    <text class="info-value">{{ detailData.misNo ?? '' }}</text>
 					</view>
+					<view class="info-item" v-if="detailData.orderType == 2">
+					    <text class="info-label">维保类型</text>
+					    <text class="info-value">{{ inspectionTypeLabel }}</text>
+					</view>
 					<view class="info-item" v-if="detailData.orderType == 2">
 					    <text class="info-label">维保内容</text>
 					    <text class="info-value">{{ detailData.content ?? '' }}</text>
@@ -167,6 +171,7 @@
 	// 添加字典加载状态
 	const dictLoaded = ref<boolean>(false)
 	let keyword = ref<string>("")
+	const inspectionTypeLabel = ref<string>("") //维保类型
 
 	// 详情数据
 	const detailData = ref<acceptOrderInfo2>({
@@ -479,6 +484,32 @@
 					teamLeaderName.value = orderDtail.teamLeaderName as string
 				}
 				loadTeamLeaderList()
+				
+				if(data['orderType'] == 2 && data['inspectionType'] != null) {
+					const result = await getDictDataByType("gxt_inspection_type")
+					const resultObj = result as UTSJSONObject
+					const dictList = resultObj['data'] as any[]
+					if (dictList.length > 0) {
+						const targetValueStr = data['inspectionType'] as string;
+						const targetValueArray = targetValueStr
+						      .split(',') // 分割逗号,转为数组(单值分割后仍为长度1的数组)
+						      .map(item => item.trim());
+						const matchedLabels = dictList.filter(dictItem => {
+							// 统一转换为字符串匹配,避免数字/字符串类型不匹配问题
+							const dictItemObj = dictItem as UTSJSONObject;
+							const dictValueStr = dictItemObj['dictValue'] as string | null;
+							// 判断当前字典项的value是否在目标值数组中
+							if (dictValueStr == null) return false;
+								return targetValueArray.includes(dictValueStr);
+							}).map(dictItem => {
+								const dictItemObj = dictItem as UTSJSONObject;
+								const label = dictItemObj['dictLabel'] as string | null;
+								return label ?? '';
+							}); // 提取匹配项的label,形成label数组
+						  // 步骤4:将label数组用逗号分隔拼接,赋值给inspectionTypeLabel
+						inspectionTypeLabel.value = matchedLabels.join(',');
+					}
+				}
             } else {
                 const msg = resultObj['msg'] as string | null
                 uni.showToast({

+ 2 - 2
pages/order/detail/index.uvue

@@ -262,7 +262,7 @@
 	const getLabel = (item : OrderInfoForDetail | null): string|null => {
 		if (item == null) return null
 		// 如果是"待接单"状态,显示派单时间
-		if (item.workOrderStatus == 'assigned') {
+		if (item.workOrderStatus == 'assigned' || item.workOrderStatus == 'auto_suspend') {
 			return '下发时间'
 		} else if(item.workOrderStatus == 'to_finish') {
 			if(item.workEndTime != null) {
@@ -291,7 +291,7 @@
 		let showTime = ref<string|null>('')
 
 		// 如果是"待接单"状态,显示派单时间
-		if (item.workOrderStatus == 'assigned') {
+		if (item.workOrderStatus == 'assigned' || item.workOrderStatus == 'auto_suspend') {
 			showTime.value = item.assignTime
 		} else if(item.workOrderStatus == 'to_finish') {
 			showTime.value = item.acceptTime

+ 2 - 2
pages/order/detail/returnIndex.uvue

@@ -40,7 +40,7 @@
 			<!-- 退回原因选择 -->
 			<view class="info-section">
 			    <!-- <view class="section-title">
-			        <text class="section-title-text">退回类型</text>
+			        <text class="section-title-text">退回原因</text>
 			    </view> -->
 			    <view class="info-card">
 			        <view class="info-item">
@@ -80,7 +80,7 @@
 			    <view class="modal-mask" @click="showReasonPicker = false"></view>
 			    <view class="modal-content">
 			        <view class="modal-header">
-			            <text class="modal-title">退回类型</text>
+			            <text class="modal-title">退回原因</text>
 			            <text class="modal-close" @click="showReasonPicker = false">取消</text>
 			        </view>
 			        <scroll-view class="modal-body" scroll-y="true">

+ 1 - 1
pages/order/detail/shutdownIndex.uvue

@@ -46,7 +46,7 @@
 								    class="input-field"
 								    placeholder="请选择停机时间"
 								    v-model="pauseTime"
-									:disabled="true"
+									type="none"
 								/>
 						    </view>
 						</view>

+ 183 - 6
pages/order/detail/wbBackfillFinalize.uvue

@@ -63,7 +63,7 @@
 								    class="input-field"
 								    placeholder="请选择开始时间"
 								    v-model="realStartTime"
-									:disabled="true"
+									type="none"
 								/>
                             </view>
                         </view>
@@ -80,11 +80,28 @@
 								    class="input-field"
 								    placeholder="请选择结束时间"
 								    v-model="realEndTime"
-									:disabled="true"
+									type="none"
 								/>
                             </view>
                         </view>
                     </view>
+					
+					<!-- 挂起结束时间 -->
+					<view class="info-item" v-if="resumeInfo != null && resumeShow">
+					    <view class="info-label">
+					        <text class="form-label required">挂起结束时间<text style="color: red;">*</text></text>
+					    </view>
+					    <view class="info-value">
+					        <view class="form-picker" @click="showResumeTimePicker = true">
+								<input
+								    class="input-field"
+								    placeholder="请选择挂起结束时间"
+								    v-model="resumeTime"
+									type="none"
+								/>
+					        </view>
+					    </view>
+					</view>
 
                     <!-- 外委人员数 -->
                     <view class="info-item">
@@ -126,7 +143,7 @@
                         <view class="info-value">
                             <input
                                 class="input-field"
-                                placeholder="请输入工作负责人"
+                                placeholder="请选择工作负责人"
                                 v-model="teamLeaderName"
                                 :disabled="true"
                             />
@@ -210,13 +227,26 @@
 					title="选择结束时间"
 					:mode="31"
 					format="YYYY-MM-DD HH:mm"
-					:modelValue="realStartTime"
+					:modelValue="realEndTime"
 					confirm-btn="确定"
 					cancel-btn="取消"
 					@confirm="onEndDateConfirm"
 					@cancel="showEndTimePicker = false">
 				</l-date-time-picker>
 			</l-popup>
+			
+			<l-popup v-model="showResumeTimePicker" position="bottom" :safe-area-inset-bottom="true" :z-index="10000">
+				<l-date-time-picker
+					title="选择挂起结束时间"
+					:mode="31"
+					format="YYYY-MM-DD HH:mm"
+					:modelValue="resumeTime"
+					confirm-btn="确定"
+					cancel-btn="取消"
+					@confirm="onResumeTimeConfirm"
+					@cancel="showResumeTimePicker = false">
+				</l-date-time-picker>
+			</l-popup>
 
             <!-- 人员选择弹窗 -->
             <view v-if="showUserSelect" class="picker-modal">
@@ -262,7 +292,7 @@
 </template>
 
 <script setup lang="uts">
-    import { ref } from 'vue'
+    import { ref, watch } from 'vue'
     import type { acceptOrderInfo } from '../../../types/order'
     import type { WorkOrderFlow } from '../../../types/flow'
     import { getOrderInfoById, getRepairOrderInfoById, returnRepairOrder, finishOrder } from '../../../api/order/detail'
@@ -333,6 +363,77 @@
 
     // 信息录入选项
 	const selectedMisInfoIndex = ref<number>(-1)
+	
+	//挂起结束时间
+	const suspendReason = ref<string>('') // 挂起原因
+	const flowList = ref<UTSJSONObject[]>([]) //流转过程
+	const suspendInfo = ref<UTSJSONObject | null>(null)
+	const resumeInfo = ref<UTSJSONObject | null>(null)
+	const resumeShow = ref<boolean>(false)
+	const resumeTime = ref<string>('') // 挂起结束时间
+	const showResumeTimePicker = ref<boolean>(false)
+	
+	// 监听开始时间和结束时间变化
+	watch(realStartTime, (value: string) => {
+	    console.log('开始时间变化:', value)
+	    // 在这里添加开始时间变化时的处理逻辑
+	    if (resumeInfo.value != null && value != '') {
+	        const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+	        if (suspendTime != '' && value != '') {
+	            const suspendDate = new Date(suspendTime)
+	            const startDate  = new Date(value)
+	            if (suspendDate.getTime() < startDate.getTime()) { // 开工前挂起
+	                const resumeDate = new Date(resumeTime.value)
+	                const endDate    = new Date(realEndTime.value)
+	                if (resumeDate.getTime() > startDate.getTime() || (realEndTime.value != '' && resumeDate.getTime() > endDate.getTime())) {
+	                    resumeShow.value = true
+	                } else {
+	                    resumeShow.value = false
+	                }
+	            } else if (suspendDate.getTime() >= startDate.getTime()) { // 作业中挂起
+	                const resumeDate = new Date(resumeTime.value)
+	                const endDate    = new Date(realEndTime.value)
+	                if (resumeDate.getTime() < startDate.getTime() || (realEndTime.value != '' && resumeDate.getTime() > endDate.getTime())) {
+	                    resumeShow.value = true
+	                } else {
+	                    resumeShow.value = false
+	                }
+	            } else {
+	                resumeShow.value = false
+	            }
+	        } else {
+	            resumeShow.value = false
+	        }
+	    }
+	})
+	
+	watch(realEndTime, (value: string) => {
+	    console.log('结束时间变化:', value)
+	    // 在这里添加结束时间变化时的处理逻辑
+		if (resumeInfo.value != null && value != '') {
+		    const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+		    if (suspendTime != '' && realStartTime.value != '' && new Date(suspendTime).getTime() < new Date(realStartTime.value).getTime()) { // 开工前挂起
+		      if (value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(realStartTime.value).getTime()) {
+		        resumeShow.value = true
+		      } else if(value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(value).getTime()) {
+		        resumeShow.value = true
+		      } else {
+		        resumeShow.value = false
+		      }
+		
+		    } else if(suspendTime != '' && realStartTime.value != '' && new Date(suspendTime).getTime() >= new Date(realStartTime.value).getTime()) { // 作业中挂起
+		      if (realStartTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() < new Date(realStartTime.value).getTime()) {
+		        resumeShow.value = true
+		      } else if(value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(value).getTime()) {
+		        resumeShow.value = true
+		      } else {
+		        resumeShow.value = false
+		      }
+		    } else {
+		      resumeShow.value = false
+		    }
+		  }
+	})
 
     // 获取用户列表
     const getUserAllList = async (): Promise<void> => {
@@ -422,6 +523,17 @@
 	  realEndTime.value = value
 	  showEndTimePicker.value = false
 	}
+	
+	function onResumeTimeConfirm(value: string) {
+	  // 检查新的结束时间是否小于开始时间
+	  if (resumeTime.value != '' && new Date(realStartTime.value as string) > new Date(value)) {
+	    uni.showToast({ title: '结束时间不能小于开始时间', icon: 'none' })
+	    return
+	  }
+	
+	  resumeTime.value = value
+	  showResumeTimePicker.value = false
+	}
 
     // 检查用户是否已被选中
     const isSelected = (user: UTSJSONObject): boolean => {
@@ -548,6 +660,47 @@
             return false;
         }
 		
+		if(resumeShow.value) {
+			if(resumeTime.value == '') {
+				uni.showToast({
+				    title: '请选挂起结束时间',
+				    icon: 'none'
+				});
+				return false;
+			} else {
+				const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+				if (suspendTime != '' && realStartTime.value != '' && new Date(suspendTime) < new Date(realStartTime.value)) { // 开工前挂起
+				  if (resumeTime.value != '' && new Date(resumeTime.value) > new Date(realStartTime.value)) {
+					uni.showToast({
+					    title: '开工前挂起结束时间晚于实际开始时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  } else if(realEndTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value) > new Date(realEndTime.value)) {
+					uni.showToast({
+					    title: '开工前挂起结束时间晚于实际结束时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  }
+				} else if(suspendTime != '' && realStartTime.value != '' && new Date(suspendTime) >= new Date(realStartTime.value)) { // 作业中挂起
+				  if (resumeTime.value != '' && new Date(resumeTime.value) < new Date(realStartTime.value)) {
+					uni.showToast({
+					    title: '作业中挂起结束时间早于实际开始时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  } else if(realEndTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value) > new Date(realEndTime.value)) {
+					uni.showToast({
+					    title: '作业中挂起结束时间晚于实际结束时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  }
+				}
+			}
+		}
+		
 		// if (infoEntry.value == '2' && (workGroupMemberName.value == '' || selectedUsers.value.length == 0)) {
 		//     uni.showToast({
 		//         title: '请选择工作班成员',
@@ -573,6 +726,12 @@
 			isDealing.value = true
 	        // 确保附件URLs是最新的逗号分隔格式
 	        attachmentUrls.value = uploadedFiles.value.map(file => file.fileName).join(',');
+			
+			flowList.value = []
+			if (resumeTime.value != '' && resumeInfo.value != null && resumeTime.value != (resumeInfo.value['actionTime'] as string | null)) { //存入新的挂起结束时间
+				resumeInfo.value['actionTime'] = resumeTime.value
+				flowList.value.push(resumeInfo.value as UTSJSONObject)
+			}
 	        const finishData = {
 	            id: orderId.value,
 	            orderType: orderType.value,
@@ -591,7 +750,8 @@
 				teamLeaderId: teamLeaderId.value,
 				teamLeaderName: teamLeaderName.value,
 				finalizeMethod: '2',
-				workOrderStatus: 'completed'
+				workOrderStatus: 'completed',
+				workOrderFlowList: flowList.value
 	        } as UTSJSONObject;
 
 	        const result = await finishOrder(finishData);
@@ -670,6 +830,7 @@
 				content.value = (data['content'] as string | null) ?? ''
 				misNo.value = (data['misNo'] as string | null) ?? ''
 				workPermitNum.value = (data['workPermitNum'] as string | null) ?? ''
+				suspendReason.value = (data['suspendReason'] as string | null) ?? ''
 				
 				const queryParams = {
 					misNo: misNo.value,
@@ -704,6 +865,22 @@
 							}
 						})
 					}
+					
+					flowList.value = data['workOrderFlowList'] as UTSJSONObject[]
+					if (suspendReason.value != '' && flowList.value.length > 0) {
+					  // 获取最后一个 actionType 等于 'resume' 的项
+					  const lastResumeItem = flowList.value.findLast(item => item['actionType'] === 'resume') as UTSJSONObject | null
+					  if (lastResumeItem != null) {
+						resumeInfo.value = lastResumeItem
+						// 直接给 resumeTime 赋值,无需 formData
+						resumeTime.value = (lastResumeItem['actionTime'] as string | null) ?? ''
+					  }
+								
+					  const lastSuspendItem = flowList.value.findLast(item => (item['actionType'] as string | null) === 'to_approve') as UTSJSONObject | null
+					  if (lastSuspendItem != null) {
+						suspendInfo.value = lastSuspendItem
+					  }
+					}
 				}
 			} else {
 				const msg = resultObj['msg'] as string | null

+ 203 - 115
pages/order/detail/wbFinalize.uvue

@@ -111,7 +111,7 @@
 								    class="input-field"
 								    placeholder="请选择开始时间"
 								    v-model="realStartTime"
-									:disabled="true"
+									type="none"
 								/>
                             </view>
                         </view>
@@ -128,11 +128,28 @@
 								    class="input-field"
 								    placeholder="请选择结束时间"
 								    v-model="realEndTime"
-									:disabled="true"
+									type="none"
 								/>
                             </view>
                         </view>
                     </view>
+					
+					<!-- 挂起结束时间 -->
+					<view class="info-item" v-if="resumeInfo != null && resumeShow">
+					    <view class="info-label">
+					        <text class="form-label required">挂起结束时间<text style="color: red;">*</text></text>
+					    </view>
+					    <view class="info-value">
+					        <view class="form-picker" @click="showResumeTimePicker = true">
+								<input
+								    class="input-field"
+								    placeholder="请选择挂起结束时间"
+								    v-model="resumeTime"
+									type="none"
+								/>
+					        </view>
+					    </view>
+					</view>
 
                     <!-- 外委人员数 -->
                     <view class="info-item">
@@ -197,7 +214,7 @@
 									@click="showUserSelect = true"
 									:disabled="infoEntry == '1'"
 								/>
-								<text class="select-users-count" v-if="selectedUserIds.length > 0" :style="{ marginRight: selectedUserIds.length > 0 ? '60rpx' : '0' }">({{ selectedUserIds.length }}人)</text>
+								<!-- <text class="select-users-count" v-if="selectedUserIds.length > 0" :style="{ marginRight: selectedUserIds.length > 0 ? '60rpx' : '0' }">({{ selectedUserIds.length }}人)</text> -->
 								<text class="select-clear" v-if="selectedUserIds.length > 0" @click="clearSelectedUsers">×</text>
 							</view>
                         </view>
@@ -259,13 +276,26 @@
 					title="选择结束时间"
 					:mode="31"
 					format="YYYY-MM-DD HH:mm"
-					:modelValue="realStartTime"
+					:modelValue="realEndTime"
 					confirm-btn="确定"
 					cancel-btn="取消"
 					@confirm="onEndDateConfirm"
 					@cancel="showEndTimePicker = false">
 				</l-date-time-picker>
 			</l-popup>
+			
+			<l-popup v-model="showResumeTimePicker" position="bottom" :safe-area-inset-bottom="true" :z-index="10000">
+				<l-date-time-picker
+					title="选择挂起结束时间"
+					:mode="31"
+					format="YYYY-MM-DD HH:mm"
+					:modelValue="resumeTime"
+					confirm-btn="确定"
+					cancel-btn="取消"
+					@confirm="onResumeTimeConfirm"
+					@cancel="showResumeTimePicker = false">
+				</l-date-time-picker>
+			</l-popup>
 
             <!-- 人员选择弹窗 -->
             <view v-if="showUserSelect" class="picker-modal">
@@ -324,10 +354,14 @@
 								class="picker-option"
 								@click="selectMisItem(item, index)"
 							>
-								<!-- <text class="option-text">{{ option.label }}</text>
-								<text class="option-text">{{ option.value }}</text> -->
+							<view>
+								<text class="option-text">MIS工单编码</text>
+								<text class="option-text">工作票编号</text>
+							</view>
+							<view>
 								<text class="option-text">{{ ((item['misNo'] as string | null) ?? '-')}}</text>
 								<text class="option-text">{{ item['workPermitNum'] as string | null ?? '-' }}</text>
+							</view>
 								<text v-if="index === selectedMisInfoIndex" class="option-check">✓</text>
 							</view>
 						</view>
@@ -338,7 +372,7 @@
 					</scroll-view>
                 </view>
             </view>
-			
+
 			<!-- 工作负责人弹窗 -->
 			<view v-if="showLeaderPicker" class="picker-modal">
 			    <view class="modal-mask" @click="showLeaderPicker = false"></view>
@@ -364,8 +398,9 @@
 								:class="{ 'selected': index === selectedTeamLeaderIndex }"
 								@click="selectLeaderManually(user, index)"
 							>
-								
+							<view class="info-row">
 								<text class="option-text">{{ (user['nickName'] as string | null) ?? '' }}</text>
+							</view>
 								<text class="option-text">{{ ((user['dept'] as UTSJSONObject | null)?.['deptName'] as string | null) ?? '' }}</text>
 								<text v-if="index === selectedTeamLeaderIndex" class="option-check">✓</text>
 							</view>
@@ -392,7 +427,7 @@
 </template>
 
 <script setup lang="uts">
-    import { ref } from 'vue'
+    import { ref, watch } from 'vue'
     import type { acceptOrderInfo } from '../../../types/order'
     import type { WorkOrderFlow } from '../../../types/flow'
     import { getOrderInfoById, getRepairOrderInfoById, returnRepairOrder, finishOrder } from '../../../api/order/detail'
@@ -477,7 +512,7 @@
     // 信息录入选项
     const infoEntryOptions = ref<SysDictData[]>([])
 	const selectedMisInfoIndex = ref<number>(-1)
-	
+
 	// 选中的负责人信息
 	const selectedTeamLeaderName = ref<string>('')
 	const selectedTeamLeaderIndex = ref<number>(-1)
@@ -485,6 +520,77 @@
 	const teamLeaderList = ref<UTSJSONObject[]>([])
 	const teamAllLeaderList = ref<UTSJSONObject[]>([])
 	let teamKeyword = ref<string>("")
+	
+	//挂起结束时间
+	const suspendReason = ref<string>('') // 挂起原因
+	const flowList = ref<UTSJSONObject[]>([]) //流转过程
+	const suspendInfo = ref<UTSJSONObject | null>(null)
+	const resumeInfo = ref<UTSJSONObject | null>(null)
+	const resumeShow = ref<boolean>(false)
+	const resumeTime = ref<string>('') // 挂起结束时间
+	const showResumeTimePicker = ref<boolean>(false)
+	
+	// 监听开始时间和结束时间变化
+	watch(realStartTime, (value: string) => {
+	    console.log('开始时间变化:', value)
+	    // 在这里添加开始时间变化时的处理逻辑
+	    if (resumeInfo.value != null && value != '') {
+	        const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+	        if (suspendTime != '' && value != '') {
+	            const suspendDate = new Date(suspendTime)
+	            const startDate  = new Date(value)
+	            if (suspendDate.getTime() < startDate.getTime()) { // 开工前挂起
+	                const resumeDate = new Date(resumeTime.value)
+	                const endDate    = new Date(realEndTime.value)
+	                if (resumeDate.getTime() > startDate.getTime() || (realEndTime.value != '' && resumeDate.getTime() > endDate.getTime())) {
+	                    resumeShow.value = true
+	                } else {
+	                    resumeShow.value = false
+	                }
+	            } else if (suspendDate.getTime() >= startDate.getTime()) { // 作业中挂起
+	                const resumeDate = new Date(resumeTime.value)
+	                const endDate    = new Date(realEndTime.value)
+	                if (resumeDate.getTime() < startDate.getTime() || (realEndTime.value != '' && resumeDate.getTime() > endDate.getTime())) {
+	                    resumeShow.value = true
+	                } else {
+	                    resumeShow.value = false
+	                }
+	            } else {
+	                resumeShow.value = false
+	            }
+	        } else {
+	            resumeShow.value = false
+	        }
+	    }
+	})
+	
+	watch(realEndTime, (value: string) => {
+	    console.log('结束时间变化:', value)
+	    // 在这里添加结束时间变化时的处理逻辑
+		if (resumeInfo.value != null && value != '') {
+		    const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+		    if (suspendTime != '' && realStartTime.value != '' && new Date(suspendTime).getTime() < new Date(realStartTime.value).getTime()) { // 开工前挂起
+		      if (value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(realStartTime.value).getTime()) {
+		        resumeShow.value = true
+		      } else if(value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(value).getTime()) {
+		        resumeShow.value = true
+		      } else {
+		        resumeShow.value = false
+		      }
+		
+		    } else if(suspendTime != '' && realStartTime.value != '' && new Date(suspendTime).getTime() >= new Date(realStartTime.value).getTime()) { // 作业中挂起
+		      if (realStartTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() < new Date(realStartTime.value).getTime()) {
+		        resumeShow.value = true
+		      } else if(value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(value).getTime()) {
+		        resumeShow.value = true
+		      } else {
+		        resumeShow.value = false
+		      }
+		    } else {
+		      resumeShow.value = false
+		    }
+		  }
+	})
 
     // 获取信息录入字典列表
     const loadInfoEntryDictList = async (): Promise<void> => {
@@ -587,60 +693,6 @@
 	    value: string
 	}
 
-	// 选中的挂起原因
-
-	const selectedReasonIndex = ref<number>(-1)
-	const returnTypeOptions = ref<PickerOption[]>([])
-	const showReasonPicker = ref<boolean>(false)
-
-	// 获取负责人列表(使用用户列表接口)
-	const dictList = async (): Promise<void> => {
-	    try {
-			const dictString = ref("")
-			if(workOrderStatus.value != 'to_finish') {
-				dictString.value = "gxt_accept_return_type"
-			} else {
-				dictString.value = "gxt_return_type"
-			}
-
-	        const result = await getDictDataByType(dictString.value)
-	        const resultObj = result as UTSJSONObject
-
-	        if (resultObj['code'] == 200) {
-				const data = resultObj['data'] as any[]
-				const options: PickerOption[] = []
-	            if (data.length > 0) {
-	                for (let i = 0; i < data.length; i++) {
-	                    const item = data[i] as UTSJSONObject
-	                    let dictItem: SysDictData = {
-							dictValue: item['dictValue'] as string | null,
-							dictLabel: item['dictLabel'] as string | null,
-							dictCode: null,
-							dictSort: null,
-							dictType: null,
-							cssClass: null,
-							listClass: null,
-							isDefault: null,
-							status: null,
-							default: null,
-							createTime: null,
-							remark: null
-	                    }
-						// 构建选择器选项
-						options.push({
-							label: dictItem.dictLabel ?? '',
-							value: dictItem.dictValue ?? ''
-						})
-	                }
-	            }
-
-				returnTypeOptions.value = options
-	        }
-	    } catch (e: any) {
-	        console.error('获取挂起原因失败:', e.message)
-	    }
-	}
-
 	// 手动选择负责人
 	const selectLeaderManually = (user: UTSJSONObject, index: number): void => {
 	    selectedTeamLeaderIndex.value = index
@@ -666,7 +718,7 @@
             workGroupMemberName.value = '';
         }
     };
-	
+
 	// 工作票编号变化处理
 	const handleWorkPermitNumChange = async(): Promise<void> => {
 	    if (infoEntry.value == '2') {
@@ -776,7 +828,7 @@
 					teamLeaderId.value = (leaderPerson['userId'] as Number | null) ?? null
 					teamLeaderName.value = (leaderPerson['nickName'] as string | null) ?? ''
 				}
-				
+
 				const nickNames = rows
 					.filter(person => person.isLeader != 1)
 					.map(person => (person.nickName as string | null) ?? '')
@@ -833,7 +885,7 @@
 	    userKeyword.value = "";
 		userList.value = userAllList.value
 	};
-	
+
 	// 搜索工作负责人
 	const handleSearch = (): void => {
 		const keyword = teamKeyword.value
@@ -842,7 +894,7 @@
 			return nickName != null && nickName.indexOf(keyword) >= 0
 		})
 	}
-	
+
 	// 清空搜索工作负责人
 	const clearSearch = (): void => {
 		teamKeyword.value = ""
@@ -871,6 +923,17 @@
 	  realEndTime.value = value
 	  showEndTimePicker.value = false
 	}
+	
+	function onResumeTimeConfirm(value: string) {
+	  // 检查新的结束时间是否小于开始时间
+	  if (resumeTime.value != '' && new Date(realStartTime.value as string) > new Date(value)) {
+	    uni.showToast({ title: '结束时间不能小于开始时间', icon: 'none' })
+	    return
+	  }
+	
+	  resumeTime.value = value
+	  showResumeTimePicker.value = false
+	}
 
     // 检查用户是否已被选中
     const isSelected = (user: UTSJSONObject): boolean => {
@@ -1013,7 +1076,7 @@
             });
             return false;
         }
-		
+
 		if (teamLeaderName.value == '') {
 		    uni.showToast({
 		        title: '请选择工作负责人',
@@ -1021,7 +1084,7 @@
 		    });
 		    return false;
 		}
-		
+
 		if (workGroupMemberName.value == '') {
 		    uni.showToast({
 		        title: '请选择工作班成员',
@@ -1029,6 +1092,47 @@
 		    });
 		    return false;
 		}
+		
+		if(resumeShow.value) {
+			if(resumeTime.value == '') {
+				uni.showToast({
+				    title: '请选挂起结束时间',
+				    icon: 'none'
+				});
+				return false;
+			} else {
+				const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+				if (suspendTime != '' && realStartTime.value != '' && new Date(suspendTime) < new Date(realStartTime.value)) { // 开工前挂起
+				  if (resumeTime.value != '' && new Date(resumeTime.value) > new Date(realStartTime.value)) {
+					uni.showToast({
+					    title: '开工前挂起结束时间晚于实际开始时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  } else if(realEndTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value) > new Date(realEndTime.value)) {
+					uni.showToast({
+					    title: '开工前挂起结束时间晚于实际结束时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  }
+				} else if(suspendTime != '' && realStartTime.value != '' && new Date(suspendTime) >= new Date(realStartTime.value)) { // 作业中挂起
+				  if (resumeTime.value != '' && new Date(resumeTime.value) < new Date(realStartTime.value)) {
+					uni.showToast({
+					    title: '作业中挂起结束时间早于实际开始时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  } else if(realEndTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value) > new Date(realEndTime.value)) {
+					uni.showToast({
+					    title: '作业中挂起结束时间晚于实际结束时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  }
+				}
+			}
+		}
 
         return true;
     };
@@ -1047,6 +1151,12 @@
 			isDealing.value = true
 	        // 确保附件URLs是最新的逗号分隔格式
 	        attachmentUrls.value = uploadedFiles.value.map(file => file.fileName).join(',');
+			
+			flowList.value = []
+			if (resumeTime.value != '' && resumeInfo.value != null && resumeTime.value != (resumeInfo.value['actionTime'] as string | null)) { //存入新的挂起结束时间
+				resumeInfo.value['actionTime'] = resumeTime.value
+				flowList.value.push(resumeInfo.value as UTSJSONObject)
+			}
 
 	        const finishData = {
 	            id: orderId.value,
@@ -1066,7 +1176,8 @@
 				teamLeaderId: teamLeaderId.value,
 				teamLeaderName: teamLeaderName.value,
 				finalizeMethod: '2',
-				workOrderStatus: 'completed'
+				workOrderStatus: 'completed',
+				workOrderFlowList: flowList.value
 	        } as UTSJSONObject;
 
 	        const result = await finishOrder(finishData);
@@ -1144,6 +1255,7 @@
 				teamLeaderName.value = (data['teamLeaderName'] as string | null) ?? ''
 				returnType.value = workOrderStatus.value == 'to_finish' ? '1' : ''
 				content.value = (data['content'] as string | null) ?? ''
+				suspendReason.value = (data['suspendReason'] as string | null) ?? ''
 				// 初始化附件数据
 				const attachmentUrlsFromServer = (data['attachmentUrls'] as string | null) ?? ''
 				if (attachmentUrlsFromServer.length > 0) {
@@ -1260,20 +1372,22 @@
 						icon: 'none'
 					});
 				}
-
-				// await dictList()
-				if (returnTypeOptions.value.length > 0 && workOrderStatus.value == 'to_finish') {
-					// returnTypeLabel.value = returnTypeOptions.value[0].label
-					// 循环匹配
-				    for (const option of returnTypeOptions.value) {
-						// 严格匹配value
-						if (returnType.value == option.value) {
-						  returnTypeLabel.value = option.label;
-						  break; // 匹配成功后跳出循环,提升性能
-						}
-					}
+				
+				flowList.value = data['workOrderFlowList'] as UTSJSONObject[]
+				if (suspendReason.value != '' && flowList.value.length > 0) {
+				  // 获取最后一个 actionType 等于 'resume' 的项
+				  const lastResumeItem = flowList.value.findLast(item => item['actionType'] === 'resume') as UTSJSONObject | null
+				  if (lastResumeItem != null) {
+					resumeInfo.value = lastResumeItem
+					// 直接给 resumeTime 赋值,无需 formData
+					resumeTime.value = (lastResumeItem['actionTime'] as string | null) ?? ''
+				  }
+							
+				  const lastSuspendItem = flowList.value.findLast(item => (item['actionType'] as string | null) === 'to_approve') as UTSJSONObject | null
+				  if (lastSuspendItem != null) {
+					suspendInfo.value = lastSuspendItem
+				  }
 				}
-
             } else {
                 const msg = resultObj['msg'] as string | null
                 uni.showToast({
@@ -1600,6 +1714,11 @@
 	    border-bottom: none;
 	}
 
+	.info-row {
+	  flex-direction: row;
+	  justify-content: space-between;
+	  align-items: center;
+	}
 
 	.option-text {
 	    font-size: 28rpx;
@@ -1625,26 +1744,6 @@
 		color: #999;
 	}
 
-	.picker-option {
-	    flex-direction: row;
-	    justify-content: space-between;
-	    align-items: center;
-	    padding: 24rpx 30rpx;
-	    border-bottom: 1rpx solid #f0f0f0;
-	}
-
-	.picker-option:last-child {
-	    border-bottom: none;
-	}
-
-	.picker-option.selected {
-	    background-color: #f8f9fa;
-	}
-
-	.option-text {
-	    font-size: 28rpx;
-	    color: #333333;
-	}
 
 	.mis-list {
     flex: 1;
@@ -1653,17 +1752,6 @@
     flex-direction: column;
 }
 
-	.empty-tip {
-	    text-align: center;
-	    padding: 40rpx;
-	    color: #999;
-	    font-size: 28rpx;
-	}
-
-
-
-
-
 .form-item {
 	flex-direction: row;
 	padding: 20rpx 0;

+ 228 - 86
pages/order/detail/wxFinalize.uvue

@@ -123,7 +123,7 @@
 								    class="input-field"
 								    placeholder="请选择开始时间"
 								    v-model="realStartTime"
-									:disabled="true"
+									type="none"
 									style="pointer-events: none;"
 								/>
                             </view>
@@ -141,7 +141,7 @@
 								    class="input-field"
 								    placeholder="请选择结束时间"
 								    v-model="realEndTime"
-									:disabled="true"
+									type="none"
 
 								/>
 								<!-- <text class="input-field">
@@ -150,11 +150,29 @@
                             </view>
                         </view>
                     </view>
+					
+					<!-- 挂起结束时间 -->
+					<view class="info-item" v-if="resumeInfo != null && resumeShow">
+					    <view class="info-label">
+					        <text class="form-label required">挂起结束时间<text style="color: red;">*</text></text>
+					    </view>
+					    <view class="info-value">
+					        <view class="form-picker" @click="showResumeTimePicker = true">
+								<input
+								    class="input-field"
+								    placeholder="请选择挂起结束时间"
+								    v-model="resumeTime"
+									type="none"
+					
+								/>
+					        </view>
+					    </view>
+					</view>
 
                     <!-- 工作部位 -->
                     <view class="info-item">
                         <view class="info-label">
-                            <text class="form-label">工作部位</text>
+                            <text class="form-label">工作部位<text style="color: red;">*</text></text>
                         </view>
                         <view class="info-value">
                             <view class="form-picker" @click="showWorkAreaPicker = true">
@@ -231,7 +249,7 @@
                                     @click="showUserSelect = true"
                                     :disabled="infoEntry == '1'"
                                 />
-                                <text class="select-users-count" v-if="selectedUserIds.length > 0" :style="{ marginRight: selectedUserIds.length > 0 ? '60rpx' : '0' }">({{ selectedUserIds.length }}人)</text>
+                                <!-- <text class="select-users-count" v-if="selectedUserIds.length > 0" :style="{ marginRight: selectedUserIds.length > 0 ? '60rpx' : '0' }">({{ selectedUserIds.length }}人)</text> -->
                                 <text class="select-clear" v-if="selectedUserIds.length > 0" @click="clearSelectedUsers">×</text>
                             </view>
                         </view>
@@ -292,13 +310,26 @@
 					title="选择结束时间"
 					:mode="31"
 					format="YYYY-MM-DD HH:mm"
-					:modelValue="realStartTime"
+					:modelValue="realEndTime"
 					confirm-btn="确定"
 					cancel-btn="取消"
 					@confirm="onEndDateConfirm"
 					@cancel="showEndTimePicker = false">
 				</l-date-time-picker>
 			</l-popup>
+			
+			<l-popup v-model="showResumeTimePicker" position="bottom" :safe-area-inset-bottom="true" :z-index="10000">
+				<l-date-time-picker
+					title="选择挂起结束时间"
+					:mode="31"
+					format="YYYY-MM-DD HH:mm"
+					:modelValue="resumeTime"
+					confirm-btn="确定"
+					cancel-btn="取消"
+					@confirm="onResumeTimeConfirm"
+					@cancel="showResumeTimePicker = false">
+				</l-date-time-picker>
+			</l-popup>
 
             <!-- 人员选择弹窗 -->
             <view v-if="showUserSelect" class="picker-modal">
@@ -357,10 +388,15 @@
 								class="picker-option"
 								@click="selectMisItem(item, index)"
 							>
-								<!-- <text class="option-text">{{ option.label }}</text>
-								<text class="option-text">{{ option.value }}</text> -->
-								<text class="option-text">{{ ((item['misNo'] as string | null) ?? '-')}}</text>
-								<text class="option-text">{{ item['workPermitNum'] as string | null ?? '-' }}</text>
+								<!-- <text class="option-text">{{ option.label }}</text> -->
+								<view> 
+									<text class="option-text">MIS工单编码</text>
+									<text class="option-text">工作票编号</text>
+								</view>
+								<view> 	
+									<text class="option-text">{{ ((item['misNo'] as string | null) ?? '-')}}</text>
+									<text class="option-text">{{ item['workPermitNum'] as string | null ?? '-' }}</text>
+								</view>
 								<text v-if="index === selectedMisInfoIndex" class="option-check">✓</text>
 							</view>
 						</view>
@@ -447,7 +483,7 @@
 </template>
 
 <script setup lang="uts">
-    import { ref } from 'vue'
+    import { ref, watch } from 'vue'
     import type { acceptOrderInfo } from '../../../types/order'
     import type { WorkOrderFlow } from '../../../types/flow'
     import { getOrderInfoById, getRepairOrderInfoById, returnRepairOrder, repairFinishOrder } from '../../../api/order/detail'
@@ -483,6 +519,13 @@
 	const faultCode = ref<string>('')
 	const faultBarcode = ref<string>('')
 	const faultDesc = ref<string>('')
+	const suspendReason = ref<string>('') // 挂起原因
+	const flowList = ref<UTSJSONObject[]>([]) //流转过程
+	const suspendInfo = ref<UTSJSONObject | null>(null)
+	const resumeInfo = ref<UTSJSONObject | null>(null)
+	const resumeShow = ref<boolean>(false)
+	const resumeTime = ref<string>('') // 挂起结束时间
+	const showResumeTimePicker = ref<boolean>(false)
 
 	// 添加字典加载状态
 	const dictLoaded = ref<boolean>(false)
@@ -498,7 +541,7 @@
     const workGroupMemberName = ref<string>('') // 工作班成员
     const attachmentUrls = ref<string>('') // 附件URLs(逗号分隔的字符串格式)
     const uploadedFiles = ref<UploadResponse[]>([]) // 上传的文件对象数组
-	const workOrderPersonList = ref<UTSJSONObject[]>([]) // 工作班成员数组
+	const repairOrderPersonList = ref<UTSJSONObject[]>([]) // 工作班成员数组
 	const selectedUserIds = ref<string[]>([]) // 选中的用户ID数组
 	const selectedUsers = ref<UTSJSONObject[]>([]) // 选中的用户对象数组
 	const realFailureReason = ref<string>('') //真实故障原因
@@ -524,6 +567,68 @@
     const endTimeDate = ref<string>('')
     const endTimeTime = ref<string>('')
 
+    // 监听开始时间和结束时间变化
+    watch(realStartTime, (value: string) => {
+        console.log('开始时间变化:', value)
+        // 在这里添加开始时间变化时的处理逻辑
+        if (resumeInfo.value != null && value != '') {
+            const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+            if (suspendTime != '' && value != '') {
+                const suspendDate = new Date(suspendTime)
+                const startDate  = new Date(value)
+                if (suspendDate.getTime() < startDate.getTime()) { // 开工前挂起
+                    const resumeDate = new Date(resumeTime.value)
+                    const endDate    = new Date(realEndTime.value)
+                    if (resumeDate.getTime() > startDate.getTime() || (realEndTime.value != '' && resumeDate.getTime() > endDate.getTime())) {
+                        resumeShow.value = true
+                    } else {
+                        resumeShow.value = false
+                    }
+                } else if (suspendDate.getTime() >= startDate.getTime()) { // 作业中挂起
+                    const resumeDate = new Date(resumeTime.value)
+                    const endDate    = new Date(realEndTime.value)
+                    if (resumeDate.getTime() < startDate.getTime() || (realEndTime.value != '' && resumeDate.getTime() > endDate.getTime())) {
+                        resumeShow.value = true
+                    } else {
+                        resumeShow.value = false
+                    }
+                } else {
+                    resumeShow.value = false
+                }
+            } else {
+                resumeShow.value = false
+            }
+        }
+    })
+
+    watch(realEndTime, (value: string) => {
+        console.log('结束时间变化:', value)
+        // 在这里添加结束时间变化时的处理逻辑
+		if (resumeInfo.value != null && value != '') {
+		    const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+		    if (suspendTime != '' && realStartTime.value != '' && new Date(suspendTime).getTime() < new Date(realStartTime.value).getTime()) { // 开工前挂起
+		      if (value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(realStartTime.value).getTime()) {
+		        resumeShow.value = true
+		      } else if(value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(value).getTime()) {
+		        resumeShow.value = true
+		      } else {
+		        resumeShow.value = false
+		      }
+		
+		    } else if(suspendTime != '' && realStartTime.value != '' && new Date(suspendTime).getTime() >= new Date(realStartTime.value).getTime()) { // 作业中挂起
+		      if (realStartTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() < new Date(realStartTime.value).getTime()) {
+		        resumeShow.value = true
+		      } else if(value != '' && resumeTime.value != '' && new Date(resumeTime.value).getTime() > new Date(value).getTime()) {
+		        resumeShow.value = true
+		      } else {
+		        resumeShow.value = false
+		      }
+		    } else {
+		      resumeShow.value = false
+		    }
+		  }
+    })
+
     // MIS工单选择相关变量
     const showMisNoQuickSelect = ref<boolean>(false)
     const quickMisNoList = ref<UTSJSONObject[]>([])
@@ -689,59 +794,6 @@
 	    value: string
 	}
 
-	// 选中的挂起原因
-
-	const returnTypeOptions = ref<PickerOption[]>([])
-	const showReasonPicker = ref<boolean>(false)
-
-	// 获取负责人列表(使用用户列表接口)
-	const dictList = async (): Promise<void> => {
-	    try {
-			const dictString = ref("")
-			if(workOrderStatus.value != 'to_finish') {
-				dictString.value = "gxt_accept_return_type"
-			} else {
-				dictString.value = "gxt_return_type"
-			}
-
-	        const result = await getDictDataByType(dictString.value)
-	        const resultObj = result as UTSJSONObject
-
-	        if (resultObj['code'] == 200) {
-				const data = resultObj['data'] as any[]
-				const options: PickerOption[] = []
-	            if (data.length > 0) {
-	                for (let i = 0; i < data.length; i++) {
-	                    const item = data[i] as UTSJSONObject
-	                    let dictItem: SysDictData = {
-							dictValue: item['dictValue'] as string | null,
-							dictLabel: item['dictLabel'] as string | null,
-							dictCode: null,
-							dictSort: null,
-							dictType: null,
-							cssClass: null,
-							listClass: null,
-							isDefault: null,
-							status: null,
-							default: null,
-							createTime: null,
-							remark: null
-	                    }
-						// 构建选择器选项
-						options.push({
-							label: dictItem.dictLabel ?? '',
-							value: dictItem.dictValue ?? ''
-						})
-	                }
-	            }
-
-				returnTypeOptions.value = options
-	        }
-	    } catch (e: any) {
-	        console.error('获取挂起原因失败:', e.message)
-	    }
-	}
-
 	// 手动选择负责人
 	const selectLeaderManually = (user: UTSJSONObject, index: number): void => {
 		selectedTeamLeaderIndex.value = index
@@ -869,7 +921,7 @@
 		await listWorkPerson(misNo.value).then(response => {
 			const responseObj = response as UTSJSONObject
 			const rows = responseObj['rows'] as UTSJSONObject[] | null
-			workOrderPersonList.value = rows ?? []
+			repairOrderPersonList.value = rows ?? []
 			if (rows != null && rows.length > 0) {
 				// 查找 isLeader 等于 1 的负责人(优先获取第一个符合条件的,贴合常规单负责人场景)
 				const leaderPerson = rows.find(person => person.isLeader == 1);
@@ -972,6 +1024,17 @@
 	  realEndTime.value = value
 	  showEndTimePicker.value = false
 	}
+	
+	function onResumeTimeConfirm(value: string) {
+	  // 检查新的结束时间是否小于开始时间
+	  if (resumeTime.value != '' && new Date(realStartTime.value as string) > new Date(value)) {
+	    uni.showToast({ title: '结束时间不能小于开始时间', icon: 'none' })
+	    return
+	  }
+	
+	  resumeTime.value = value
+	  showResumeTimePicker.value = false
+	}
 
     // 检查用户是否已被选中
     const isSelected = (user: UTSJSONObject): boolean => {
@@ -1045,8 +1108,8 @@
 
         workGroupMemberName.value = nickNames;
 
-        // 更新workOrderPersonList为选中的用户
-        workOrderPersonList.value = [...selectedUsers.value];
+        // 更新repairOrderPersonList为选中的用户
+        repairOrderPersonList.value = [...selectedUsers.value];
 
         showUserSelect.value = false;
     };
@@ -1061,7 +1124,7 @@
         workGroupMemberName.value = '';
 
         // 清空工作班成员列表
-        workOrderPersonList.value = [];
+        repairOrderPersonList.value = [];
     };
 
     // 检查工作部位是否已被选中
@@ -1169,6 +1232,53 @@
 		    });
 		    return false;
 		}
+		if (workArea.value == '') {
+		    uni.showToast({
+		        title: '请选择工作部位',
+		        icon: 'none'
+		    });
+		    return false;
+		}
+		if(resumeShow.value) {
+			if(resumeTime.value == '') {
+				uni.showToast({
+				    title: '请选挂起结束时间',
+				    icon: 'none'
+				});
+				return false;
+			} else {
+				const suspendTime = (suspendInfo.value?.['actionTime'] as string | null) ?? ''
+				if (suspendTime != '' && realStartTime.value != '' && new Date(suspendTime) < new Date(realStartTime.value)) { // 开工前挂起
+				  if (resumeTime.value != '' && new Date(resumeTime.value) > new Date(realStartTime.value)) {
+					uni.showToast({
+					    title: '开工前挂起结束时间晚于实际开始时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  } else if(realEndTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value) > new Date(realEndTime.value)) {
+					uni.showToast({
+					    title: '开工前挂起结束时间晚于实际结束时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  }
+				} else if(suspendTime != '' && realStartTime.value != '' && new Date(suspendTime) >= new Date(realStartTime.value)) { // 作业中挂起
+				  if (resumeTime.value != '' && new Date(resumeTime.value) < new Date(realStartTime.value)) {
+					uni.showToast({
+					    title: '作业中挂起结束时间早于实际开始时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  } else if(realEndTime.value != '' && resumeTime.value != '' && new Date(resumeTime.value) > new Date(realEndTime.value)) {
+					uni.showToast({
+					    title: '作业中挂起结束时间晚于实际结束时间,请调整',
+					    icon: 'none'
+					});
+					return false;
+				  }
+				}
+			}
+		}
 
         return true;
     };
@@ -1187,13 +1297,19 @@
 			isDealing.value = true
 	        // 确保附件URLs是最新的逗号分隔格式
 	        attachmentUrls.value = uploadedFiles.value.map(file => file.fileName).join(',');
-
+			
+			flowList.value = []
+			if (resumeTime.value != '' && resumeInfo.value != null && resumeTime.value != (resumeInfo.value['actionTime'] as string | null)) { //存入新的挂起结束时间
+				resumeInfo.value['actionTime'] = resumeTime.value
+				flowList.value.push(resumeInfo.value as UTSJSONObject)
+			}
+	
 	        const finishData = {
 	            id: orderId.value,
 	            orderType: orderType.value,
 	            workOrderProjectNo: workOrderProjectNo.value,
 	            infoEntry: infoEntry.value,
-	            misNo: infoEntry.value == '1' ? misNo.value : null,
+	            misOrderNo: infoEntry.value == '1' ? misNo.value : null,
 	            workPermitNum: workPermitNum.value,
 	            realStartTime: realStartTime.value,
 	            realEndTime: realEndTime.value,
@@ -1202,12 +1318,13 @@
 	            workGroupMemberName: workGroupMemberName.value,
 	            realFailureReason: realFailureReason.value,
 	            attachmentUrls: attachmentUrls.value,
-				workOrderPersonList: workOrderPersonList.value,
+				repairOrderPersonList: repairOrderPersonList.value,
 				teamLeaderId: teamLeaderId.value,
 				teamLeaderName: teamLeaderName.value,
 				finalizeMethod: '2',
 				workOrderStatus: 'completed',
 				workArea: workArea.value,
+				repairOrderFlowList: flowList.value,
 				repairMethod: '1'
 	        } as UTSJSONObject;
 
@@ -1288,6 +1405,7 @@
 				faultCode.value = (data['faultCode'] as string | null) ?? ''
 				faultBarcode.value = (data['faultBarcode'] as string | null) ?? ''
 				faultDesc.value = (data['faultDesc'] as string | null) ?? ''
+				suspendReason.value = (data['suspendReason'] as string | null) ?? ''
 				// 初始化附件数据
 				const attachmentUrlsFromServer = (data['attachmentUrls'] as string | null) ?? ''
 				if (attachmentUrlsFromServer.length > 0) {
@@ -1354,10 +1472,10 @@
 									await listWorkPerson(misNo.value).then(response => {
 										const responseObj = response as UTSJSONObject
 										const rows = responseObj['rows'] as UTSJSONObject[] | null
-										workOrderPersonList.value = rows ?? []
+										repairOrderPersonList.value = rows ?? []
 										if (rows != null && rows.length > 0) {
 											// 查询负责人信息并回填
-											for (const person of workOrderPersonList.value) {
+											for (const person of repairOrderPersonList.value) {
 											  // 严格判断isLeader为1(兼容数字/字符串类型)
 											  if (person.isLeader == 1) {
 												teamLeaderName.value = (person.nickName as string | null) ?? '';
@@ -1404,20 +1522,23 @@
 						icon: 'none'
 					});
 				}
-
-				// await dictList()
-				if (returnTypeOptions.value.length > 0 && workOrderStatus.value == 'to_finish') {
-					// returnTypeLabel.value = returnTypeOptions.value[0].label
-					// 循环匹配
-				    for (const option of returnTypeOptions.value) {
-						// 严格匹配value
-						if (returnType.value == option.value) {
-						  returnTypeLabel.value = option.label;
-						  break; // 匹配成功后跳出循环,提升性能
-						}
-					}
+				
+				flowList.value = data['repairOrderFlowList'] as UTSJSONObject[]
+				if (suspendReason.value != '' && flowList.value.length > 0) {
+				  // 获取最后一个 actionType 等于 'resume' 的项
+				  const lastResumeItem = flowList.value.findLast(item => item['actionType'] === 'resume') as UTSJSONObject | null
+				  if (lastResumeItem != null) {
+					resumeInfo.value = lastResumeItem
+					// 直接给 resumeTime 赋值,无需 formData
+					resumeTime.value = (lastResumeItem['actionTime'] as string | null) ?? ''
+				  }
+			
+				  const lastSuspendItem = flowList.value.findLast(item => (item['actionType'] as string | null) === 'to_approve') as UTSJSONObject | null
+				  if (lastSuspendItem != null) {
+					suspendInfo.value = lastSuspendItem
+				  }
+			
 				}
-
             } else {
                 const msg = resultObj['msg'] as string | null
                 uni.showToast({
@@ -1785,6 +1906,27 @@
 	.picker-option.selected {
 	    background-color: #f8f9fa;
 	}
+	
+	
+	.picker-mis-option {
+	    justify-content: space-between;
+	    align-items: center;
+	    padding: 24rpx 30rpx;
+	    border-bottom: 1rpx solid #f0f0f0;
+	}
+	
+	.picker-mis-option:last-child {
+	    border-bottom: none;
+	}
+	
+	.picker-mis-option.selected {
+	    background-color: #f8f9fa;
+	}
+	.option-row {
+		flex-direction: row;
+		justify-content: space-around;
+		align-items: center;
+	}
 
 	.option-text {
 	    font-size: 28rpx;

+ 8 - 5
pages/profile/index.uvue

@@ -7,7 +7,7 @@
             <!-- 用户信息头部 -->
             <view class="header">
                 <image class="avatar" src="/static/images/login/2.png" mode="aspectFill"></image>
-                <text class="user-name">{{ userName }}</text>
+                <text class="user-name">{{ nickName }}({{ userName }})</text>
             </view>
 
             <!-- 信息卡片区域 -->
@@ -80,6 +80,7 @@
     const userDept = ref<string>('')
 	const userRole = ref<string>('')
     const isNewVersion = ref<boolean>(false)
+	const nickName = ref<string>('')
 	
     // 版本信息
     const manifestVersion = manifest.versionName as string | null
@@ -333,18 +334,20 @@
 		checkVersion();
         const userInfo = getUserInfo()
         if (userInfo != null) {
-			
-            const nickName = userInfo['nickName'] as string | null
+            const nickNameRaw = userInfo['nickName'] as string | null
 			const phone = userInfo['phone'] as string | null
+			const userNameRaw = userInfo['userName'] as string | null
 			
 			const isKey = getStoreIsKey();
 			if(isKey == "1"){
-				userName.value = decryptAES(nickName ?? '')
+				userName.value = decryptAES(userNameRaw ?? '')
+				nickName.value = decryptAES(nickNameRaw ?? '')
 				if (phone != null && phone.length > 0) {
 					userPhone.value = decryptAES(phone ?? '')
 				}
 			}else{
-				userName.value = nickName ?? ''
+				userName.value = userNameRaw ?? ''
+				nickName.value = nickNameRaw ?? ''
 				if (phone != null && phone.length > 0) {
 					userPhone.value = phone
 				}

+ 3 - 1
utils/request.uts

@@ -14,9 +14,11 @@ export type RequestConfig = {
 
 // 基础 URL
 // const BASE_URL = "http://192.168.110.105:8080";
-const BASE_URL = "http://222.243.138.146:5095" //测试服务器;
+// const BASE_URL = "http://222.243.138.146:5095" //测试服务器;
 	// const BASE_URL = "http://222.243.138.146:5097" //正式服务器;
 // const BASE_URL = "http://10.170.129.135:8089";
+const BASE_URL = "http://222.243.138.146:5096/prod-api"
+// const BASE_URL = "http://10.170.129.135/prod-api";
 
 /**
  * 获取基础 URL