From 46d143d1d6fe8f286399f4d027c9a86adf7cd7fc Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期三, 09 七月 2025 08:50:01 +0800
Subject: [PATCH] feat(inspection,maintenance): - 实现保养工单批量确认功能 - 在点检记录确认时增加时间限制,距离上次更新时间两小时内不允许确认

---
 eims-ui-mobile/src/pages/inspect/insp-record.vue |  231 ++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 187 insertions(+), 44 deletions(-)

diff --git a/eims-ui-mobile/src/pages/inspect/insp-record.vue b/eims-ui-mobile/src/pages/inspect/insp-record.vue
index a276635..aa5832a 100644
--- a/eims-ui-mobile/src/pages/inspect/insp-record.vue
+++ b/eims-ui-mobile/src/pages/inspect/insp-record.vue
@@ -6,7 +6,14 @@
 }
 </route>
 <template>
-  <z-paging ref="paging" v-model="dataList" :auto="false" @query="queryList" show-refresher-update-time>
+  <z-paging
+    ref="paging"
+    v-model="dataList"
+    :auto="false"
+    @query="queryList"
+    refresher-only
+    show-refresher-update-time
+  >
     <template #top>
       <wd-navbar
         title="鐐规璁板綍"
@@ -18,16 +25,19 @@
         safeAreaInsetTop
       >
         <template #right>
-          <text v-if="isOperatorOrRepair()" class="text-white">鎻愪氦</text>
+          <text v-if="inspSt.status === '0'" class="text-white">鎻愪氦</text>
         </template>
       </wd-navbar>
       <wd-card type="rectangle">
         <template #title>
           <view class="flex justify-between">
-            <view class="flex items-center menu-title-box">
+            <view
+              class="flex items-center menu-title-box center"
+              style="align-content: center; flex-wrap: wrap"
+            >
               <view class="menu-indicator"></view>
-              <view class="ml-1 text-sm align-center">{{ inspSt.equName }}</view>
-              <view class="text-color-gray ml-2 text-mini">{{ inspSt.assetNo }}</view>
+              <view class="ml-1 text-lg align-center">{{ inspSt.equName }}</view>
+              <view class="text-color-gray ml-2 text-sm">{{ inspSt.assetNo }}</view>
             </view>
 
             <view class="flex items-center">
@@ -38,30 +48,34 @@
         <view class="flex h-[140rpx]" items-center>
           <image class="slot-img text-center" src="/static/images/camera.png" />
           <view class="flex-1">
-            <view class="text-color-gray text-xs mt-1 flex">
+            <view class="text-color-gray text-sm mt-1 flex">
               <text class="mr-3">鐐规鎬绘暟: {{ dataCount }}</text>
               |
               <text class="mx-3">宸茬偣妫�: {{ checkCount }}</text>
               |
               <text class="ml-3">鏈偣妫�: {{ dataCount - checkCount }}</text>
             </view>
-            <view class="text-color-gray text-xs mt-2 flex">
+            <view class="text-color-gray text-sm mt-2 flex">
               <text class="mr-3">姝e父: {{ normalNum }}</text>
               |
               <text class="mx-3">寮傚父: {{ abNormalNum }}</text>
             </view>
-            <view class="text-color-gray text-xs mt-2 flex">
+            <view class="text-color-gray text-sm mt-2 flex">
               <text>鐘舵�侊細</text>
-              <template v-if="dataCount > 0 && dataCount === checkCount">
+              <template v-if="inspSt.status === '1'">
                 <wd-icon class="icon-color-success" name="check-outline" size="34rpx"></wd-icon>
                 <text class="ml-1">宸插畬鎴�</text>
+              </template>
+              <template v-else-if="inspSt.status === '2'">
+                <wd-icon class="icon-color-warning" name="check-outline" size="34rpx"></wd-icon>
+                <text class="ml-1">宸茬‘璁�</text>
               </template>
               <template v-else>
                 <wd-icon class="icon-color-base" name="detection" size="40rpx"></wd-icon>
                 <text class="ml-1">杩涜涓�</text>
               </template>
             </view>
-            <view class="text-color-gray text-xs mt-2 flex">鍒涘缓鏃堕棿: {{ inspSt.createTime }}</view>
+            <view class="text-color-gray text-sm mt-2 flex">鍒涘缓鏃堕棿: {{ inspSt.createTime }}</view>
           </view>
         </view>
       </wd-card>
@@ -71,18 +85,23 @@
       <view class="w-full h-[24rpx]"></view>
       <wd-cell>
         <template #title>
-          <text class="text-color-gray">鐐规椤�</text>
+          <text class="text-color-gray text-sm">鐐规椤�</text>
         </template>
