From f571cf0182abd65176fb1512c5cb5ddaea49c4a3 Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期二, 24 六月 2025 09:00:14 +0800
Subject: [PATCH] feat(eims): 设备状态变更记录功能

---
 eims-ui-mobile/src/pages/scan/index.vue |  243 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 231 insertions(+), 12 deletions(-)

diff --git a/eims-ui-mobile/src/pages/scan/index.vue b/eims-ui-mobile/src/pages/scan/index.vue
index 82d4d73..55f889a 100644
--- a/eims-ui-mobile/src/pages/scan/index.vue
+++ b/eims-ui-mobile/src/pages/scan/index.vue
@@ -19,17 +19,17 @@
           <view class="flex justify-between items-baseline">
             <view class="flex items-center menu-title-box">
               <view class="menu-indicator"></view>
-              <text class="ml-1 text-xs">{{ model.assetNo }}</text>
+              <text class="ml-1 text-sm">{{ model.assetNo }}</text>
               <wd-tag v-if="model.status === '0'" class="ml-2" bg-color="cyan">璇曠敤</wd-tag>
               <wd-tag v-else-if="model.status === '1'" class="ml-2" type="success">浣跨敤</wd-tag>
               <wd-tag v-else-if="model.status === '2'" class="ml-2" type="danger">鍋滅敤</wd-tag>
               <wd-tag v-else-if="model.status === '3'" class="ml-2" bg-color="pink">鎶ュ簾</wd-tag>
               <wd-tag v-else-if="model.status === '4'" class="ml-2" type="warning">闂茬疆</wd-tag>
-              <wd-tag v-else-if="model.status === '5'" class="ml-2">鏂板</wd-tag>
+              <wd-tag v-else class="ml-2">鏂板</wd-tag>
             </view>
 
             <view @click="handleInfo">
-              <text class="icon-color-base">璇︽儏</text>
+              <text class="icon-color-base">鐘舵�佸彉鏇�</text>
               <wd-icon name="arrow-right" custom-class="icon-color-base"></wd-icon>
             </view>
           </view>
@@ -41,7 +41,7 @@
               {{ model.equName }}
               <text class="text-color-gray ml-2 text-mini">{{ model.modelNo }}</text>
             </view>
-            <view class="text-color-gray text-xs mt-1">
+            <view class="text-color-gray text-sm mt-1">
               {{ model.location }} | {{ model.madeIn }}
             </view>
           </view>
@@ -57,10 +57,44 @@
         <view class="h-[1px] bg-base"></view>
         <view class="bg-white flex justify-around py-4">
           <wd-button icon="edit-outline" @click.stop="handleInsp">鐐规</wd-button>
-          <wd-button icon="laptop" @click.stop="handMaint">淇濆吇</wd-button>
-          <wd-button icon="tools" @click.stop="showActions">缁翠慨</wd-button>
+          <wd-button icon="laptop" v-if="isRepair() || isLeader()" @click.stop="handMaint">
+            淇濆吇
+          </wd-button>
+          <wd-button icon="laptop" @click.stop="handleRequest">鎶ヤ慨</wd-button>
+          <!--          <wd-button icon="tools" @click.stop="showActions">缁翠慨</wd-button>-->
         </view>
       </view>
+      <view class="h-[10px] bg-base"></view>
+      <wd-tabs v-model="tab">
+
+        <wd-tab title="鎶ヤ慨鍗�">
+          <view class="h-[10px] bg-base"></view>
+          <!-- 缁翠慨璇锋眰鍖哄煙 -->
+          <view class="mt-2" v-if="reqList.length > 0">
+
+
+            <view class="bg-base">
+              <req-card
+                v-for="item in reqList"
+                :key="item.id"
+                :item="item"
+                @click="handleReqClick"
+              />
+            </view>
+          </view>
+        </wd-tab>
+        <wd-tab title="缁翠慨鍗�">
+          <view class="h-[10px] bg-base"></view>
+          <!-- 缁翠慨鍗曞尯鍩� -->
+          <view class="mt-2" v-if="resList.length > 0">
+
+
+            <view class="bg-base">
+              <res-card v-for="item in resList" :key="item.id" :item="item" />
+            </view>
+          </view>
+        </wd-tab>
+      </wd-tabs>
 
       <wd-action-sheet
         v-model="show"
@@ -69,6 +103,33 @@
         @select="select"
         cancel-text="鍙栨秷"
       />
