Prechádzať zdrojové kódy

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

wuhb 2 mesiacov pred
rodič
commit
c92d1a8ac6

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

@@ -278,15 +278,15 @@
 		} else if(item.workOrderStatus == 'to_finish') {
 			showTime.value = item.acceptTime
 		} else if(item.workOrderStatus == 'to_approve') {
-			showTime.value = item.updateTime
+			showTime.value = item.updateTime?.slice(0, -3) ?? ''
 		} else if(item.workOrderStatus == 'suspended') {
-			showTime.value = item.updateTime
+			showTime.value = item.updateTime?.slice(0, -3) ?? ''
 		} else if(item.workOrderStatus == 'return' || item.workOrderStatus == 'accept_return') {
-			showTime.value = item.updateTime
+			showTime.value = item.updateTime?.slice(0, -3) ?? ''
 		} else if(item.workOrderStatus == 'completed') {
-			showTime.value = item.updateTime
+			showTime.value = item.updateTime?.slice(0, -3) ?? ''
 		} else if(item.workOrderStatus == "archived") {
-			showTime.value = item.updateTime
+			showTime.value = item.updateTime?.slice(0, -3) ?? ''
 		} else {
 			if (item.createTime != null && item.createTime.length >= 3) {
 			  showTime.value = item.createTime.slice(0, -3);

+ 3 - 1
pages/order/index.uvue

@@ -657,6 +657,7 @@ const canHandleOrder = (item: any | null, buttonType: string | ''): boolean => {
 			// 结单
 			permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:complete'] : ['gxt:repairOrder:finalize']
 		} else if(buttonType != '' && buttonType == "shutdown" && orderItem.orderType == 2) {
+			// 停机
 			permit = ['gxt:maintenance:order:shutdown']
 		} else if(buttonType != '' && buttonType == "restart") {
 			// 复运
@@ -678,6 +679,7 @@ const canHandleOrder = (item: any | null, buttonType: string | ''): boolean => {
 		// 停机
 		permit = ['gxt:maintenance:order:shutdown']
 	} else if(orderItem.workOrderStatus == 'completed') {
+		// 复运
 		permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:restart'] : ['gxt:repairOrder:restart']
 	} else {
 		return false
@@ -721,7 +723,7 @@ const canHandleOrder = (item: any | null, buttonType: string | ''): boolean => {
 			}
 		} else if(orderItem.workOrderStatus == 'to_finish') {
 			if(buttonType != '' && buttonType == "suspend") {
-				// 跳转到待结单页面
+				// 跳转到待挂起页面
 				uni.navigateTo({
 					url: `/pages/order/detail/suspendIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
 				})

+ 80 - 23
pages/order/pendingOrder.uvue

@@ -41,13 +41,21 @@
 								<text class="btn-text">接单</text>
 							</view>
 							<view
-								v-if="(getOrderStatus(item) == 'assigned' || getOrderStatus(item) == 'to_finish') 
+								v-if="(getOrderStatus(item) == 'assigned' || getOrderStatus(item) == 'to_finish')
 								&& canHandleOrder(item,'shutdown') && (item as acceptOrderInfoExtend).pauseTime == null"
 								class="btn-primary info-value"
 								@click.stop="handleItemClick(item,'shutdown')"
 								>
 								<text class="btn-text">停机</text>
 							</view>
+							<view
+								v-if="(getOrderStatus(item) == 'assigned' || getOrderStatus(item) == 'to_finish' || getOrderStatus(item) == 'completed')
+								&& canHandleOrder(item,'restart') && (item as acceptOrderInfoExtend).restartTime == null"
+								class="btn-primary info-value"
+								@click.stop="handleItemClick(item,'restart')"
+								>
+								<text class="btn-text">复运</text>
+							</view>
 							<view
 								v-if="getOrderStatus(item) == 'to_approve' && canHandleOrder(item,'')"
 								class="btn-primary info-value"
@@ -76,13 +84,20 @@
 								>
 								<text class="btn-text">退回</text>
 							</view>
-							<!-- <view
+							<view
 								v-if="getOrderStatus(item) == 'to_finish' && canHandleOrder(item, 'return')"
 								class="btn-primary info-value"
 								@click.stop="handleItemClick(item, 'return')"
 								>
 								<text class="btn-text">退回</text>
-							</view> -->
+							</view>
+							<view
+								v-if="getOrderStatus(item) == 'to_finish' && canHandleOrder(item, 'complete')"
+								class="btn-primary info-value"
+								@click.stop="handleItemClick(item, 'complete')"
+								>
+								<text class="btn-text">结单</text>
+							</view>
 							<view
 								v-if="getOrderStatus(item) == 'to_finish' && canHandleOrder(item, 'suspend')"
 								class="btn-primary info-value"
@@ -140,6 +155,7 @@ type acceptOrderInfoExtend = {
   workEndTime: string | null
   orderEntryType: string | null
   pauseTime: string | null
+  restartTime: string | null
 }
 
 	const userId = ref<string>("")
@@ -184,9 +200,12 @@ type acceptOrderInfoExtend = {
 			} else if(buttonType != '' && buttonType == "accept") {
 				// 接单
 				permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:accept'] : ['gxt:repairOrder:accept']
-			}  else if(buttonType != '' && buttonType == "shutdown" && orderItem.orderType == 2) {
+			} else if(buttonType != '' && buttonType == "shutdown" && orderItem.orderType == 2) {
 				permit = ['gxt:maintenance:order:shutdown']
-			} 
+			} else if(buttonType != '' && buttonType == "restart") {
+				// 复运
+				permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:restart'] : ['gxt:repairOrder:restart']
+			}
 	  } else if(orderItem.workOrderStatus == 'to_finish') {
 	  		if(buttonType != '' && buttonType == "suspend" && (orderItem.teamLeaderId == parseInt(userId.value) || roles.value.includes("管理员"))) {
 	  			// 挂起
@@ -197,24 +216,33 @@ type acceptOrderInfoExtend = {
 	  		} else if(buttonType != '' && buttonType == "finalize" && orderItem.orderType == 1 && (orderItem.teamLeaderId == parseInt(userId.value) || roles.value.includes("管理员"))) {
 	  			// 复启
 	  			permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:finalize'] : ['gxt:repairOrder:finalize']
-	  		} else if(buttonType != '' && buttonType == "shutdown" && orderItem.orderType == 2) {
-			    permit = ['gxt:maintenance:order:shutdown']
+	  		} else if(buttonType != '' && buttonType == "complete") {
+				// 结单
+				permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:complete'] : ['gxt:repairOrder:finalize']
+			} else if(buttonType != '' && buttonType == "shutdown" && orderItem.orderType == 2) {
+			    // 停机
+				permit = ['gxt:maintenance:order:shutdown']
+			} else if(buttonType != '' && buttonType == "restart") {
+				// 复运
+				permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:restart'] : ['gxt:repairOrder:restart']
 			}
-	  } else if(orderItem.workOrderStatus == 'to_approve') {
-	  	// 审批
-	  	permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:approve'] : ['gxt:repairOrder:approve']
-	  } else if(orderItem.workOrderStatus == 'suspended' && (orderItem.teamLeaderId == parseInt(userId.value) || roles.value.includes("管理员"))) {
-	  	// 恢复
-	  	permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:resume'] : ['gxt:repairOrder:resume']
-	  } else if(orderItem.workOrderStatus == 'return') {
-	  	// 接单退回
-	  	permit = ['gxt:repairOrder:acceptReturn']
-	  }
-	   else {
-	  		  return false
-	  }
+		} else if(orderItem.workOrderStatus == 'to_approve') {
+			// 审批
+			permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:approve'] : ['gxt:repairOrder:approve']
+		} else if(orderItem.workOrderStatus == 'suspended' && (orderItem.teamLeaderId == parseInt(userId.value) || roles.value.includes("管理员"))) {
+			// 恢复
+			permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:resume'] : ['gxt:repairOrder:resume']
+		} else if(orderItem.workOrderStatus == 'return') {
+			// 接单退回
+			permit = ['gxt:repairOrder:acceptReturn']
+		} else if(orderItem.workOrderStatus == 'completed') {
+			// 复运
+			permit = orderItem.orderType == 2 ? ['gxt:maintenance:order:restart'] : ['gxt:repairOrder:restart']
+		} else {
+	  		return false
+		}
 	  // const orderType = (item as acceptOrderInfoExtend).orderType
-	  return checkPermi(permit)
+		return checkPermi(permit)
 	}
 
 	// 获取工单状态字典列表
@@ -344,7 +372,9 @@ type acceptOrderInfoExtend = {
 						rejectionReason: item['rejectionReason'] as string | null,
 						updateTime: item['updateTime'] as string | null,  // 新增字段
 						workEndTime: item['workEndTime'] as string | null,  // 新增字段
-						pauseTime: item['pauseTime'] as string | null
+						orderEntryType: item['orderEntryType'] as string | null,
+						pauseTime: item['pauseTime'] as string | null,
+						restartTime: item['restartTime'] as string | null
                     }
                     newData.push(orderItem)
                 }
@@ -579,6 +609,11 @@ type acceptOrderInfoExtend = {
 				uni.navigateTo({
 					url: `/pages/order/detail/shutdownIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
 				})
+			} else if(buttonType != '' && buttonType == "restart") {
+				// 跳转到复运页面
+				uni.navigateTo({
+					url: `/pages/order/detail/restartIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
+				})
 			} else {
 				// 跳转到接单页面
 				uni.navigateTo({
@@ -587,7 +622,7 @@ type acceptOrderInfoExtend = {
 			}
 		} else if(orderItem.workOrderStatus == 'to_finish') {
 			if(buttonType != '' && buttonType == "suspend") {
-				// 跳转到待结单页面
+				// 跳转到待挂起页面
 				uni.navigateTo({
 					url: `/pages/order/detail/suspendIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
 				})
@@ -606,6 +641,21 @@ type acceptOrderInfoExtend = {
 				uni.navigateTo({
 					url: `/pages/order/detail/shutdownIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
 				})
+			} else if(buttonType != '' && buttonType == "restart") {
+				// 跳转到复运页面
+				uni.navigateTo({
+					url: `/pages/order/detail/restartIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
+				})
+			} else if(buttonType != '' && buttonType == "complete" && orderItem.orderType == 2 && orderItem.orderEntryType == '1') {
+				// 跳转到结单页面
+				uni.navigateTo({
+					url: `/pages/order/detail/wbFinalize?id=${orderItem.id}&orderType=${orderItem.orderType}`
+				})
+			} else if(buttonType != '' && buttonType == "complete" && orderItem.orderType == 1) {
+				// 跳转到结单页面
+				uni.navigateTo({
+					url: `/pages/order/detail/wxFinalize?id=${orderItem.id}&orderType=${orderItem.orderType}`
+				})
 			}
 		} else if(orderItem.workOrderStatus == 'to_approve') {
 			// 跳转到待审批页面
@@ -622,6 +672,13 @@ type acceptOrderInfoExtend = {
 			uni.navigateTo({
 			    url: `/pages/order/detail/returnIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
 			})
+		} else if(orderItem.workOrderStatus == 'completed') {
+			if(buttonType != '' && buttonType == "restart") {
+				// 跳转到复运页面
+				uni.navigateTo({
+					url: `/pages/order/detail/restartIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
+				})
+			}
 		} else {
 			uni.navigateTo({
 				url: `/pages/order/detail/index?id=${orderItem.id}&orderType=${orderItem.orderType}`

+ 25 - 2
pages/score/detail/index.uvue

@@ -59,6 +59,14 @@
 					    <text class="info-label">故障描述</text>
 					    <text class="info-value">{{ detailData.faultDesc ?? '' }}</text>
 					</view>
+					<view class="info-item" v-if="detailData.orderType == 2">
+					    <text class="info-label">分项完成系数</text>
+					    <text class="info-value">{{ detailData.itemCompletionFactor ?? '' }}</text>
+					</view>
+					<view class="info-item" v-if="detailData.orderType == 2">
+					    <text class="info-label">分项完成系数和</text>
+					    <text class="info-value">{{ detailData.itemCompletionFactorSum ?? '' }}</text>
+					</view>
                 </view>
             </view>
 
@@ -98,6 +106,18 @@
 			      </view>
 			  </view>
 			
+			<!-- 修改理由 -->
+			<view class="info-section" v-if="detailData.modifyReason != null && detailData.modifyReason != ''">
+			     <view class="section-title">
+			         <text class="section-title-text">修改理由</text>
+			     </view>
+			     <view class="info-card">
+			         <view class="summary-content">
+			             <text class="summary-text">{{ detailData.modifyReason ?? '' }}</text>
+			         </view>
+			     </view>
+			 </view>
+			 
             <!-- 得分明细 -->
             <view class="info-section">
                 <view class="section-title">
@@ -188,6 +208,7 @@
 		faultCode: string | null
 		faultBarcode: string | null
 		faultDesc: string | null
+		modifyReason: string | null     // 修改理由
     }
     
     const detailData = reactive<DetailDataType>({
@@ -210,7 +231,8 @@
         scorePersonList: [],
 		faultCode: null,
 		faultBarcode: null,
-		faultDesc: null
+		faultDesc: null,
+		modifyReason: null     // 修改理由
     })
 
     const loading = ref<boolean>(false) 
@@ -481,7 +503,8 @@
 				detailData.faultCode = data.get('faultCode') as string | null
 				detailData.faultBarcode = data.get('faultBarcode') as string | null
 				detailData.faultDesc = data.get('faultDesc') as string | null
-                
+                detailData.modifyReason = data.get('modifyReason') as string | null
+				
                 if (scorePersonList != null) {
                     const processedList: ScorePersonItem[] = []
                     for (let i = 0; i < scorePersonList.length; i++) {

+ 133 - 43
pages/score/detail/reEvaluate.uvue

@@ -51,7 +51,19 @@
 		<view class="info-item" v-if="reEvaluationForm.orderType == '2'">
 		  <text class="info-label">分项完成系数和</text>
 		  <text class="info-value">{{ reEvaluationForm.itemCompletionFactorSum }}</text>
-		</view> 
+		</view>
+
+		<view class="info-item"  v-if="reEvaluationForm.orderType == '2'">
+           <text class="info-label">分项完成系数<text style="color: red;">*</text></text>
+           <input
+            class="info-input"
+            type="digit"
+            :value="getItemCompletionFactorDisplayValue()"
+            @input="onItemCompletionFactorInput"
+            @blur="formatItemCompletionFactor()"
+            placeholder="请输入分项完成系数"
+            />
+        </view>
       </view>
 
       <!-- 退回理由 -->
@@ -69,20 +81,9 @@
       </view> -->
 
       
-      <view class="info-card" v-if="reEvaluationForm.orderType == '2'">
-		  <view class="info-item">
-		    <text class="info-label">分项完成系数<text style="color: red;">*</text></text>
-		    <input 
-		  	class="info-input"
-		  	type="digit"
-		  	:value="getItemCompletionFactorDisplayValue()"
-		  	@input="onItemCompletionFactorInput"
-			@blur="formatItemCompletionFactor()"
-		  	placeholder="请输入分项完成系数"
-		    />
-		  </view>
+      <view class="info-card" v-if="showModifyReason">
 		  <!-- 修改理由 - 仅当需要修改时显示 -->
-        <view class="form-item" v-if="showModifyReason">
+        <view class="form-item" >
           <text class="label">修改理由<text style="color: red;">*</text></text>
           <textarea 
             class="textarea" 
@@ -224,6 +225,9 @@ const hasExtraWorkFlag = ref<boolean>(false)
 const showReturnReason = ref<boolean>(false)
 // 显示修改理由
 const showModifyReason = ref<boolean>(false)
+
+// 检查是否存在复评分数与自评分数不同的情况
+const hasDifferentReviewAndSelfScore = ref<boolean>(false)
 // 显示反馈理由
 const showFeedbackReason = ref<boolean>(false)
 
@@ -324,6 +328,48 @@ watch(reEvaluationForm, (newForm: ReEvaluationFormData) => {
   hasReturnReason.value = newForm.scoreReturnReason != null && !isWhitespaceOnly(newForm.scoreReturnReason as string);
 }, { deep: true })
 
+// 检查是否存在复评分数与自评分数不同的情况
+function checkDifferentReviewAndSelfScore(): boolean {
+  const scorePersonList = reEvaluationForm.value.scorePersonList as UTSJSONObject[]
+  if (scorePersonList == null || scorePersonList.length == 0) {
+    return false;
+  }
+
+  for (let i = 0; i < scorePersonList.length; i++) {
+    const person = scorePersonList[i]
+    const reviewScore = person.get('reviewScore')
+    const selfScore = person.get('selfScore')
+    
+    // 如果复评分数或自评分数为空,则跳过比较
+    if (reviewScore == null || selfScore == null || reviewScore == '' || selfScore == '') {
+      continue;
+    }
+    
+    // 统一转换为数值进行比较
+    let reviewScoreNum = 0;
+    let selfScoreNum = 0;
+    
+    if (typeof reviewScore == 'number') {
+      reviewScoreNum = reviewScore as number;
+    } else {
+      reviewScoreNum = parseFloat(reviewScore as string);
+    }
+    
+    if (typeof selfScore == 'number') {
+      selfScoreNum = selfScore as number;
+    } else {
+      selfScoreNum = parseFloat(selfScore as string);
+    }
+    
+    // 比较数值是否不同(考虑浮点数精度问题)
+    if (Math.abs(reviewScoreNum - selfScoreNum) > 0.001) {
+      return true;
+    }
+  }
+  
+  return false;
+}
+
 // 获取已复评总分
 function getReEvaluatedTotalScore(): number {
   const scorePersonList = reEvaluationForm.value.scorePersonList as UTSJSONObject[]
@@ -951,26 +997,35 @@ function validateForm(): any {
       result.set('message', '修改了分项完成系数,请填写修改理由');
       return result;
   }
+  
+  // 检查是否存在复评分数与自评分数不同但未填写修改理由的情况
+  if (checkDifferentReviewAndSelfScore() && 
+      (reEvaluationForm.value.modifyReason == null || isWhitespaceOnly(reEvaluationForm.value.modifyReason as string))) {
+      const result = new UTSJSONObject();
+      result.set('valid', false);
+      result.set('message', '复评分数与自评分数不同,请填写修改理由');
+      return result;
+  }
 
   // 验证评分规则
   let scoringValidation: UTSJSONObject;
-  try {
-    scoringValidation = validateScoringRules() as UTSJSONObject;
-  } catch (error: any) {
-    console.error('评分规则验证过程中出现异常:', error);
-    const result = new UTSJSONObject();
-    result.set('valid', false);
-    result.set('message', '评分规则验证失败');
-    return result;
-  }
-  if (!(scoringValidation.get('valid') as boolean)) {
-    const result = new UTSJSONObject();
-    result.set('valid', false);
-    result.set('message', scoringValidation.get('message') as string);
-    return result;
-  }
-  
-  const result = new UTSJSONObject();
+	try {
+	  scoringValidation = validateScoringRules() as UTSJSONObject;
+	} catch (error: any) {
+	  console.error('评分规则验证过程中出现异常:', error);
+	  const result = new UTSJSONObject();
+	  result.set('valid', false);
+	  result.set('message', '评分规则验证失败');
+	  return result;
+	}
+	if (!(scoringValidation.get('valid') as boolean)) {
+	  const result = new UTSJSONObject();
+	  result.set('valid', false);
+	  result.set('message', scoringValidation.get('message') as string);
+	  return result;
+	}
+
+	const result = new UTSJSONObject();
   result.set('valid', true);
   result.set('message', '');
   return result;
@@ -1172,17 +1227,23 @@ async function loadOrderDetail() {
       // 根据工单类型和数据设置显示控制
       // 如果工单有反馈理由,则显示反馈理由区域
      showFeedbackReason.value = formData.feedbackReason != null && !isWhitespaceOnly(formData.feedbackReason as string);
+
+      // 检查是否存在复评分数与自评分数不同的情况
+      hasDifferentReviewAndSelfScore.value = checkDifferentReviewAndSelfScore();
       
-      // 如果工单的初始值与当前值不同,显示修改理由区域
-      if (orderType.value == '1' && formData.maintenanceType != formData.initialMaintenanceType) {
-        showModifyReason.value = true;
-      } else if (orderType.value == '2' && formData.itemCompletionFactor != formData.initialItemCompletionFactor) {
+      // 如果存在复评分数与自评分数不同,或者工单的初始值与当前值不同,显示修改理由区域
+      // 只有两个条件都不存在时才隐藏修改理由
+      if (hasDifferentReviewAndSelfScore.value ||
+          (orderType.value == '1' && reEvaluationForm.value.maintenanceType != reEvaluationForm.value.initialMaintenanceType) ||
+          (orderType.value == '2' && reEvaluationForm.value.itemCompletionFactor != reEvaluationForm.value.initialItemCompletionFactor)) {
         showModifyReason.value = true;
+      } else {
+        showModifyReason.value = false;
       }
       
       // 如果工单已经有退回理由(来自后端),则显示退回理由区域
       showReturnReason.value = formData.scoreReturnReason != null && !isWhitespaceOnly(formData.scoreReturnReason as string);
-      
+
       // 初始化已复评总分
       updateReEvaluatedTotalScore()
     } else {
@@ -1256,7 +1317,11 @@ function onReturnReasonInput(e: UniInputEvent) {
 
 // 修改理由输入处理
 function onModifyReasonInput(e: UniInputEvent) {
-  const value = e.detail?.value as string
+  let value = e.detail?.value as string
+  // 限制输入长度在200以内
+  if (value != null && value.length > 200) {
+    value = value.substring(0, 200)
+  }
   reEvaluationForm.value.modifyReason = value
   
   // 当用户输入修改理由时,更新显示控制
@@ -1315,8 +1380,14 @@ function formatItemCompletionFactor() {
     tempItemCompletionFactorInput.value = '';
   }
   
-  // 检查是否需要显示修改理由
-  if (finalValue != reEvaluationForm.value.initialItemCompletionFactor) {
+  // 检查是否存在复评分数与自评分数不同的情况
+  hasDifferentReviewAndSelfScore.value = checkDifferentReviewAndSelfScore();
+  
+  // 如果存在复评分数与自评分数不同,或者修改了分项完成系数,显示修改理由
+  // 只有两个条件都不存在时才隐藏修改理由
+  if (hasDifferentReviewAndSelfScore.value || 
+      (reEvaluationForm.value.orderType == '2' && 
+       reEvaluationForm.value.itemCompletionFactor != reEvaluationForm.value.initialItemCompletionFactor)) {
     showModifyReason.value = true;
   } else {
     showModifyReason.value = false;
@@ -1350,11 +1421,16 @@ function onItemCompletionFactorInput(e: UniInputEvent) {
         reEvaluationForm.value.itemCompletionFactor = numValue > 1 ? 1 : 0;
       } 
       
-      // 检查是否修改了分项完成系数
-      if (reEvaluationForm.value.itemCompletionFactor != reEvaluationForm.value.initialItemCompletionFactor) {
+      // 检查是否存在复评分数与自评分数不同的情况
+      hasDifferentReviewAndSelfScore.value = checkDifferentReviewAndSelfScore();
+      
+      // 如果存在复评分数与自评分数不同,或者修改了分项完成系数,显示修改理由
+      // 只有两个条件都不存在时才隐藏修改理由
+      if (hasDifferentReviewAndSelfScore.value || 
+          (reEvaluationForm.value.orderType == '2' && 
+           reEvaluationForm.value.itemCompletionFactor != reEvaluationForm.value.initialItemCompletionFactor)) {
         showModifyReason.value = true;
       } else {
-        // 如果值等于初始值,则隐藏修改理由
         showModifyReason.value = false;
       } 
       
@@ -1482,6 +1558,20 @@ function formatScoreInput(index: number, field: string) {
 function onScoreChange() {
   updateTotalScores()
   updateReEvaluatedTotalScore() // 更新已复评总分显示
+  
+  // 检查是否需要显示修改理由
+  // 检查是否存在复评分数与自评分数不同的情况
+  hasDifferentReviewAndSelfScore.value = checkDifferentReviewAndSelfScore();
+  
+  // 如果存在复评分数与自评分数不同,或者修改了分项完成系数,显示修改理由
+  // 只有两个条件都不存在时才隐藏修改理由
+  if (hasDifferentReviewAndSelfScore.value || 
+      (reEvaluationForm.value.orderType == '2' && 
+       reEvaluationForm.value.itemCompletionFactor != reEvaluationForm.value.initialItemCompletionFactor)) {
+    showModifyReason.value = true;
+  } else {
+    showModifyReason.value = false;
+  }
 }
 
 // 返回按钮事件
@@ -2069,4 +2159,4 @@ async function submitReEvaluationForm(): Promise<void> {
   font-weight: bold;
   color: #333;
 }
-</style>
+</style>

+ 71 - 48
pages/score/index.uvue

@@ -22,7 +22,7 @@
         <view class="scroll-view-item_H">
           <text
             class="status-txt"
-            :class="{ 'stauts-sel': statusFilter === '' }"
+            :class="{ 'stauts-sel': statusFilter == '' }"
             @click="filterByStatus('')"
           >
             全部
@@ -31,7 +31,7 @@
         <view class="scroll-view-item_H">
           <text
             class="status-txt"
-            :class="{ 'stauts-sel': statusFilter === 'to_self' }"
+            :class="{ 'stauts-sel': statusFilter == 'to_self' }"
             @click="filterByStatus('to_self')"
           >
             待自评
@@ -40,7 +40,7 @@
         <view class="scroll-view-item_H">
           <text
             class="status-txt"
-            :class="{ 'stauts-sel': statusFilter === 'to_re' }"
+            :class="{ 'stauts-sel': statusFilter == 'to_re' }"
             @click="filterByStatus('to_re')"
           >
             待复评
@@ -50,7 +50,7 @@
 		<view class="scroll-view-item_H">
 		  <text
 		    class="status-txt"
-		    :class="{ 'stauts-sel': statusFilter === 'returned' }"
+		    :class="{ 'stauts-sel': statusFilter == 'returned' }"
 		    @click="filterByStatus('returned')"
 		  >
 		    已退回
@@ -59,7 +59,7 @@
 		<view class="scroll-view-item_H">
 		  <text
 		    class="status-txt"
-		    :class="{ 'stauts-sel': statusFilter === 'to_final' }"
+		    :class="{ 'stauts-sel': statusFilter == 'to_final' }"
 		    @click="filterByStatus('to_final')"
 		  >
 		    待终评
@@ -68,7 +68,7 @@
 		<view class="scroll-view-item_H">
 		  <text
 		    class="status-txt"
-		    :class="{ 'stauts-sel': statusFilter === 'appealing' }"
+		    :class="{ 'stauts-sel': statusFilter == 'appealing' }"
 		    @click="filterByStatus('appealing')"
 		  >
 		    申诉中
@@ -76,7 +76,7 @@
 		</view>
 		<text
 		  class="status-txt"
-		  :class="{ 'stauts-sel': statusFilter === 'to_confirm' }"
+		  :class="{ 'stauts-sel': statusFilter == 'to_confirm' }"
 		  @click="filterByStatus('to_confirm')"
 		>
 		  待确认
@@ -89,21 +89,21 @@
       <view class="stats-tabs">
         <text
           class="tab-item"
-          :class="{ 'tab-active': activeTab === 'ranking' }"
+          :class="{ 'tab-active': activeTab == 'ranking' }"
           @click="switchTab('ranking')"
         >
           个人排名
         </text>
         <text
           class="tab-item"
-          :class="{ 'tab-active': activeTab === 'score' }"
+          :class="{ 'tab-active': activeTab == 'score' }"
           @click="switchTab('score')"
         >
           月度工分
         </text>
       </view>
 		<!-- 个人排名内容 -->
-		<view v-if="activeTab === 'ranking'" class="ranking-content">
+		<view v-if="activeTab == 'ranking'" class="ranking-content">
 		  <!-- 排名模块 -->
 		  <view v-if="rankingItems.length > 0">
 		    <view class="ranking-item-wrapper" v-for="(item, index) in rankingItems" :key="index">
@@ -123,14 +123,14 @@
 		  </view>
 		</view>
 		<!-- 月度工分内容 -->
-		<view v-if="activeTab === 'score'" class="score-content">
+		<view v-if="activeTab == 'score'" class="score-content">
 			<view class="stats-header">
 				<text class="stats-title">{{ monthTitle }}月度工分</text>
 				<view class="month-filters">
 					<view class="month-tab">
 					  <text
 						class="month-filter"
-						:class="{ 'month-filter-sel': selectedMonth === 'prev' }"
+						:class="{ 'month-filter-sel': selectedMonth == 'prev' }"
 						@click="changeMonth('prev')"
 					  >
 						上月
@@ -139,7 +139,7 @@
 					<view class="month-tab">
 					  <text
 						class="month-filter"
-						:class="{ 'month-filter-sel': selectedMonth === 'current' }"
+						:class="{ 'month-filter-sel': selectedMonth == 'current' }"
 						@click="changeMonth('current')"
 					  >
 						本月
@@ -148,7 +148,7 @@
 				  <view class="month-tab">
 					  <text
 						class="month-filter"
-						:class="{ 'month-filter-sel': selectedMonth === 'custom' }"
+						:class="{ 'month-filter-sel': selectedMonth == 'custom' }"
 						@click="showCustomDatePicker"
 					  >
 						自定义
@@ -216,16 +216,16 @@
 			</view>
 			<view class="btn-group">
 			  <view
-			    v-if="getPropertyValue(item, 'scoringStatus')  == 'to_self' || getPropertyValue(item, 'scoringStatus') == 'returned'"
+			    v-if="canHandleScore(item, 'to_self')"
 			    class="btn-primary info-value"
-			    @click.stop="handleScoreClick(item, 'self')"
+			    @click.stop="handleScoreClick(item, 'to_self')"
 			    >
 			    <text class="btn-text">自评</text>
 			  </view>
 			  <view
-			    v-if="getPropertyValue(item, 'scoringStatus') == 'to_re'"
+			    v-if="canHandleScore(item, 'to_re')"
 			    class="btn-primary info-value"
-			    @click.stop="handleScoreClick(item, 're')"
+			    @click.stop="handleScoreClick(item, 'to_re')"
 			    >
 			    <text class="btn-text">复评</text>
 			  </view>
@@ -282,7 +282,7 @@
     import { getDictDataByType } from '@/api/dict/index'
     import { selectHomePageData } from '@/api/index/index'
     import type { SysDictData } from '@/types/dict'
-    import {checkPermi} from '../../utils/storage'
+    import {checkPermi, getUserInfo} from '../../utils/storage'
 
     // 数据状态
     const searchKeyword = ref<string>('')
@@ -299,6 +299,10 @@
     const rank = ref<number | null>(null)
     const totalRankingUsers = ref<number | null>(null)
     const customDate = ref<string>('')
+	
+	// 用户信息
+	const userId = ref<string>("")
+	const roles = ref<string>('')
 
     // 新增:标签切换相关
     const activeTab = ref<string>('ranking') // 默认显示个人排名
@@ -399,7 +403,7 @@
 
           // 部门排名(东山电场)
           if (data.hasOwnProperty('deptSort') && data.hasOwnProperty('scoreDept')) {
-            const deptSort = typeof data['deptSort'] === 'number' ? data['deptSort'] as number : 0;
+            const deptSort = typeof data['deptSort'] == 'number' ? data['deptSort'] as number : 0;
             const scoreDept = Array.isArray(data['scoreDept']) ? data['scoreDept'] as any[] : [];
             // 只有当部门排序大于0且scoreDept数组不为空时才添加
             if (deptSort > 0 && scoreDept.length > 0) {
@@ -413,7 +417,7 @@
 
           // 中心排名(陆上设备维护中心)
           if (data.hasOwnProperty('centerSort') && data.hasOwnProperty('scoreCenter')) {
-            const centerSort = typeof data['centerSort'] === 'number' ? data['centerSort'] as number : 0;
+            const centerSort = typeof data['centerSort'] == 'number' ? data['centerSort'] as number : 0;
             const scoreCenter = Array.isArray(data['scoreCenter']) ? data['scoreCenter'] as any[] : [];
             // 只有当中心排序大于0且scoreCenter数组不为空时才添加
             if (centerSort > 0 && scoreCenter.length > 0) {
@@ -427,7 +431,7 @@
 
           // 公司排名
           if (data.hasOwnProperty('companySort') && data.hasOwnProperty('scoreCompany')) {
-            const companySort = typeof data['companySort'] === 'number' ? data['companySort'] as number : 0;
+            const companySort = typeof data['companySort'] == 'number' ? data['companySort'] as number : 0;
             const scoreCompany = Array.isArray(data['scoreCompany']) ? data['scoreCompany'] as any[] : [];
             // 只有当公司排序大于0且scoreCompany数组不为空时才添加
             if (companySort > 0 && scoreCompany.length > 0) {
@@ -452,7 +456,7 @@
       activeTab.value = tab;
 
       // 当切换到个人排名标签时,获取排名数据
-      if (tab === 'ranking') {
+      if (tab == 'ranking') {
         fetchRankingData();
       }
     }
@@ -693,16 +697,16 @@
     function getStatistics() {
       // Convert 'current' and 'prev' values to actual date strings
       let monthValue = '';
-      if (selectedMonth.value === 'custom') {
+      if (selectedMonth.value == 'custom') {
         monthValue = customDate.value;
-      } else if (selectedMonth.value === 'current') {
+      } else if (selectedMonth.value == 'current') {
           const now = new Date();
           monthValue = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}`;
-      } else if (selectedMonth.value === 'prev') {
+      } else if (selectedMonth.value == 'prev') {
         const now = new Date();
           const prevMonth = now.getMonth(); // getMonth() returns 0-11
-          const prevYear = prevMonth === 0 ? now.getFullYear() - 1 : now.getFullYear();
-          const monthStr = prevMonth === 0 ? '12' : prevMonth.toString().padStart(2, '0');
+          const prevYear = prevMonth == 0 ? now.getFullYear() - 1 : now.getFullYear();
+          const monthStr = prevMonth == 0 ? '12' : prevMonth.toString().padStart(2, '0');
         monthValue = `${prevYear}-${monthStr}`;
       }
 
@@ -774,9 +778,9 @@
 
       // Convert 'current' and 'prev' values to actual date strings
       let monthValue = '';
-      if (selectedMonth.value === 'custom') {
+      if (selectedMonth.value == 'custom') {
         monthValue = customDate.value;
-      } else if (selectedMonth.value === 'current') {
+      } else if (selectedMonth.value == 'current') {
         const now = new Date();
         const m = now.getMonth() + 1
         let mStr = m.toString()
@@ -784,11 +788,11 @@
           mStr = '0' + mStr
         }
         monthValue = `${now.getFullYear()}-${mStr}`;
-      } else if (selectedMonth.value === 'prev') {
+      } else if (selectedMonth.value == 'prev') {
         const now = new Date();
         const prevMonth = now.getMonth(); // getMonth() returns 0-11
-        const prevYear = prevMonth === 0 ? now.getFullYear() - 1 : now.getFullYear();
-        let monthStr = prevMonth === 0 ? '12' : prevMonth.toString()
+        const prevYear = prevMonth == 0 ? now.getFullYear() - 1 : now.getFullYear();
+        let monthStr = prevMonth == 0 ? '12' : prevMonth.toString()
         if (prevMonth !== 0 && prevMonth < 10) {
           monthStr = '0' + monthStr
         }
@@ -1014,12 +1018,12 @@
 	    const idStr = '' + id
 	    const orderTypeStr = '' + orderType
 	    
-	    if (operationType === 'self') {
+	    if (operationType == 'to_self') {
 	      // 自评操作:跳转到自评页面
 	      uni.navigateTo({
 	        url: `/pages/score/detail/selfEvaluate?id=${idStr}&orderType=${orderTypeStr}`
 	      })
-	    } else if (operationType === 're') {
+	    } else if (operationType == 'to_re') {
 	      // 复评操作:跳转到复评页面
 	      uni.navigateTo({
 	        url: `/pages/score/detail/reEvaluate?id=${idStr}&orderType=${orderTypeStr}`
@@ -1032,22 +1036,33 @@
 	function canHandleScore(item: any | null, operationType: string): boolean {
 	  if (item == null) return false
 	  
+	  let permit: string[] = []
+	  const orderItem = item as UTSJSONObject
 	  const scoringStatus = getPropertyValue(item, 'scoringStatus')
+	  const orderType = getPropertyValue(item, 'orderType')
+	  const teamLeaderId = parseInt(getPropertyValue(item, 'teamLeaderId'))
 	  
-	  // 根据评分状态和操作类型决定是否显示操作按钮
-	  if (operationType === 'self' && (scoringStatus === 'to_self' || scoringStatus === 'returned')) {
-	    // 自评操作:状态为to_self或returned时显示
-	    return true
-	  } else if (operationType === 're' && scoringStatus === 'to_re') {
-	    // 复评操作:状态为to_re时显示
-	    return true
+	  // 根据评分状态和操作类型决定权限
+	  if (scoringStatus == 'to_self' || scoringStatus == 'returned') {
+	    // 自评权限
+	    if (operationType == 'to_self' && (teamLeaderId == parseInt(userId.value) || roles.value.includes("管理员"))) {
+	      permit = ['gxt:orderScore:selfEvaluation']
+	    }
+	  } else if (scoringStatus == 'to_re') {
+	    // 复评权限
+	    if (operationType == 'to_re') {
+	      permit = ['gxt:orderScore:review']
+	    }
+	  } else {
+	    return false
 	  }
 	  
-	  return false
+	  // 检查权限
+	  return checkPermi(permit)
 	}
 
     function formatNumber(value: number | null) {
-      if (value === null) return '0.0'
+      if (value == null) return '0.0'
       return value.toFixed(2)
     }
 
@@ -1076,6 +1091,14 @@
         // 检查权限设置tabbar
         tabbar[2] = checkPermi(['gxt:app:worktime']) ? 1 : 0
         tabbar[3] = checkPermi(['gxt:app:score']) ? 1 : 0
+		
+		// 获取用户信息
+		const userInfo = getUserInfo()
+		if (userInfo != null) {
+			const userIdStr = userInfo['userId'].toString()
+			userId.value = userIdStr
+			roles.value = userInfo['roleNames'].toString()
+		}
 
         loadStatusDictList()
         loadInspectionTypeDictList()
@@ -1092,7 +1115,7 @@
     onShow(() => {
       // 检查是否有来自子页面的刷新标记
       const needRefresh = uni.getStorageSync('needRefresh')
-      if (needRefresh === true) {
+      if (needRefresh == true) {
         // 清除标记
         uni.removeStorageSync('needRefresh')
         // 延迟执行刷新,确保页面完全加载后再刷新数据
@@ -1119,9 +1142,9 @@
     // 获取排名类型(dept, center, company)
     function getRankingType(index: number): string {
       // 根据索引返回对应的排名类型
-      if (index === 0) return 'dept';
-      if (index === 1) return 'center';
-      if (index === 2) return 'company';
+      if (index == 0) return 'dept';
+      if (index == 1) return 'center';
+      if (index == 2) return 'company';
       return 'dept'; // 默认返回部门排名
     }
 

+ 1 - 1
pages/splash/index.uvue

@@ -456,7 +456,7 @@ export default {
   color: #94a3b8;
 }
 
-.ranking-icon {
+.ranking-icon[image] {
   width: 48rpx;
   height: 48rpx;
 }