xuzhancheng 3 nedēļas atpakaļ
vecāks
revīzija
2502daa4d5

+ 97 - 74
yudao-ui-admin-vue3/src/views/pressure2/schedule/components/ShiftSchedule.vue

@@ -4,11 +4,12 @@
       <el-table v-loading="loading" :data="tableData" border @selection-change="handleSelectionChange"
         @sort-change="handleSortChange" class="shift-schedule-table" ref="tableRef" :row-class-name="getRowClassName">
         <el-table-column type="selection" width="55" fixed="left" :selectable="isSelectable" />
+        <el-table-column type="index" label="序号" width="65" align="center" fixed="left" />
         <el-table-column label="日期" prop="date" width="170" align="center" fixed="left" sortable>
           <template #default="{ row }">
             <div class="date-cell">
               <el-date-picker v-model="row.date" type="date" value-format="YYYY-MM-DD" placeholder="选择日期"
-                :clearable="false" class="!w-120px" :disabled="!canEdit(row)" @change="handleDateChange(row)" />
+                :clearable="false" class="!w-120px" :disabled="!canEditDate(row)" @change="handleDateChange(row)" />
             </div>
           </template>
         </el-table-column>
@@ -20,13 +21,14 @@
           <template #default="{ row }">
             <div>
               <!-- 不可编辑状态:只显示检验员名称 -->
-              <div v-if="!canEdit(row)" class="checker-display">
+              <div v-if="!canEditCheckers(row)" class="checker-display">
                 {{ getCheckerNames(row) || '-' }}
               </div>
 
               <!-- 可编辑状态:使用Popover -->
               <el-popover v-else placement="bottom-start" :width="600" trigger="click"
-                popper-class="checker-select-popover" @show="() => handlePopoverShow(row)">
+                popper-class="checker-select-popover" @show="() => handlePopoverShow(row)"
+                @hide="() => handlePopoverHide(row)">
                 <template #reference>
                   <div class="checker-trigger" :class="{ 'has-checkers': getCheckerNames(row) }" @click.stop>
                     <span class="checker-text">{{ getCheckerNames(row) || '请选择检验员' }}</span>
@@ -109,6 +111,14 @@
                     <span class="status-dot" style="background-color: #f56c6c;"></span>
                     <span>检测中</span>
                   </div>
+                  <div class="legend-item">
+                    <span class="status-dot" style="background-color: #909399;"></span>
+                    <span>部分办结</span>
+                  </div>
+                  <div class="legend-item">
+                    <span class="status-dot" style="background-color: #303133;"></span>
+                    <span>已办结</span>
+                  </div>
                 </div>
               </template>
               <div class="flex items-center justify-center gap-6px cursor-help">
@@ -130,7 +140,7 @@
           <template #default="{ row }">
             <el-tag v-if="row.isCopied && !row.submitted" type="warning" size="small">已复制</el-tag>
             <el-button v-else size="small" :type="row.modified ? 'success' : 'primary'"
-              :disabled="row.status === 100 || !canEdit(row)" @click="handleCopy(row)">
+              :disabled="!canEditCheckers(row)" @click="handleCopy(row)">
               复制
             </el-button>
           </template>
@@ -190,6 +200,7 @@ interface ScheduleRow {
   status?: number // 状态, 100 已排期 200 待约检 300 已受理 400 检测中
   isCopied?: boolean // 是否为复制的行
   submitted?: boolean // 是否已提交
+  sourceId?: string
 }
 
 const loading = ref(false)
@@ -277,13 +288,48 @@ const setCheckerSelectRef = (el: any, rowId: string) => {
   }
 }
 const inspectors = ref()
+// 从 teamList 重新构建 inspectors,保证是最新数据
+const buildInspectorsFromTeamList = (teamList: any[]): any[] => {
+  if (!teamList) return []
+  return teamList.flatMap(team => {
+    const teamMembers: any[] = []
+    if (team.leaders && team.leaders.length > 0) {
+      team.leaders.forEach((leader: any) => {
+        if (leader) {
+          teamMembers.push({
+            memberId: leader.id,
+            groupTeamId: team.groupTeamId,
+            leaderId: leader.id,
+            member: leader,
+            isLeader: true
+          })
+        }
+      })
+    }
+    if (team.members && team.members.length > 0) {
+      team.members.forEach((member: any) => {
+        if (member) {
+          teamMembers.push({
+            memberId: member.id,
+            groupTeamId: team.groupTeamId,
+            leaderId: team.leaders?.[0]?.id || '',
+            member: member,
+            isLeader: false
+          })
+        }
+      })
+    }
+    return teamMembers
+  })
+}
 // 处理 Popover 显示
 const handlePopoverShow = async (row: ScheduleRow) => {
   if (!canEdit(row)) {
     return
   }
 
-  inspectors.value = row.inspectors
+  // 从当前 teamList 重新构建 inspectors,确保拿到最新数据
+  inspectors.value = buildInspectorsFromTeamList(row.teamList)
   currentEditingRow.value = row
 
   const checkerSelectRef = checkerSelectRefs.value[row.id]
@@ -291,12 +337,6 @@ const handlePopoverShow = async (row: ScheduleRow) => {
   // 加载检验员列表
   const deptId = userStore.getUser.deptId?.toString() || props.relateDepartment
   await checkerSelectRef.getCheckerList(deptId)
-  console.log(row.inspectors)
-}
-
-// 关闭Popover
-const closePopover = () => {
-  currentEditingRow.value = null
 }
 
 // 处理检验员选择变化
@@ -332,8 +372,13 @@ const handleCheckerSelectChange = (selectedCheckers: CheckerItem[], row: Schedul
     }
   })
   row.teamList = Array.from(teamMap.values())