-        <wd-button size="small" type="text" @click.stop="toggleCollapse">
-          {{ isAllExpanded ? '鍏ㄩ儴鎶樺彔' : '鍏ㄩ儴灞曞紑' }}
-        </wd-button>
+        <!--        <wd-button size="small" type="text" @click.stop="toggleCollapse">-->
+        <!--          {{ isAllExpanded ? '鍏ㄩ儴鎶樺彔' : '鍏ㄩ儴灞曞紑' }}-->
+        <!--        </wd-button>-->
       </wd-cell>
-      <wd-collapse v-model="collSelects" title="鐐规椤�" ref="collapseRef">
-        <wd-collapse-item :name="item.id" v-for="(item, index) in dataList" disabled>
+      <wd-collapse v-model="collSelects" title="鐐规椤�" ref="collapseRef" accordion>
+        <wd-collapse-item
+          :name="item.id"
+          v-for="(item, index) in dataList"
+          :key="item.id"
+          :class="getItemClass(item)"
+        >
           <template #title="{ expanded, disabled, isFirst }">
             <view class="flex justify-between">
-              <view class="flex justify-center items-center" style="max-width: 60%;">
-                <text class="text-sm" >{{ item.inspName }}</text>
+              <view class="flex justify-center items-center" style="max-width: 60%">
+                <text class="text-sm">{{ item.inspName }}</text>
               </view>
 
               <view class="flex items-center">
@@ -105,34 +124,47 @@
               </view>
             </view>
           </template>
-          <view class="text-color-gray text-xs flex justify-between">
+
+          <view v-if="item.inspResult === '2'" class="mt-2">
+            <wd-input
+              v-model="item.inspDesc"
+              placeholder="璇疯緭鍏ュ紓甯告弿杩�"
+              clearable
+              :maxlength="200"
+            />
+          </view>
+          <view class="text-color-gray text-sm flex justify-between">
             <text class="mr-3">鐐规浜�: {{ item.inspUserName }}</text>
             <text class="mx-3">鐐规鏃堕棿: {{ item.inspTime }}</text>
           </view>
         </wd-collapse-item>
       </wd-collapse>
-      <view class="w-full h-[24rpx]"></view>
-      <wd-cell>
-        <template #title>
-          <text class="text-color-gray">鍏朵粬</text>
-        </template>
-      </wd-cell>
+      <!--      <view class="w-full h-[24rpx]"></view>-->
+      <!--      <wd-cell>-->
+      <!--&lt;!&ndash;        <template #title>&ndash;&gt;-->
+      <!--&lt;!&ndash;          <text class="text-color-gray">鍏朵粬</text>&ndash;&gt;-->
+      <!--&lt;!&ndash;        </template>&ndash;&gt;-->
+      <!--      </wd-cell>-->
       <view class="w-full h-[1px] bg-base"></view>
       <wd-input
+        v-if="inspSt.status !== '0'"
         label="杩愯鏃堕棿"
         label-width="200rpx"
         clearable
         v-model="inspSt.runTimes"
         placeholder="璇疯緭鍏ヨ繍琛屾椂闂�(h)"
         inputmode="numeric"
+        size="large"
       />
       <wd-input
+        v-if="inspSt.status !== '0'"
         label="鏁呴殰鏃堕棿"
         label-width="200rpx"
         clearable
         v-model="inspSt.faultTimes"
         placeholder="璇疯緭鍏ユ晠闅滄椂闂�(h)"
         inputmode="numeric"
+        size="large"
       />
       <wd-textarea
         label="鐗硅浜嬮」"
@@ -144,15 +176,20 @@
         show-word-limit
         placeholder="璇疯緭鍏ョ壒璁颁簨椤�"
         clearable
+        size="large"
       />
+      <!-- 鏂板鎻愪氦鎸夐挳 -->
+      <view class="flex justify-around">
+        <wd-button type="primary" style="margin: 20px" block  v-if="inspSt.status === '0' || inspSt.status === '1'" @click="handleClickRight">鎻愪氦</wd-button>
+<!--        <wd-button type="success" block size="large" v-if="isLeader() && inspSt.status === '1'" @click="handleComplete">纭瀹屾垚</wd-button>-->
+      </view>
     </view>
   </z-paging>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
 import { useUserStore, useAccessStore, useSystemConfigStore } from '@/store'
