yanghao hace 6 horas
padre
commit
d1509ddb12

+ 1 - 1
.env.local

@@ -4,7 +4,7 @@ NODE_ENV=development
 VITE_DEV=true
 
 # 请求路径  http://192.168.188.149:48080  https://iot.deepoil.cc
-VITE_BASE_URL='https://iot.deepoil.cc'
+VITE_BASE_URL='http://192.168.188.149:48080'
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server

+ 5 - 0
src/api/pms/inspect/order/index.ts

@@ -85,5 +85,10 @@ export const IotInspectOrderApi = {
   // 列表接口
   getFaultReportList: async (params: any) => {
     return await request.get({ url: `/rq/report/failure/page`, params })
+  },
+
+  // 异常设备列表
+  getExceptionDeviceList: async (params: any) => {
+    return await request.get({ url: `/rq/iot-inspect-order/exception/device`, params })
   }
 }

+ 1 - 2
src/views/report-statistics/device_book/index2.vue

@@ -413,14 +413,13 @@ const statusChartOption = computed(() => {
   return {
     tooltip: {
       trigger: 'item',
-      formatter: '{a} <br/>{b}: {c} ({d}%)'
+      formatter: '{b}: {c} ({d}%)'
     },
     legend: {
       show: false
     },
     series: [
       {
-        name: ' ',
         type: 'pie',
         radius: ['40%', '70%'],
         avoidLabelOverlap: false,

+ 307 - 106
src/views/report-statistics/inspection_order/index.vue

@@ -12,14 +12,24 @@
           <div style="border-radius: 10px">
             <div
               class="stat-card bg-blue-gradient"
-              :style="{ border: statusList.all ? '2px solid #0050b3' : '' }"
-              @click="getList('all')"
+              :class="{ 'stat-card-selected': statusList.all }"
+              @click="
+                () => {
+                  queryParams.pageNo = 1
+                  getList('all')
+                }
+              "
             >
               <Icon icon="ep:histogram" :size="40" />
               <div class="card-title">工单数量</div>
-              <div class="card-value pt-5">{{
-                deviceCount.finished + deviceCount.ignore + deviceCount.todo
-              }}</div>
+
+              <div class="card-value pt-5">
+                <CountTo
+                  class="text-2xl"
+                  :end-val="deviceCount.finished + deviceCount.ignore + deviceCount.todo || 0"
+                  :decimals="0"
+                />
+              </div>
             </div>
           </div>
         </el-col>
@@ -27,13 +37,20 @@
         <el-col :span="4">
           <div
             style="border-radius: 10px"
-            @click="getList('finished')"
-            :style="{ border: statusList.finished ? '2px solid #0050b3' : '' }"
+            @click="
+              () => {
+                queryParams.pageNo = 1
+                getList('finished')
+              }
+            "
+            :class="{ 'stat-card-selected': statusList.finished }"
           >
             <div class="stat-card bg-green-gradient">
               <Icon icon="ep:finished" :size="40" />
               <div class="card-title">完成数量</div>
-              <div class="card-value pt-5">{{ deviceCount.finished }}</div>
+              <div class="card-value pt-5">
+                <CountTo class="text-2xl" :end-val="deviceCount.finished || 0" :decimals="0" />
+              </div>
             </div>
           </div>
         </el-col>
@@ -41,13 +58,20 @@
         <el-col :span="4">
           <div
             style="border-radius: 10px"
-            @click="getList('todo')"
-            :style="{ border: statusList.todo ? '2px solid #0050b3' : '' }"
+            @click="
+              () => {
+                queryParams.pageNo = 1
+                getList('todo')
+              }
+            "
+            :class="{ 'stat-card-selected': statusList.todo }"
           >
             <div class="stat-card bg-orange-gradient">
               <Icon icon="ep:more-filled" :size="40" />
               <div class="card-title">未完成数量</div>
-              <div class="card-value pt-5">{{ deviceCount.todo }}</div>
+              <div class="card-value pt-5">
+                <CountTo class="text-2xl" :end-val="deviceCount.todo || 0" :decimals="0" />
+              </div>
             </div>
           </div>
         </el-col>
@@ -55,36 +79,66 @@
         <el-col :span="4">
           <div
             style="border-radius: 10px"
-            @click="getList('ignore')"
-            :style="{ border: statusList.ignore ? '2px solid #0050b3' : '' }"
+            @click="
+              () => {
+                queryParams.pageNo = 1
+                getList('ignore')
+              }
+            "
+            :class="{ 'stat-card-selected': statusList.ignore }"
           >
             <div class="stat-card bg-green-gradient">
               <Icon icon="ep:hide" :size="40" />
               <div class="card-title">已忽略</div>
-              <div class="card-value pt-5">{{ deviceCount.ignore }}</div>
+              <div class="card-value pt-5">
+                <CountTo class="text-2xl" :end-val="deviceCount.ignore || 0" :decimals="0" />
+              </div>
             </div>
           </div>
         </el-col>
 
         <el-col :span="4">
-          <div style="border-radius: 10px">
-            <div class="stat-card bg-red-gradient">
+          <div
+            style="border-radius: 10px"
+            @click="
+              () => {
+                queryParams.pageNo = 1
+                getExceptionList()
+              }
+            "
+          >
+            <div
+              class="stat-card bg-red-gradient"
+              :class="{ 'stat-card-selected': statusList.exception }"
+            >
               <Icon icon="ep:bell" :size="40" />
               <div class="card-title">异常设备数量</div>
-              <div class="card-value pt-5">{{ exceptions?.exceptionNum || 0 }}</div>
+              <div class="card-value pt-5">
+                <CountTo class="text-2xl" :end-val="exceptions?.exceptionNum || 0" :decimals="0" />
+              </div>
             </div>
           </div>
         </el-col>
 
         <el-col :span="4">
-          <div style="border-radius: 10px" @click="getExceptionPoint">
+          <div
+            style="border-radius: 10px"
+            @click="
+              () => {
+                queryParams.pageNo = 1
+                getExceptionPoint()
+              }
+            "
+          >
             <div
               class="stat-card bg-warn-gradient"
-              :style="{ border: statusList.exceptionPoint ? '2px solid #0050b3' : '' }"
+              :class="{ 'stat-card-selected': statusList.exceptionPoint }"
             >
               <Icon icon="ep:info-filled" :size="40" />
               <div class="card-title">异常点数量</div>
-              <div class="card-value pt-5">{{ exceptionPoint.value }}</div>
+              <div class="card-value pt-5">
+                <CountTo class="text-2xl" :end-val="exceptionPoint.value || 0" :decimals="0" />
+              </div>
             </div>
           </div>
         </el-col>
@@ -102,8 +156,55 @@
 
       <!-- 列表 -->
       <ContentWrap style="border: 0; margin-top: 10px">
+        <!-- 异常设备 -->
+        <el-table
+          v-if="isException"
+          v-loading="loading"
+          :data="list3"
+          :stripe="true"
+          :show-overflow-tooltip="true"
+        >
+          <el-table-column :label="t('iotDevice.serial')" width="70" align="center">
+            <template #default="scope">
+              {{ scope.$index + 1 }}
+            </template>
+          </el-table-column>
+
+          <el-table-column label="设备编码" align="center" prop="deviceCode" />
+          <el-table-column :label="t('monitor.deviceName')" align="center" prop="deviceName" />
+          <el-table-column label="工单数量" align="center" prop="orderCount" />
+        </el-table>
+
+        <!-- 巡检异常点 -->
         <el-table
-          v-if="!isExceptionPoint"
+          v-else-if="isExceptionPoint"
+          v-loading="loading"
+          :data="list2"
+          :stripe="true"
+          :show-overflow-tooltip="true"
+        >
+          <el-table-column :label="t('iotDevice.serial')" width="70" align="center">
+            <template #default="scope">
+              {{ scope.$index + 1 }}
+            </template>
+          </el-table-column>
+          <el-table-column :label="t('bomList.name')" align="center" prop="orderName" />
+          <el-table-column :label="t('iotDevice.code')" align="center" prop="deviceCode" />
+          <el-table-column :label="t('monitor.deviceName')" align="center" prop="deviceName" />
+          <el-table-column :label="t('operationFill.duty')" align="center" prop="charge" />
+          <el-table-column :label="t('inspect.InspectionItems')" align="center" prop="item" />
+          <el-table-column :label="t('inspect.isException')" align="center" prop="ifNormal">
+            <template #default="scope">
+              <span v-if="scope.row.ifNormal" style="color: dodgerblue">正常</span>
+              <span v-else-if="scope.row.ifNormal === null" style="color: #101010">待填写</span>
+              <span v-else-if="!scope.row.ifNormal" style="color: orangered">异常</span>
+            </template>
+          </el-table-column>
+          <el-table-column :label="t('inspect.exceptionDes')" align="center" prop="description" />
+        </el-table>
+
+        <el-table
+          v-else
           v-loading="loading"
           :row-class-name="tableRowClassName"
           :data="list"
@@ -160,21 +261,6 @@
             min-width="110"
           />
 
-          <!-- 
-          <el-table-column
-            :label="t('inspect.generateTime')"
-            align="center"
-            prop="createTime"
-            :formatter="dateFormatter"
-            min-width="180px"
-          />
-          <el-table-column
-            :label="t('inspect.executeTime')"
-            align="center"
-            prop="executeDate"
-            :formatter="dateFormatter"
-            min-width="180px"
-          /> -->
           <el-table-column
             :label="t('iotMaintain.operation')"
             align="center"
@@ -189,34 +275,6 @@
           </el-table-column>
         </el-table>
 
-        <!-- 巡检异常点 -->
-        <el-table
-          v-else
-          v-loading="loading"
-          :data="list2"
-          :stripe="true"
-          :show-overflow-tooltip="true"
-        >
-          <el-table-column :label="t('iotDevice.serial')" width="70" align="center">
-            <template #default="scope">
-              {{ scope.$index + 1 }}
-            </template>
-          </el-table-column>
-          <el-table-column :label="t('bomList.name')" align="center" prop="orderName" />
-          <el-table-column :label="t('iotDevice.code')" align="center" prop="deviceCode" />
-          <el-table-column :label="t('monitor.deviceName')" align="center" prop="deviceName" />
-          <el-table-column :label="t('operationFill.duty')" align="center" prop="charge" />
-          <el-table-column :label="t('inspect.InspectionItems')" align="center" prop="item" />
-          <el-table-column :label="t('inspect.isException')" align="center" prop="ifNormal">
-            <template #default="scope">
-              <span v-if="scope.row.ifNormal" style="color: dodgerblue">正常</span>
-              <span v-else-if="scope.row.ifNormal === null" style="color: #101010">待填写</span>
-              <span v-else-if="!scope.row.ifNormal" style="color: orangered">异常</span>
-            </template>
-          </el-table-column>
-          <el-table-column :label="t('inspect.exceptionDes')" align="center" prop="description" />
-        </el-table>
-
         <!-- 分页 -->
         <Pagination
           :total="total"
@@ -270,15 +328,38 @@ const queryParams = reactive({
   deptId: undefined,
   deviceIds: undefined
 })
-const queryFormRef = ref() // 搜索的表单
 
 let exceptions = ref(null)
 let exceptionPoint = ref([])
 let deviceCount = ref([])
 
+// const handleDeptNodeClick = async (row) => {
+//   queryParams.status = undefined
+//   queryParams.deptId = row.id
+//   await getList()
+//   await getCounts()
+// }
+
 const handleDeptNodeClick = async (row) => {
+  queryParams.status = undefined
   queryParams.deptId = row.id
-  await getList()
+
+  // 保持当前表格视图和状态
+  if (isExceptionPoint.value) {
+    // 当前显示异常点表
+    queryParams.pageNo = 1
+    await getPointList()
+  } else if (isException.value) {
+    // 当前显示异常设备表
+    queryParams.pageNo = 1
+    await getExceptionList()
+  } else {
+    // 当前显示普通工单表
+    const currentStatus = Object.keys(statusList.value).find((key) => statusList.value[key])
+    queryParams.pageNo = 1
+    await getList(currentStatus || 'all', false) // 不重置状态
+  }
+
   await getCounts()
 }
 
@@ -306,6 +387,9 @@ let isExceptionPoint = ref(false)
 const list2 = ref<IotInspectItemVO[]>([]) // 列表的数据
 
 const getPointList = async () => {
+  isException.value = false
+  isExceptionPoint.value = true
+
   loading.value = true
   try {
     queryParams.status = '异常'
@@ -326,13 +410,77 @@ const getExceptionPoint = () => {
   isExceptionPoint.value = true
   getPointList()
 }
-/** 查询列表 */
-const getList = async (status: string = 'all') => {
+
+let isException = ref(false)
+const list3 = ref([])
+const getExceptionList = async () => {
+  isException.value = true
   isExceptionPoint.value = false
+
   Object.keys(statusList.value).forEach((key) => {
     statusList.value[key] = false
   })
-  statusList.value[status] = true
+  statusList.value['exception'] = true
+
+  loading.value = true
+  try {
+    queryParams.status = undefined
+    const data = await IotInspectOrderApi.getExceptionDeviceList(queryParams)
+    list3.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+/** 查询列表 */
+// const getList = async (status: string = '') => {
+//   isExceptionPoint.value = false
+//   isException.value = false
+
+//   Object.keys(statusList.value).forEach((key) => {
+//     statusList.value[key] = false
+//   })
+//   statusList.value[status] = true
+//   loading.value = true
+//   try {
+//     if (status === 'all') {
+//       queryParams.status = undefined
+//     } else if (status === 'todo') {
+//       queryParams.status = 'todo'
+//     } else if (status === 'finished') {
+//       queryParams.status = 'finished'
+//     } else if (status === 'ignore') {
+//       queryParams.status = 'ignore'
+//     }
+//     const data = await IotInspectOrderApi.getIotInspectOrderList(queryParams)
+//     list.value = data.list
+//     total.value = data.total
+//   } finally {
+//     loading.value = false
+//   }
+// }
+
+// const getAllList = async () => {
+//   if (isExceptionPoint.value) {
+//     await getPointList()
+//   } else if (isException.value) {
+//     await getExceptionList()
+//   } else {
+//     await getList()
+//   }
+// }
+
+const getList = async (status: string = '', shouldResetStatus = true) => {
+  isExceptionPoint.value = false
+  isException.value = false
+
+  if (shouldResetStatus) {
+    Object.keys(statusList.value).forEach((key) => {
+      statusList.value[key] = false
+    })
+    statusList.value[status] = true
+  }
+
   loading.value = true
   try {
     if (status === 'all') {
@@ -352,14 +500,76 @@ const getList = async (status: string = 'all') => {
   }
 }
 
+// 修改 getAllList 函数
 const getAllList = async () => {
   if (isExceptionPoint.value) {
     await getPointList()
+  } else if (isException.value) {
+    await getExceptionList()
   } else {
-    await getList()
+    // 获取当前选中的状态
+    const currentStatus = Object.keys(statusList.value).find((key) => statusList.value[key])
+    await getList(currentStatus || '', false) // 不重置状态
   }
 }
 
+// watch(
+//   dateType,
+//   () => {
+//     const now = new Date()
+//     let startTime: Date
+//     let endTime: Date
+
+//     switch (dateType.value) {
+//       case 'year':
+//         // 当年:1月1日 00:00:00 到 12月31日 23:59:59
+//         startTime = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0)
+//         endTime = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999)
+//         break
+
+//       case 'month':
+//         // 当月:月初 00:00:00 到 月末 23:59:59
+//         startTime = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0, 0)
+//         // 下个月的第0天就是当月的最后一天
+//         endTime = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999)
+//         break
+
+//       case 'day':
+//         // 当日:当天 00:00:00 到 23:59:59
+//         const year = now.getFullYear()
+//         const month = now.getMonth()
+//         const date = now.getDate()
+//         startTime = new Date(year, month, date, 0, 0, 0, 0)
+//         endTime = new Date(year, month, date, 23, 59, 59, 999)
+//         break
+
+//       default:
+//         startTime = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0)
+//         endTime = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999)
+//     }
+
+//     // 使用本地时间格式化函数,避免时区转换问题
+//     const formatLocalDateTime = (date: Date): string => {
+//       const year = date.getFullYear()
+//       const month = String(date.getMonth() + 1).padStart(2, '0')
+//       const day = String(date.getDate()).padStart(2, '0')
+//       const hours = String(date.getHours()).padStart(2, '0')
+//       const minutes = String(date.getMinutes()).padStart(2, '0')
+//       const seconds = String(date.getSeconds()).padStart(2, '0')
+
+//       return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+//     }
+//     // 设置查询参数 - 使用本地时间格式化
+//     queryParams.createTime = [formatLocalDateTime(startTime), formatLocalDateTime(endTime)]
+
+//     // 重新获取数据
+//     getList()
+//     getCounts()
+//   },
+//   {
+//     immediate: true
+//   }
+// )
 watch(
   dateType,
   () => {
@@ -409,40 +619,27 @@ watch(
     // 设置查询参数 - 使用本地时间格式化
     queryParams.createTime = [formatLocalDateTime(startTime), formatLocalDateTime(endTime)]
 
-    // 重新获取数据
-    getList()
+    // 重新获取数据,保持当前状态和表格视图
+    if (isExceptionPoint.value) {
+      // 当前显示异常点表
+      queryParams.pageNo = 1
+      getPointList()
+    } else if (isException.value) {
+      // 当前显示异常设备表
+      queryParams.pageNo = 1
+      getExceptionList()
+    } else {
+      // 当前显示普通工单表
+      const currentStatus = Object.keys(statusList.value).find((key) => statusList.value[key])
+      queryParams.pageNo = 1
+      getList(currentStatus || 'all', false) // 不重置状态
+    }
     getCounts()
   },
   {
     immediate: true
   }
 )
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  handleQuery()
-}
-
-const reasonFormRef = ref(null)
-const form = reactive({
-  id: undefined,
-  reason: ''
-})
-
-// 重置表单
-const resetForm = () => {
-  reasonFormRef.value?.resetFields()
-}
-
-/** 添加/修改操作 */
-const formRef = ref()
 const openForm = (id?: number) => {
   push({ name: 'InspectOrderDetail', params: { id } })
 }
@@ -510,13 +707,14 @@ onMounted(() => {
   color: white;
   text-align: center;
   font-size: 14px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  /* box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); */
   transition:
     transform 0.3s ease,
     box-shadow 0.3s ease;
   backdrop-filter: blur(12px);
   height: 200px;
   cursor: pointer;
+  overflow: hidden; /* 防止闪光效果溢出 */
 }
 .stat-card::before {
   position: absolute;
@@ -524,11 +722,6 @@ onMounted(() => {
   z-index: -1;
 }
 
-.stat-card:hover {
-  transform: translateY(-4px);
-  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
-}
-
 .card-title {
   margin: 8px 0;
   font-size: 16px;
@@ -551,8 +744,7 @@ onMounted(() => {
 }
 
 .bg-green-gradient {
-  background: linear-gradient(135deg, rgba(101, 226, 136, 0.1), #52d7a2);
-  background-color: rgba(76, 175, 80, 0.1);
+  background: linear-gradient(135deg, rgba(101, 226, 136, 0.3), #52d7a2);
 }
 
 .bg-orange-gradient {
@@ -584,4 +776,13 @@ onMounted(() => {
   top: 0px;
   z-index: 2000;
 }
+
+.stat-card-selected {
+  position: relative;
+  transform: scale(1.06);
+  transition: all 0.2s;
+  box-shadow:
+    0 10px 20px rgba(0, 80, 179, 0.5),
+    0 0 10px rgba(0, 120, 255, 0.4) inset;
+}
 </style>