From f19e5267cc23b1c714dc746239864f33ed715dd9 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 05 十二月 2025 17:55:02 +0800
Subject: [PATCH] 完成地图制作任务功能初版

---
 src/views/fysp/task/components/CompMonitorPlan.vue |  231 +++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 190 insertions(+), 41 deletions(-)

diff --git a/src/views/fysp/task/components/CompMonitorPlan.vue b/src/views/fysp/task/components/CompMonitorPlan.vue
index 954a280..acea676 100644
--- a/src/views/fysp/task/components/CompMonitorPlan.vue
+++ b/src/views/fysp/task/components/CompMonitorPlan.vue
@@ -5,39 +5,156 @@
     @update:model-value="onDateChange"
   >
     <template #header="{ date }">
-      <span>{{ title }}</span>
-      <el-space>
-        <el-tag>鎬昏锛歿{ taskStatistic.total }}</el-tag>
-        <el-tag>瀹屾垚锛歿{ taskStatistic.complete }}</el-tag>
-        <el-tag>鏁存敼锛歿{ taskStatistic.changed }}</el-tag>
-      </el-space>
-      <!-- <span>{{ date }}</span> -->
+      <div style="width: 100%">
+        <el-row justify="space-between">
+          <el-space>
+            <el-tag type="default"
+              >宸℃煡閲忥細{{
+                `${taskStatistic.complete}/${taskStatistic.total}`
+              }}</el-tag
+            >
+            <el-tag type="default"
+              >缁煎悎鏁存敼鐜囷細{{
+                formatPercent(
+                  taskStatistic.changedProblemNum /
+                    taskStatistic.totalProblemNum
+                )
+              }}</el-tag
+            >
+            <!-- <el-tag type="default">鏁存敼锛歿{ taskStatistic.changed }}</el-tag> -->
+          </el-space>
+          <el-space>
+            <el-text>鑱氱劍鐢ㄦ埛锛�</el-text>
+            <el-select
+              v-model="selectedUsers"
+              multiple
+              clearable
+              collapse-tags
+              :max-collapse-tags="1"
+              style="width: 150px"
+            >
+              <el-option
+                v-for="user in taskStatistic.progressPerUser"
+                :key="user.userId"
+                :label="user.userName"
+                :value="user.userName"
+              />
+            </el-select>
+          </el-space>
+        </el-row>
+        <el-row class="m-t-4">
+          <el-space wrap>
+            <el-tag
+              type="default"
+              v-for="user in taskStatistic.progressPerUser"
+              :key="user.userId"
+            >
+              <!-- {{
+                `${user.userName}锛氬贰鏌ラ噺 ${
+                  user.completeTaskNum
+                }锛屽嵆鏃舵暣鏀圭巼 ${formatPercent(
+                  user.changedProblemNumOnTime / user.totalProblemNum
+                )}锛屽钩鍧囪�楁椂 ${
+                  user.avgInspectionTime ? user.avgInspectionTime : '--'
+                }`
+              }} -->
+                {{
+                `${user.userName}锛�${
+                  user.completeTaskNum
+                } | ${formatPercent(
+                  user.changedProblemNumOnTime / user.totalProblemNum
+                )} | ${
+                  user.avgInspectionTime ? user.avgInspectionTime : '--'
+                }`
+              }}
+            </el-tag>
+          </el-space>
+        </el-row>
+      </div>
     </template>
     <template #date-cell="{ data }">
       <div :class="calendarDayClz(data.day)">
         <div style="background-color: #f8f4f4">{{ getDay(data.day) }}</div>
         <template v-if="computeDayTask(data.day)">
-          <!-- <el-divider></el-divider> -->
-          <el-row justify="space-between" class="m-t-16">
+          <el-row
+            v-if="computeDayTask(data.day).totalTaskNum > 0"
+            justify="space-between"
+          >
             <el-space direction="vertical">
-              <el-text size="small">鎬昏</el-text>
-              <el-text>{{ computeDayTask(data.day).totalTaskNum }}</el-text>
+              <el-text size="small" tag="b">宸℃煡閲�</el-text>
+              <el-text size="small"
+                >{{ computeDayTask(data.day).completeTaskNum }} /
+                {{ computeDayTask(data.day).totalTaskNum }}</el-text
+              >
             </el-space>
             <el-space direction="vertical">