+
+      <wd-popup v-model="showStatusDialog" position="center" round :close-on-click-modal="false">
+        <view class="popup-container">
+          <view class="popup-title">璁惧鐘舵�佸彉鏇�</view>
+          <view class="flex flex-wrap justify-between mb-4">
+            <view
+              v-for="item in statusOptions"
+              :key="item.value"
+              :class="['status-option', selectedStatus === item.value ? 'active' : '']"
+              @click="selectStatus(item.value)"
+            >
+              {{ item.label }}
+            </view>
+          </view>
+          <wd-textarea
+            v-model="changeReason"
+            placeholder="璇疯緭鍏ュ彉鏇村師鍥�"
+            :maxlength="100"
+            show-word-limit
+            required
+          />
+          <view class="popup-actions">
+            <wd-button block @click="handleStatusChangeCancel">鍙栨秷</wd-button>
+            <wd-button type="primary" block class="ml-2" @click="handleStatusChangeConfirm">纭畾</wd-button>
+          </view>
+        </view>
+      </wd-popup>
     </view>
     <view v-else>
       <wd-status-tip image="search" tip="褰撳墠鎼滅储鏃犵粨鏋�" />
@@ -79,16 +140,27 @@
 <script setup lang="ts">
 import dayjs from 'dayjs'
 import type { EquVO } from '@/service/equ.d'
+import type { RepairReqVO, RepairResVO } from '@/service/repair.d'
 import { useToast, useMessage } from 'wot-design-uni'
 import { getEquByAssetNo } from '@/service/equ'
 import { getInspStByStId } from '@/service/inspect'
+import { isLeader, isRepair } from '@/utils/RoleUtils'
+import { getRepairReqList, getRepairResList } from '@/service/repair'
+import ReqCard from '@/components/repair/req-card.vue'
+import ResCard from '@/components/repair/res-card.vue'
+import { useUserStore } from '@/store'
+import { addEquStatu } from '@/service/equ_status'
+import type { EimsEquStatuBo } from '@/service/equ_status.d'
+const tab = ref<number>(0)
 const message = useMessage()
 const toast = useToast()
 const model = reactive<EquVO>({})
-
+const userStore = useUserStore()
 const scanResult = ref<string>('')
 const show = ref<boolean>(false)
 const exist = ref<boolean>(false)
+const reqList = ref<RepairReqVO[]>([])
+const resList = ref<RepairResVO[]>([])
 const actions = ref([
   {
     name: '鏂板鎶ヤ慨',
@@ -97,12 +169,27 @@
     name: '鍘荤淮淇�',
   },
 ])