-  // 标记为已修改并自动保存
+  // 标记为已修改,Popover 关闭时保存
   row.modified = true
+}
+
+// Popover 关闭时保存
+const handlePopoverHide = (row: ScheduleRow) => {
+  if (!row || !row.modified) return
   autoSaveRow(row)
 }
 
@@ -358,14 +403,14 @@ const calculateWeek = (dateStr: string): string => {
 
 // 获取状态文本
 const getStatusText = (status: number | string | null | undefined): string => {
-  if (status === null || status === undefined) {
-    return '未知'
-  }
+  if (status === null || status === undefined) return '未知'
   const statusMap: Record<number, string> = {
     100: '已排期',
     200: '待约检',
     300: '已受理',
-    400: '检测中'
+    400: '检测中',
+    500: '部分办结',
+    600: '已办结'
   }
   return statusMap[Number(status)] || '未知'
 }
@@ -380,26 +425,35 @@ const formatPipeLength = (val: string | undefined): string => {
 
 // 获取状态样式类
 const getStatusClass = (status: number | string | null | undefined): string => {
-  if (status === null || status === undefined) {
-    return ''
-  }
+  if (status === null || status === undefined) return ''
   const classMap: Record<number, string> = {
     100: 'dot-scheduled',
     200: 'dot-pending-appointment',
     300: 'dot-accepted',
-    400: 'dot-testing'
+    400: 'dot-testing',
+    500: 'dot-partial-done',
+    600: 'dot-done'
   }
   return classMap[Number(status)] || ''
 }
 
-// 判断是否可以编辑
+// 复制行(有 sourceId)在办结前不限制修改
+const isCopyNotDone = (row: ScheduleRow): boolean => {
+  return !!row.sourceId && (row.status === undefined || row.status < 500)
+}
+
+const canEditDate = (row: ScheduleRow): boolean => {
+  if (isCopyNotDone(row)) return true
+  return row.status === 100 || row.status === 200
+}
+
+const canEditCheckers = (row: ScheduleRow): boolean => {
+  if (isCopyNotDone(row)) return true
+  return row.status === 100 || row.status === 200 || row.status === 300 || row.status === 400
+}
+
 const canEdit = (row: ScheduleRow): boolean => {
-  // 受理前(状态为 100 已排期或 200 待约检)的行可以编辑
-  if (row.status === 100 || row.status === 200) {
-    return true
-  }
-  // 其他行不可编辑
-  return false
+  return canEditDate(row) || canEditCheckers(row)
 }
 
 // 获取行类名
@@ -415,11 +469,6 @@ const getRowClassName = ({ row }: { row: ScheduleRow }): string => {
 
 // 复制行
 const handleCopy = (row: ScheduleRow) => {
-  // 限制只有有 confirmOrderId 的情况下才能复制
-  if (!row.confirmOrderId) {
-    ElMessage.warning('只有已确认的订单才能复制')
-    return
-  }
 
   // 计算下一天的日期
   let nextDate = ''
@@ -433,6 +482,7 @@ const handleCopy = (row: ScheduleRow) => {
   const newRow: ScheduleRow = {
     ...row,
     sourceIndex: row.index,
+    sourceId: row.sourceId || row.id,
     date: nextDate, // 设置为下一天
     week: nextWeek, // 设置对应的星期
     isCopied: true, // 标记为复制的行
@@ -497,44 +547,8 @@ const handleQuery = async () => {
     isCopied: false,
     submitted: true
   }))
-  tableData.value.forEach((row, index) => {
-    const inspectors = row.teamList?.flatMap(team => {
-      const teamMembers = []
-
-      // 处理组长
-      if (team.leaders && team.leaders.length > 0) {
-        team.leaders.forEach(leader => {
-          if (leader) {
-            teamMembers.push({
-              memberId: leader.id,
-              groupTeamId: team.groupTeamId,
-              leaderId: leader.id,
-              member: leader,
-              isLeader: true
-            })
-          }
-        })
-      }
-
-      // 处理组员
-      if (team.members && team.members.length > 0) {
-        team.members.forEach(member => {
-          if (member) {
-            teamMembers.push({
-              memberId: member.id,
-              groupTeamId: team.groupTeamId,
-              leaderId: team.leaders?.[0]?.id || '',
-              member: member,
-              isLeader: false
-            })
-          }
-        })
-      }
-
-      return teamMembers
-    }) || []
-    row.inspectors = inspectors
-    console.log('inspectors', inspectors)
+  tableData.value.forEach((row) => {
+    row.inspectors = buildInspectorsFromTeamList(row.teamList)
   })
   loading.value = false
 }
@@ -549,12 +563,13 @@ const autoSaveRow = async (row: ScheduleRow) => {
   if (!row.checkers || row.checkers.length === 0) {
     return
   }
-  // 校验:同 confirmOrderId 日期不能重复
-  if (row.confirmOrderId) {
-    const sameGroup = tableData.value.filter(r => r.confirmOrderId === row.confirmOrderId)
+  // 校验:同源排期(sourceId 或 id)的日期不能重复
+  const sourceOrId = row.sourceId || row.id
+  if (sourceOrId) {
+    const sameGroup = tableData.value.filter(r => (r.sourceId === sourceOrId || r.id === sourceOrId))
     const duplicate = sameGroup.some(item => item.date === row.date && item !== row)
     if (duplicate) {
-      ElMessage.warning('同一个约检确认单下日期不能重复')
+      ElMessage.warning('同一源排期下日期不能重复')
       return
     }
   }
@@ -891,6 +906,14 @@ onMounted(async () => {
 .dot-testing {
   background: #f56c6c;
 }
+
+.dot-partial-done {
+  background: #909399;
+}
+
+.dot-done {
+  background: #303133;
+}
 </style>
 
 <style lang="scss">

+ 14 - 0
yudao-ui-admin-vue3/src/views/pressure2/schedule/index.vue

@@ -147,6 +147,7 @@
                           <span v-if="task.equipDistrictName && task.equipStreetName">-</span>
                           <span v-if="task.equipStreetName">{{ task.equipStreetName }}</span>
                         </div>
+                        <div class="text-[12px] text-[#015293]">{{ getStatusText(task) }}</div>
                       </div>
                       <el-button
                         class="delete-btn"
@@ -227,6 +228,19 @@ const EQUIP_TYPE_NAMES: Record<string, string> = {
   [EQUIP_TYPES.CONTAINER]: '容器',
   [EQUIP_TYPES.BOILER]: '锅炉'
 } as const
+const getStatusText = (taskItem): string => {
+  const { status } = taskItem
+  if (status === null || status === undefined) return '未知'
+  const statusMap: Record<number, string> = {
+    100: '已排期',
+    200: '待约检',
+    300: '已受理',
+    400: '检测中',
+    500: '部分办结',
+    600: '已办结'
+  }
+  return statusMap[Number(status)] || '未知'
+}
 
 // 查询参数
 const queryParams = ref({

+ 18 - 2
yudao-ui-admin-vue3/src/views/pressure2/schedule/pipeindex.vue

@@ -35,8 +35,8 @@
           class="!w-150px"
         >
           <el-option label="全部" value=""/>
-          <el-option label="年度检查" value="100"/>
-          <el-option label="定期检验" value="200"/>
+          <el-option label="定期检验" value="100"/>
+          <el-option label="年度检查" value="200"/>
         </el-select>
       </el-form-item>
       <el-form-item label="单位" prop="unitName">
@@ -79,6 +79,8 @@
             <el-option label="待约检" value="200"/>
             <el-option label="已受理" value="300"/>
             <el-option label="检测中" value="400"/>
+            <el-option label="部分办结" value="500"/>
+            <el-option label="已办结" value="600"/>
           </el-select>
         </el-form-item>
       </template>
@@ -212,6 +214,7 @@
                           <span v-if="task.equipDistrictName && task.equipStreetName">-</span>
                           <span v-if="task.equipStreetName">{{ task.equipStreetName }}</span>
                         </div>
+                        <div class="text-[12px] text-[#015293]">{{ getStatusText(task) }}</div>
                       </div>
                       <el-button
                         class="delete-btn"
@@ -344,6 +347,19 @@ const showDetailDialog = ref(false)
 
 // 添加任务ID数组
 const taskIds = ref<string[]>([])
+const getStatusText = (taskItem): string => {
+  const { status } = taskItem
+  if (status === null || status === undefined) return '未知'
+  const statusMap: Record<number, string> = {
+    100: '已排期',
+    200: '待约检',
+    300: '已受理',
+    400: '检测中',
+    500: '部分办结',
+    600: '已办结'
+  }
+  return statusMap[Number(status)] || '未知'
+}
 
 // 添加 watch 监听器
 watch(currentDate, (newDate) => {