| 
					
				 | 
			
			
				@@ -1,5 +1,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <script setup lang="ts"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { ref, reactive, nextTick } from 'vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import * as XLSX from 'xlsx';  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { Delete } from '@element-plus/icons-vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import Drawer from '@/components/Drawer/index.vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import type { FormInstance, FormRules } from 'element-plus' 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,6 +93,49 @@ const addDeviceSn = (id: number, type: number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   drawerSnRef.value?.openDrawer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const drawer = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 导入xlsx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 组件状态变化的回调 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const uploadExcelFile = (event:any) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const files = event.target.files;   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (files.length === 0) return;   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const file = files[0];   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const reader = new FileReader();   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      reader.onload = (e:any) => {   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const data = new Uint8Array(e.target.result);   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const workbook = XLSX.read(data, { type: 'array' });   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 假设我们知道第一个工作表包含我们需要的数据   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const firstSheetName = workbook.SheetNames[0];   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const worksheet:any = workbook.Sheets[firstSheetName];   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 假设我们知道 t_sn 是第一列   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const tSnColumn = 'A'; // 或者使用 XLSX.utils.decode_col(columnNumber) 来从列号获取列名   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const columnNumber = XLSX.utils.decode_col(tSnColumn); // 但实际上我们可能直接知道列号,如 0   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 使用 sheet_to_json 但只选择我们需要的列   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const json = XLSX.utils.sheet_to_json(worksheet, { header: 1, range: XLSX.utils.decode_range(worksheet['!ref']) }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 如果表头不是第一行,或者你不想要表头,可以调整 header 选项   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 提取 t_sn 列的数据(假设表头在第一行,且 t_sn 是第一列)   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let tSnData:any = json.map((row:any) => row[0]); // 假设 t_sn 是第一列,所以使用 row[0]   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let snArray = tSnData.map((sn:any) => ({ sn: sn })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        snArray = snArray.slice(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let arrs = [...tableSnData.value,...snArray] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 去重 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let seen = new Set();   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tableSnData.value = arrs.filter((item:any) => {   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return seen.has(item.sn) ? false : seen.add(item.sn) || true;   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        });  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log('打印',tableSnData.value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 注意:如果 t_sn 列不是第一列,你需要调整索引号   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 例如,如果 t_sn 是第三列,则使用 row[2]   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      };   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      reader.readAsArrayBuffer(file); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const getDeviceSn = () => SNDataMap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const clearDeviceSn = () => SNDataMap.clear() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const deleteDeviceSn = (id: number) => SNDataMap.delete(id) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -104,7 +148,7 @@ defineExpose({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  <Drawer ref="drawerSnRef" :handleClose="callbackSnDrawer" size="30%"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  <Drawer ref="drawerSnRef" :handleClose="callbackSnDrawer" size="50%"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     <el-card class="box-card" shadow="never"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       <template #header> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         <div class="sn-header"> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -114,6 +158,7 @@ defineExpose({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           <el-button type="primary" @click="addSn(ruleSnFormRef)">添加</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-button type="success" @click="drawer = true">导入xlsx</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       <el-table 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -143,7 +188,11 @@ defineExpose({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <el-drawer v-model="drawer" title="导入xlsx" size="50%" :destroy-on-close="true"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <input type="file" @change="uploadExcelFile" accept=".xlsx, .xls" />  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    </el-drawer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   </Drawer> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <style scoped lang="scss"> 
			 |