| 
					
				 | 
			
			
				@@ -2,14 +2,100 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { ref, reactive } from 'vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import { GlobalStore } from '@/stores/index' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import TableBase from '@/components/TableBase/index.vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import { Storehouse_Device_List } from '@/api/storehouse/index' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Storehouse_Device_List, Storehouse_Device_Excel, Storehouse_Device_Take_Stock } from '@/api/storehouse/index' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import type { ColumnProps } from '@/components/TableBase/interface/index' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import ImageCom from '@/components/Image/index.vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import btnview from './modules/btnview.vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { ElMessage } from 'element-plus' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Check, Close } from '@element-plus/icons-vue' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const globalStore = GlobalStore() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const TableRef = ref<InstanceType<typeof TableBase> | null>(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const exportLoading = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const formLabelWidth = ref('120px') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 盘点相关状态 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const takeStockDialogVisible = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const takeStockLoading = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const snList = ref('') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const takeStockResult = ref<any>(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const takeStockStats = ref<any>(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 扫码相关状态 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const scannedSNs = ref<{sn: string}[]>([]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const productNameRequired = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const productModelRequired = ref(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 提取SN中间部分(如果是特定格式) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const extractSN = (fullSN: string): string => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (fullSN.length === 24 && fullSN.startsWith('03') && fullSN.endsWith('000001')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return fullSN.substring(2, 18) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return fullSN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 处理扫码输入 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleScanInput = (event: KeyboardEvent) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 如果是回车键,表示扫码完成 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (event.key === 'Enter') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    event.preventDefault() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    event.stopPropagation() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const currentSN = snList.value.trim() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (currentSN) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const extractedSN = extractSN(currentSN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 检查是否已经存在相同的SN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!scannedSNs.value.some(item => item.sn === extractedSN)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        scannedSNs.value.unshift({ sn: extractedSN }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 清空输入框,准备下一次扫描 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        snList.value = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 检查产品名称和型号是否已填写 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        checkRequiredFields() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 如果已存在,给出提示并清空输入框 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ElMessage.warning('已存在相同的SN,不能重复添加') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        snList.value = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 检查必填字段 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const checkRequiredFields = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  productNameRequired.value = !initParam.T_product_name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  productModelRequired.value = !initParam.T_product_model 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 从扫描列表中移除SN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const removeSN = (index: number) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scannedSNs.value.splice(index, 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 将扫描的SN列表转换为逗号分隔的字符串 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getFormattedSNList = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return scannedSNs.value.map(item => item.sn).join(',') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 显示完整SN内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const showFullSN = (sn: string) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ElMessage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    message: sn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    duration: 3000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    showClose: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const columns: ColumnProps[] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { type: 'index', label: '序号', width: 80 }, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -44,6 +130,123 @@ const initParam = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const searchHandle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TableRef.value?.searchTable() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 导出设备数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const exportDeviceData = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (exportLoading.value) return // 防止重复点击 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  exportLoading.value = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const params = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ...initParam, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const response: any = await Storehouse_Device_Excel(params) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (response.Code === 200 && response.Data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 从URL中提取文件名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const fileUrl = response.Data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const urlParts = fileUrl.split('/') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const fileName = urlParts[urlParts.length - 1] // 获取URL最后一部分作为文件名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 创建下载链接 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const link = document.createElement('a') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      link.href = fileUrl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      link.download = fileName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      link.target = '_blank' // 在新标签页中打开,确保下载 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      document.body.appendChild(link) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      link.click() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      document.body.removeChild(link) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      console.error('导出失败:', response.Msg || '未知错误') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.error('导出失败:', error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exportLoading.value = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 打开盘点弹框 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const openTakeStockDialog = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockDialogVisible.value = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  snList.value = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scannedSNs.value = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockResult.value = null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockStats.value = null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 检查产品名称和型号是否已填写 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  checkRequiredFields() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 执行设备盘点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const executeTakeStock = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (takeStockLoading.value) return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 检查产品名称和型号是否已填写 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!initParam.T_product_name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ElMessage.warning('请输入产品名称') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!initParam.T_product_model) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ElMessage.warning('请输入产品型号') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // 使用扫描的SN列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (scannedSNs.value.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ElMessage.warning('请至少扫描一个SN码') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  let snListToSubmit = getFormattedSNList() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockLoading.value = true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const params = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      User_tokey: globalStore.GET_User_tokey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      T_product_name: initParam.T_product_name || '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      T_product_model: initParam.T_product_model || '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      T_sn_list: snListToSubmit || '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const response: any = await Storehouse_Device_Take_Stock(params) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (response.Code === 200 && response.Data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      takeStockResult.value = response.Data.devices || [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      takeStockStats.value = response.Data.stats || {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 清空扫描列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      scannedSNs.value = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ElMessage.error(response.Msg || '盘点失败') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      console.error('盘点失败:', response.Msg || '未知错误') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ElMessage.error('盘点请求失败') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.error('盘点失败:', error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    takeStockLoading.value = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 关闭盘点弹框 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const closeTakeStockDialog = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockDialogVisible.value = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  snList.value = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scannedSNs.value = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockResult.value = null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  takeStockStats.value = null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  productNameRequired.value = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  productModelRequired.value = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <template> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -56,20 +259,23 @@ const searchHandle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <span class="inline-flex items-center">关键字:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <el-input v-model="initParam.T_name" class="w-50 m-2" type="text" placeholder="按合同编号、出库单号、SN搜索" @change="searchHandle"/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-col :xl="6" :lg="6" :md="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :xl="5" :lg="5" :md="5"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <span class="inline-flex items-center">状态:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择状态~"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               </el-select> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-col :xl="6" :lg="6" :md="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :xl="5" :lg="5" :md="5"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <span class="inline-flex items-center">产品名称:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <el-input class="w-50 m-2" v-model="initParam.T_product_name" type="text" placeholder="按产品名称搜索" @change="searchHandle" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <el-col :xl="6" :lg="6" :md="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :xl="8" :lg="8" :md="8"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <span class="inline-flex items-center">产品型号:</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <el-input class="w-50 m-2" v-model="initParam.T_product_model" type="text" placeholder="按合产品型号搜索" @change="searchHandle" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               <el-button type="primary" @click="searchHandle">搜索</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-button type="success" :loading="exportLoading" @click="exportDeviceData">导出</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-button type="warning" @click="openTakeStockDialog">盘点</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         </div> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -85,6 +291,173 @@ const searchHandle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         <btnview :btnData="row"></btnview> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     </TableBase> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <!-- 盘点弹框 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <el-dialog 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      v-model="takeStockDialogVisible" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      title="设备盘点" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      width="80%" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      :close-on-click-modal="false" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      @close="closeTakeStockDialog" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <div class="take-stock-content"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <!-- SN录入区域 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div class="sn-input-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <h4>设备SN录入</h4> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <!-- 产品信息输入 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div class="product-info-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-form :model="initParam" label-width="80px"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-col :span="16"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-form-item label="产品名称" :label-width="formLabelWidth" :required="true" :error="productNameRequired ? '产品名称为必填项' : ''"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <el-input  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        v-model="initParam.T_product_name"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        placeholder="请输入产品名称(必填)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        @input="checkRequiredFields" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        clearable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-col :span="16"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-form-item label="产品型号" :label-width="formLabelWidth" :required="true" :error="productModelRequired ? '产品型号为必填项' : ''"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <el-input  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        v-model="initParam.T_product_model"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        placeholder="请输入产品型号(必填)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        @input="checkRequiredFields" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        clearable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-col :span="16"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    <el-form-item label="SN" :label-width="formLabelWidth" :required="true"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <el-input 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        v-model="snList" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        placeholder="请输入SN" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        @keydown="handleScanInput" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        clearable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        autofocus 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        size="large" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      <div class="scan-tip">扫描后会自动添加到下方列表,按回车确认</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <!-- 扫描列表 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div class="scanned-list-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <h5>已扫描SN列表 <span v-if="scannedSNs.length > 0" class="sn-count">({{ scannedSNs.length }})</span></h5> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <div v-if="scannedSNs.length === 0" class="empty-list"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-empty description="暂无扫描SN数据" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              v-else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              :data="scannedSNs"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              style="width: 100%; margin-bottom: 16px;"  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              height="250" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              border 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stripe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              highlight-current-row 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            > 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-table-column type="index" label="序号" width="80" align="center" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-table-column prop="sn" label="设备SN" min-width="200" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-table-column label="操作" width="100" align="center"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <template #default="{ $index }"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <el-button type="danger" size="small" @click="removeSN($index)">删除</el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div class="button-group"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-button type="primary" size="large" :loading="takeStockLoading" @click="executeTakeStock"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-icon><Check /></el-icon> 开始盘点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-button size="large" @click="closeTakeStockDialog"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-icon><Close /></el-icon> 取消 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-button> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <!-- 统计信息 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div v-if="takeStockStats" class="stats-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <h4>盘点统计</h4> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-row :gutter="20"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-card class="stat-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="stat-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-value">{{ takeStockStats.total_input || 0 }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-label">输入设备总数</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-card class="stat-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="stat-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-value success">{{ takeStockStats.exists || 0 }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-label">存在于库存</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-card class="stat-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="stat-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-value warning">{{ takeStockStats.in_stock || 0 }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-label">在库设备</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-col :span="6"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <el-card class="stat-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <div class="stat-item"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-value danger">{{ takeStockStats.not_exists || 0 }}</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  <div class="stat-label">不存在于库存</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </el-card> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-col> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <!-- 盘点结果表格 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <div v-if="takeStockResult && takeStockResult.length > 0" class="result-section"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <h4>盘点结果</h4> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <el-table :data="takeStockResult" border style="width: 100%"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column type="index" label="序号" width="60" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_sn" label="设备SN" width="180"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_product_name" label="产品名称" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_product_model" label="产品型号" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_iccid" label="物联网卡号" width="220" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_imei" label="模组IMEI" show-overflow-tooltip /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_in_number" label="入库编号" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column prop="t_out_number" label="出库编号" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column label="状态" width="100"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <template #default="{ row }"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-tag v-if="row.t_state === 1" type="success">已出库</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-tag v-else-if="row.t_state === 2" type="warning">未出库</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-tag v-else type="danger">未入库</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            <el-table-column label="来源" width="80"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              <template #default="{ row }"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-tag v-if="row.t_from_input" type="primary">输入</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                <el-tag v-else type="info">系统</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    </el-dialog> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -104,4 +477,136 @@ const searchHandle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.take-stock-content { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .sn-input-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin-bottom: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    h4 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    h5 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin: 16px 0 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      color: #606266; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font-weight: 500; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .product-info-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      padding: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      background-color: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .el-form-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .el-input { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .scan-input-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .scan-tip { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font-size: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .scanned-list-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin: 20px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      border-top: 1px solid #ebeef5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      padding-top: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .sn-count { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        color: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font-weight: bold; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .empty-list { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        padding: 20px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .sn-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font-family: monospace; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        &.clickable { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          color: #409eff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          text-decoration: underline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          &:hover { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            color: #66b1ff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .manual-input-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      background-color: #f5f7fa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      border-radius: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .button-group { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gap: 12px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .stats-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    margin-bottom: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    h4 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .stat-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      text-align: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .stat-item { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .stat-value { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font-size: 24px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font-weight: bold; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          margin-bottom: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          &.success { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            color: #67c23a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          &.warning { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            color: #e6a23c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          &.danger { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            color: #f56c6c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .stat-label { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font-size: 14px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          color: #909399; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  .result-section { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    h4 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      color: #303133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font-weight: 600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </style> 
			 |