Browse Source

feat: 新增-表格任意位置点击选中/shift多选/选中增加背景色

bxy 1 year ago
parent
commit
597dc1a3a0
1 changed files with 117 additions and 10 deletions
  1. 117 10
      src/views/datamanager/alertformdata/components/common/AlertTable.vue

+ 117 - 10
src/views/datamanager/alertformdata/components/common/AlertTable.vue

@@ -5,11 +5,14 @@
       :data="tableData"
       style="width: 100%"
       height="100%"
-      stripe
       :cell-style="colorOfState"
+      :row-class-name="colorOfRow"
+      @select="handleShiftSelect"
       @selection-change="handleSelectionChange"
+      @row-click="handleRowClick"
     >
       <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column type="index" width="55"></el-table-column>
       <el-table-column label="问题来源" prop="source" width="150">
         <template #default="{ row }">
           {{ getNameBySource(row.source) }}
@@ -23,7 +26,15 @@
       <el-table-column label="问题描述" prop="description" width="400" show-overflow-tooltip>
         <template #default="{ row }">
           <span>{{ getSplicedDes(row.description) }}</span>
-          <span class="detail-text" @click="handleDetailClick(row)"> 详情</span>
+          <span
+            class="detail-text"
+            @click="
+              handleDetailClick(row);
+              $event.stopPropagation();
+            "
+          >
+            详情</span
+          >
         </template>
       </el-table-column>
       <el-table-column label="地点" prop="workspaceId" width="300">
@@ -49,14 +60,17 @@
             :content="row.isHide ? '点此设置为生效问题' : '点此设置为无效问题'"
             placement="top"
           >
-            <el-switch :model-value="!row.isHide" @change="handleShow(row)" />
+            <el-switch :model-value="!row.isHide" @change="handleShow(row)" @click.stop.native />
           </el-tooltip>
           <el-tooltip effect="dark" content="点击标记为加急问题" placement="top">
             <img
               src="/src/assets/images/alert/urgent.png"
               alt=""
               v-if="!isShowTab && !row.priority"
-              @click="handleUrgent(row)"
+              @click="
+                handleUrgent(row);
+                $event.stopPropagation();
+              "
             />
           </el-tooltip>
           <el-tooltip effect="dark" content="点击取消问题加急" placement="top">
@@ -64,7 +78,10 @@
               src="/src/assets/images/alert/urgent-active.png"
               alt=""
               v-if="!isShowTab && row.priority"
-              @click="handleUrgent(row)"
+              @click="
+                handleUrgent(row);
+                $event.stopPropagation();
+              "
             />
           </el-tooltip>
           <el-tooltip effect="dark" content="点击编辑问题" placement="top">
@@ -72,7 +89,10 @@
               src="/src/assets/images/alert/edit.png"
               alt=""
               v-if="isShowTab"
-              @click="handleEdit(row)"
+              @click="
+                handleEdit(row);
+                $event.stopPropagation();
+              "
             />
           </el-tooltip>
           <el-tooltip
@@ -81,7 +101,14 @@
             placement="top"
             v-if="hasDataDeletePermisson()"
           >
-            <img src="/src/assets/images/alert/delete.png" alt="" @click="handleDelete(row)" />
+            <img
+              src="/src/assets/images/alert/delete.png"
+              alt=""
+              @click="
+                handleDelete(row);
+                $event.stopPropagation();
+              "
+            />
           </el-tooltip>
         </template>
       </el-table-column>
@@ -91,7 +118,7 @@
 
 <script setup lang="ts">
   import { ElTable } from 'element-plus';
-  import { onBeforeMount, ref } from 'vue';
+  import { onBeforeMount, onMounted, ref } from 'vue';
   import { getNameBySource, getNameByState } from './constant.question';
   import { useIssueType } from '../../hooks/useIssueType';
   import { useWorkLocation } from '../../hooks/useWorkLocation';
@@ -109,6 +136,8 @@
   const multipleTableRef = ref<InstanceType<typeof ElTable>>();
 
   interface DataSourceItem {
+    index: Number;
+    id: Number;
     source: Number; // 问题单来源:1-AI检测、2-人工上报
     issueType: Number; // 问题单类型
     description: String; // 问题描述
@@ -131,8 +160,60 @@
   const props = defineProps<Props>();
 
   const emits = defineEmits(['update:selection']);
+
+  const startPoint = ref<number | undefined>();
+  const endPoint = ref<number | undefined>();
+  const shiftKeyBoard = ref(false); // shift按钮按住/松开
+
+  const selections = ref<DataSourceItem[]>([]);
   const handleSelectionChange = (selection: any[]) => {
-    emits('update:selection', selection);
+    selections.value = selection;
+    emits('update:selection', selections.value);
+  };
+
+  const handleShiftSelect = (_, row) => {
+    props.tableData.forEach((item, index) => {
+      item.index = index;
+    });
+    // 按住shift
+    if (shiftKeyBoard.value) {
+      // 有起点startPoint
+      if (startPoint.value !== undefined) {
+        endPoint.value = row.index as number;
+        if (startPoint.value > endPoint.value) {
+          let temp = startPoint.value;
+          startPoint.value = endPoint.value;
+          endPoint.value = temp;
+        }
+        setTimeout(() => {
+          for (let i = startPoint.value as number; i < (endPoint.value as number); i++) {
+            multipleTableRef.value!.toggleRowSelection(props.tableData[i], true);
+          }
+        }, 100);
+      }
+      // 没有起点startPoint
+      else {
+        startPoint.value = row.index;
+        endPoint.value = undefined;
+      }
+    }
+    // 没按住shift
+    else {
+      startPoint.value = row.index;
+      endPoint.value = undefined;
+    }
+  };
+
+  const rowClickSelections = ref<DataSourceItem[]>([]);
+  const handleRowClick = (row) => {
+    if (rowClickSelections.value.find((item) => item.id === row.id)) {
+      let index = rowClickSelections.value.findIndex((item) => item.id === row.id);
+      rowClickSelections.value.splice(index, 1);
+      multipleTableRef.value!.toggleRowSelection(row, false);
+    } else {
+      rowClickSelections.value.push(row);
+      multipleTableRef.value!.toggleRowSelection(row, true);
+    }
   };
 
   const handleDetailClick = (row) => {
@@ -171,6 +252,13 @@
     }
   };
 
+  const colorOfRow = ({ row }) => {
+    if (selections.value.includes(row)) {
+      return 'selected-row';
+    }
+    return '';
+  };
+
   const clearAll = () => {
     multipleTableRef.value!.clearSelection();
   };
@@ -182,9 +270,24 @@
     getManualOptions();
     getLocationOptions();
   });
+
+  onMounted(() => {
+    window.addEventListener('keydown', (code) => {
+      if (code.shiftKey) {
+        shiftKeyBoard.value = true;
+      }
+    });
+    window.addEventListener('keyup', (code) => {
+      if (!code.shiftKey) {
+        shiftKeyBoard.value = false;
+        startPoint.value = -1;
+        endPoint.value = -1;
+      }
+    });
+  });
 </script>
 
-<style scoped lang="scss">
+<style scoped lang="less">
   .alert-table-box {
     display: flex;
     flex-direction: column;
@@ -221,5 +324,9 @@
     ::before {
       height: 0px;
     }
+
+    .selected-row {
+      background: #ddefff;
+    }
   }
 </style>