-              <el-text size="small">瀹屾垚</el-text>
-              <el-text>{{ computeDayTask(data.day).completeTaskNum }}</el-text>
+              <el-text size="small" tag="b">缁煎悎鏁存敼鐜�</el-text>
+              <el-text size="small">{{
+                formatPercent(
+                  computeDayTask(data.day).changedProblemNum /
+                    computeDayTask(data.day).totalProblemNum
+                )
+              }}</el-text>
             </el-space>
-            <el-space direction="vertical">
-              <el-text size="small">鏁存敼</el-text>
-              <el-text>{{ computeDayTask(data.day).changedTaskNum }}</el-text>
-            </el-space>
-            <!-- <el-statistic title="鎬昏" :value="computeDayTask(data.day).totalTaskNum" />
-            <el-statistic title="瀹屾垚" :value="computeDayTask(data.day).completeTaskNum" />
-            <el-statistic title="鏁存敼" :value="computeDayTask(data.day).changedTaskNum" /> -->
           </el-row>
-          <!-- <div>浠诲姟鎬昏锛歿{ computeDayTask(data.day).totalTaskNum }}</div>
-          <div>浠诲姟瀹屾垚锛歿{ computeDayTask(data.day).completeTaskNum }}</div>
-          <div>浠诲姟鏁存敼锛歿{ computeDayTask(data.day).changedTaskNum }}</div> -->
+          <div style="border-top: 1px solid #0000002f" class="m-t-4"></div>
+          <div
+            v-for="item in computeDayTask(data.day).progressPerUser"
+            :key="item.userId"
+            class="m-t-4"
+          >
+            <el-row justify="space-between">
+              <el-text
+                title="宸℃煡浜哄憳"
+                size="small"
+                :type="
+                  selectedUsers.includes(item.userName) ? 'primary' : 'info'
+                "
+                :tag="selectedUsers.includes(item.userName) ? 'b' : 'span'"
+                >{{ item.userName }}</el-text
+              >
+            </el-row>
+            <el-row justify="space-between">
+              <!-- <el-space> -->
+              <el-text
+                title="宸℃煡閲�"
+                size="small"
+                style="text-align: center; flex: 1"
+                :type="
+                  selectedUsers.includes(item.userName) ? 'primary' : 'info'
+                "
+                :tag="selectedUsers.includes(item.userName) ? 'b' : 'span'"
+                >{{ item.completeTaskNum }}</el-text
+              >
+              <el-text
+                title="鍗虫椂鏁存敼鐜�"
+                size="small"
+                style="text-align: center; flex: 1"
+                :type="
+                  selectedUsers.includes(item.userName) ? 'primary' : 'info'
+                "
+                :tag="selectedUsers.includes(item.userName) ? 'b' : 'span'"
+                >{{
+                  formatPercent(
+                    item.changedProblemNumOnTime / item.totalProblemNum
+                  )
+                }}</el-text
+              >
+              <el-text
+                title="骞冲潎鑰楁椂"
+                size="small"
+                style="text-align: center; flex: 1"
+                :type="
+                  selectedUsers.includes(item.userName) ? 'primary' : 'info'
+                "
+                :tag="selectedUsers.includes(item.userName) ? 'b' : 'span'"
+                >{{
+                  timeUtil.formatSecondsToChinese(item.avgInspectionTime)
+                }}</el-text
+              >
+              <!-- </el-space> -->
+            </el-row>
+          </div>
         </template>
       </div>
     </template>
@@ -47,6 +164,7 @@
 import { ref, computed, onMounted, watch } from 'vue';
 import taskApi from '@/api/fysp/taskApi';
 import dayjs from 'dayjs';