+const showStatusDialog = ref(false)
+const selectedStatus = ref<string>('')
+const changeReason = ref<string>('')
+const statusOptions = [
+  { label: '璇曠敤', value: '0' },
+  { label: '浣跨敤', value: '1' },
+  { label: '鍋滅敤', value: '2' },
+  { label: '鎶ュ簾', value: '3' },
+  { label: '闂茬疆', value: '4' },
+  { label: '鏂板', value: '5' },
+]
 
 function initData(assetNo: any) {
   getEquByAssetNo(assetNo)
     .then((res: any) => {
-      if (res.data) {
+      console.error(res)
+      if (res?.equId) {
+        exist.value = true
         Object.assign(model, res)
+        // 鍔犺浇缁翠慨璇锋眰鍜岀淮淇崟鏁版嵁
+        loadRepairData()
       } else {
         toast.error('鏈煡璇㈠埌璇ヨ祫浜х紪鍙风浉鍏虫暟鎹紒')
       }
@@ -112,11 +199,47 @@
       toast.error(res?.data?.msg || '璇锋眰澶辫触')
     })
 }
-function handleInfo() {
-  uni.showToast({
-    title: '鍔熻兘寮�鍙戜腑',
-    icon: 'none',
+
+// 鍔犺浇缁翠慨璇锋眰鍜岀淮淇崟鏁版嵁
+function loadRepairData() {
+  // 鍔犺浇鏈帴鍗曠殑缁翠慨璇锋眰
+  getRepairReqList({
+    equId: model.equId,
+    status: '0',
+  }).then((res: any) => {
+    if (res?.rows) {
+      reqList.value = res.rows
+    }
   })
+
+  // 鍔犺浇鏈畬鎴愮殑缁翠慨鍗�
+  const params = {
+    equId: model.equId,
+    params: {
+      status: '0,1,2',
+    },
+  }
+  // 濡傛灉鏄淮淇伐鍒欏姞杞芥湰瑕佹帴鍗曠殑缁翠慨鍗�
+  if (isRepair()) {
+    params.resUser = userStore?.userInfo?.userId
+    params.params.status = '0,1,2'
+  }
+  getRepairResList(params).then((res: any) => {
+    if (res?.rows) {
+      resList.value = res.rows
+    }
+  })
+}
+
+function handleInfo() {
+  if (!model?.equId) {
+    uni.showToast({ title: '鏈煡璇㈠埌璁惧锛岃鑱旂郴绠$悊鍛橈紒', icon: 'none' })
+    return
+  }
+  console.log("model::",model)
+  selectedStatus.value = model.status || '5'
+  changeReason.value = ''
+  showStatusDialog.value = true
 }
 
 function handleInsp() {
@@ -150,6 +273,19 @@
   })
 }
 
+function handleRequest() {
+  if (!model?.assetNo) {
+    uni.showToast({
+      title: '鏈煡璇㈠埌璁惧锛岃鑱旂郴绠$悊鍛橈紒',
+      icon: 'none',
+    })
+    return false
+  }
+  uni.navigateTo({
+    url: `/pages/repair/repair-add?equId=${model?.equId}&equName=${model?.equName}&from=scan`,
+  })
+}
+
 function showActions() {
   show.value = true
 }
@@ -157,6 +293,7 @@
 function close() {
   show.value = false
 }
+
 function select({ item, index }) {
   console.error(model?.equId)
   console.error(!model?.equId)
@@ -180,9 +317,58 @@
       break
   }
 }
+
+// 澶勭悊缁翠慨璇锋眰鐐瑰嚮浜嬩欢
+function handleReqClick(item) {
+  uni.navigateTo({
+    url: `/pages/repair/req-detail?id=${item.id}`,
+  })
+}
+
+defineExpose({ handleReqClick })
+
+function selectStatus(val: string) {
+  selectedStatus.value = val
+}
+
+function handleStatusChangeCancel() {
+  showStatusDialog.value = false
+}
+
+async function handleStatusChangeConfirm() {
+  if (!selectedStatus.value) {
+    uni.showToast({ title: '璇烽�夋嫨璁惧鐘舵��', icon: 'none' })
+    return
+  }
+  if (!changeReason.value.trim()) {
+    uni.showToast({ title: '璇峰~鍐欏彉鏇村師鍥�', icon: 'none' })
+    return
+  }
+  const params: EimsEquStatuBo = {
+    equId: model.equId,
+    beforeChange: model.status,
+    afterChange: selectedStatus.value,
+    changeDesc: changeReason.value,
+    orderStatus: '0',
+  }
+  try {
+    await addEquStatu(params)
+    uni.showToast({ title: '鎻愪氦鎴愬姛锛屽緟绠$悊鍛樼‘璁�', icon: 'success' })
+    showStatusDialog.value = false
+    // 鍙�夛細鍒锋柊璁惧淇℃伅
+    initData(model.assetNo)
+  } catch (e) {
+    uni.showToast({ title: '鎻愪氦澶辫触', icon: 'none' })
+  }
+}
+
 onLoad((options) => {
+  uni.$on('list-refresh', loadRepairData)
   scanResult.value = options?.result
   initData(options?.result)
+})
+onUnload(() => {
+  uni.$off('list-refresh', loadRepairData)
 })
 </script>
 
@@ -212,4 +398,37 @@
 :deep(.wd-card__title-content) {
   padding: 16rpx 0 !important;
 }
+.status-option {
+  display: inline-block;
+  padding: 10rpx 24rpx;
+  margin: 8rpx 8rpx 8rpx 0;
+  border-radius: 8rpx;
+  border: 1px solid #eee;
+  background: #f7f7f7;
+  color: #666;
+  cursor: pointer;
+}
+.status-option.active {
+  background: $uni-color-primary;
+  color: #fff;
+  border-color: $uni-color-primary;
+}
+.popup-container {
+  width: 600rpx;
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 32rpx 24rpx 24rpx 24rpx;
+}
+.popup-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  text-align: center;
+  margin-bottom: 24rpx;
+}
+.popup-actions {
+  display: flex;
+  margin-top: 24rpx;
+  gap: 16rpx;
+  justify-content: space-around;
+}
 </style>

--
Gitblit v1.9.3