-import { isLeader, isOperatorOrRepair } from '@/utils/RoleUtils'
+import { isLeader, isLineOrRepair } from '@/utils/RoleUtils'
 import {
   getInspStRecordList,
   getInspSt,
@@ -188,13 +225,16 @@
   specialNote: string
   runTimes: number
   faultTimes: number
+  verifyUser?: number | string
+  verifyTime?: string
 }
 
 const dataChange = ref(false)
 
 const userStore = useUserStore()
 
-const collSelects = ref<string[]>([])
+const collSelects = ref('')
+const selectedItems = ref([])
 
 // 鐐规姹囨�绘暟鎹�(涓婁釜椤甸潰浼犲��)
 const inspSt = reactive<InspSt>({
@@ -207,26 +247,24 @@
   status: '',
   inspUser: '',
   specialNote: '',
-  runTimes: 0,
-  faultTimes: 0,
+  runTimes: undefined,
+  faultTimes: undefined,
 })
 
 const paging = ref(null)
 const dataList = ref([])
 
-const queryList = (pageNum?: number, pageSize?: number) => {
+const queryList = () => {
   // 杩欓噷鐨刾ageNo鍜宲ageSize浼氳嚜鍔ㄨ绠楀ソ锛岀洿鎺ヤ紶缁欐湇鍔″櫒鍗冲彲
   // 杩欓噷鐨勮姹傚彧鏄紨绀猴紝璇锋浛鎹㈡垚鑷繁鐨勯」鐩殑缃戠粶璇锋眰锛屽苟鍦ㄧ綉缁滆姹傚洖璋冧腑閫氳繃paging.value.complete(璇锋眰鍥炴潵鐨勬暟缁�)灏嗚姹傜粨鏋滀紶缁檢-paging
   const params: QueryParams = {
-    pageNum,
-    pageSize,
     inspCode: inspSt.inspCode,
   }
 
   getInspStRecordList(params)
     .then((res: any) => {
       // 璇峰嬁鍦ㄧ綉缁滆姹傚洖璋冧腑缁檇ataList璧嬪�硷紒锛佸彧闇�瑕佽皟鐢╟omplete灏卞彲浠ヤ簡
-      paging.value.completeByTotal(res.rows, res.total)
+      paging.value.complete(res.rows, res.total)
     })
     .catch((res) => {
       // 濡傛灉璇锋眰澶辫触鍐檖aging.value.complete(false)锛屼細鑷姩灞曠ず閿欒椤甸潰
@@ -237,7 +275,12 @@
 }
 
 function inspResultClick(item: any) {
-  // userStore?.userInfo?.userId
+  console.log('inspResultClick', userStore.userInfo)
+  // 鑷姩濉厖鐐规浜哄拰鏃堕棿
+  item.inspUserName = userStore?.userInfo?.realName || ''
+  // 淇敼鏃堕棿鏍煎紡涓� YYYY-MM-DD HH:mm:ss
+  const now = new Date()
+  item.inspTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
 }
 
 const goBack = () => {
@@ -245,10 +288,12 @@
 }
 
 function handleClickRight() {
-  if(isOperatorOrRepair()){
-    handleConfirm()
-  }
 
+  if (inspSt.status === '0') {
+    handleConfirm()
+  } else if (inspSt.status === '1') {
+    handleComplete()
+  }
 }
 
 const toggleCollapse = () => {
@@ -257,10 +302,31 @@
 }
 
 function handleConfirm() {
+  console.log('handleConfirm')
   if (!dataChange.value) {
     message.alert('璇锋搷浣滃悗鎻愪氦!')
     return false
   }
+
+  // 妫�鏌ユ槸鍚︽湁寮傚父椤规湭濉啓鎻忚堪
+  const invalidItems = dataList.value.filter(
+    (item) => item.inspResult === '2' && !item.inspDesc?.trim(),
+  )
+  if (invalidItems.length > 0) {
+    message.alert('璇峰~鍐欐墍鏈夊紓甯搁」鐨勫紓甯告弿杩�!')
+    return false
+  }
+
+  // 杩囨护鍑哄凡閫夋嫨鐨勯」鐩�
+  selectedItems.value = dataList.value.filter(
+    (item) => item.inspResult === '1' || item.inspResult === '2',
+  )
+
+  if (selectedItems.value.length === 0) {
+    message.alert('璇疯嚦灏戦�夋嫨涓�涓偣妫�椤�!')
+    return false
+  }
+
   message
     .confirm({
       msg: '纭畾鎻愪氦锛�',
@@ -278,8 +344,9 @@
 }
 
 function updateData(resolve: any) {
+  console.log('updateData', selectedItems.value)
   const params = {
-    inspRecordList: dataList.value,
+    inspRecordList: selectedItems.value,
   }
   // 鏇存柊鐐规璁板綍
   updateInspRecordBatch(params)
@@ -293,7 +360,12 @@
 }
 function updateInspSt(resolve: any) {
   // 鏇存柊鐐规姹囨��
-  inspSt.status = '1'
+  if (dataCount.value === selectedItems.value.length) {
+    inspSt.status = '1'
+  } else {
+    inspSt.status = '0'
+  }
+
   updateInspectSt(inspSt)
     .then((res: any) => {
       toast.success('鎿嶄綔鎴愬姛')
@@ -308,13 +380,71 @@
 }
 
 /**
+ * 纭瀹屾垚鎸夐挳鐐瑰嚮浜嬩欢
+ */
+function handleComplete() {
+  console.log('handleComplete', inspSt)
+  if (!inspSt.runTimes || !inspSt.faultTimes) {
+    message.alert('璇峰~鍐欒繍琛屾鏁板拰鏁呴殰娆℃暟!')
+    return false
+  }
+  // 濡傛灉褰撳墠鏃堕棿璺濅笂娆℃柊鏃堕棿涓ゅ皬鏃朵互鍐呭垯涓嶅厑璁哥‘璁�
+  console.log('inspSt.updateTime', inspSt.updateTime)
+  console.log('new Date().getTime()', new Date().getTime())
+  console.log('inspSt.updateTime', new Date(inspSt.updateTime).getTime())
+  console.log('new Date().getTime() - new Date(inspSt.updateTime).getTime()', new Date().getTime() - new Date(inspSt.updateTime).getTime())
+  console.log("2 * 60 * 60 * 1000", 2 * 60 * 60 * 1000)
+  console.log('new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000', new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000)
+  if (
+    new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000
+  ) {
+    console.log("new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000",new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000)
+    message.alert('鐐规涓ゅ皬鏃朵互鍐呬笉鍏佽纭!')
+    return false
+  }
+  const now = new Date();
+  const data: any = Object.assign(
+    {},
+    {
+      id: inspSt.id,
+      runTimes: inspSt.runTimes,
+      faultTimes: inspSt.faultTimes,
+      status: '2',
+      verifyUser: userStore?.userInfo?.userId,
+      verifyTime: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
+    },
+  )
+  updateInspectSt(data)
+    .then((res: any) => {
+      if (res?.code === 200) {
+        uni.$emit('insp-st-refresh')
+        goBack()
+        toast.success('鎿嶄綔鎴愬姛')
+      }
+    })
+    .catch((res) => {
+      console.error(res)
+      toast.error('鎿嶄綔澶辫触')
+    })
+}
+
+/**
  * 鐐规璁板綍鏉$洰鐐瑰嚮浜嬩欢
  * @param item
  */
 function itemClick(item: any) {}
 
+function getItemClass(item: any) {
+  if (item.inspResult === '1') {
+    return 'status-normal'
+  } else if (item.inspResult === '2') {
+    return 'status-abnormal'
+  }
+  return ''
+}
+
 watch(
-  () => [...dataList.value], // 浣跨敤鎵╁睍杩愮畻绗﹀垱寤烘柊鏁扮粍浠ヨЕ鍙戠洃鍚�
+  () => [...dataList.value, inspSt], // 浣跨敤鎵╁睍杩愮畻绗﹀垱寤烘柊鏁扮粍浠ヨЕ鍙戠洃鍚�
   (newVal, oldVal) => {
     if (oldVal.length > 0) {
       dataChange.value = true
@@ -375,7 +505,7 @@
   margin-right: 24rpx;
 }
 .text-mini {
-  font-size: 22rpx;
+  font-size: 24rpx;
 }
 
 .menu-indicator {
@@ -394,13 +524,26 @@
   background: $uni-color-primary;
 }
 :deep(.wd-navbar__text) {
-  font-size: 26rpx;
+  font-size: 28rpx;
   color: white;
 }
 :deep(.wd-icon-arrow-left:before),
 :deep(.wd-navbar__title) {
   color: white;
   font-weight: 0;
-  font-size: 32rpx;
+  font-size: 34rpx;
+}
+
+// 鏂板鏍峰紡锛氱偣妫�椤硅儗鏅壊
+.status-normal {
+  background-color: #e6f7ff; // 姝e父鐘舵�佽儗鏅壊锛堢豢鑹诧級
+}
+
+.status-abnormal {
+  background-color: #fffbe6; // 寮傚父鐘舵�佽儗鏅壊锛堥粍鑹诧級
+}
+:deep(.wd-radio-group) {
+  // 鏀逛负鏃犺儗鏅壊
+  background-color: transparent;
 }
 </style>

--
Gitblit v1.9.3