+import timeUtil from '@/utils/time-util';
 
 const props = defineProps({
   task: {
@@ -60,16 +178,9 @@
 });
 const emit = defineEmits(['dateChange']);
 // 閫変腑鏃ユ湡
+const selectedUsers = ref([]);
+// const dateValue = ref(new Date());
 const dateValue = ref();
-// 鏃ュ巻鏍囬
-const title = computed(() => {
-  if (props.task) {
-    // return `${props.task.name}璁″垝`;
-    return `宸℃煡璁″垝`;
-  } else {
-    return '';
-  }
-});
 // 鏃ュ巻鑼冨洿
 const startDay = computed(() => dayjs(props.task.starttime));
 const endDay = computed(() => dayjs(props.task.endtime));
@@ -77,7 +188,6 @@
   startDay.value.toDate(),
   endDay.value.toDate()
 ]);
-// const dateRange = computed(() => [new Date(2024, 4, 27), new Date(2024, 5, 30)]);
 
 // 鏃ユ湡鏄惁鍦ㄤ换鍔¤寖鍥村唴
 function isDayEnable(day) {
@@ -154,14 +264,53 @@
 
 // 鎬讳换鍔$粺璁�
 const taskStatistic = computed(() => {
-  const res = { total: 0, complete: 0, changed: 0 };
+  // const resMap = new Map()
+  const res = {
+    total: 0,
+    complete: 0,
+    changed: 0,
+    changedProblemNum: 0,
+    totalProblemNum: 0
+  };
+  const userMap = new Map();
   props.dayTaskList.forEach((e) => {
     res.total += e.totalTaskNum;
     res.complete += e.completeTaskNum;
     res.changed += e.changedTaskNum;
+    res.changedProblemNum += e.changedProblemNum;
+    res.totalProblemNum += e.totalProblemNum;
+    e.progressPerUser.forEach((user) => {
+      if (!userMap.has(user.userId)) {
+        userMap.set(user.userId, {
+          userName: user.userName,
+          completeTaskNum: 0,
+          changedProblemNumOnTime: 0,
+          totalProblemNum: 0,
+          totalInspectionTime: 0,
+          dayTaskNum: 0
+        });
+      }
+      const userItem = userMap.get(user.userId);
+      userItem.completeTaskNum += user.completeTaskNum;
+      userItem.changedProblemNumOnTime += user.changedProblemNumOnTime;
+      userItem.totalProblemNum += user.totalProblemNum;
+      userItem.totalInspectionTime += user.avgInspectionTime;
+      userItem.dayTaskNum++;
+    });
   });
+  res.progressPerUser = Array.from(userMap.values()).map((user) => ({
+    ...user,
+    completeTaskNum: Math.round(user.completeTaskNum * 100) / 100,
+    avgInspectionTime: timeUtil.formatSecondsToChinese(
+      user.totalInspectionTime / user.dayTaskNum
+    )
+  }));
   return res;
 });
+
+const formatPercent = (num) => {
+  return isNaN(num) ? '0%' : parseInt(num * 100) + '%';
+};
 /********************** 鍒濆鍖� *********************************/
 
 // watch(
@@ -192,16 +341,16 @@
   top: 5px;
 }
 
-::v-deep .el-calendar-table .el-calendar-day {
+:deep(.el-calendar-table .el-calendar-day) {
   height: initial;
   padding: initial;
 }
 
-::v-deep .el-calendar-table .el-calendar-day:hover {
+:deep(.el-calendar-table .el-calendar-day:hover) {
   background-color: transparent;
 }
 
-/* ::v-deep .el-calendar-table td.is-selected {
+/* :deep(.el-calendar-table td.is-selected) {
   background-color: initial;
 } */
 
@@ -228,15 +377,15 @@
   cursor: not-allowed;
 }
 
-/* ::v-deep .el-calendar-table tr td:first-child {
+/* :deep(.el-calendar-table tr td:first-child) {
   border-left: none !important;
 } */
 
-/* ::v-deep .el-calendar-table tr:first-child td {
+/* :deep(.el-calendar-table tr:first-child td) {
   border-top: none;
 } */
 
-/* ::v-deep .el-calendar-table td {
+/* :deep(.el-calendar-table td) {
   border-bottom: none;
   border-right: none;
   vertical-align: top;
@@ -244,7 +393,7 @@
   transition: background-color 0.2s ease;
 } */
 
-::v-deep .el-calendar-table thead th {
+:deep(.el-calendar-table thead th) {
   padding: 12px 0;
   color: #606266;
   font-weight: normal;

--
Gitblit v1.9.3