From 5333935ae59999c47653122a669f4326f0173c1c Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 08 一月 2026 14:47:02 +0800
Subject: [PATCH] 确认按钮在左边

---
 src/components/QRCodeGenerator/index.vue |  859 +++++++++++++++++++++++++++++---------------------------
 1 files changed, 442 insertions(+), 417 deletions(-)

diff --git a/src/components/QRCodeGenerator/index.vue b/src/components/QRCodeGenerator/index.vue
index 1708130..fd44f44 100644
--- a/src/components/QRCodeGenerator/index.vue
+++ b/src/components/QRCodeGenerator/index.vue
@@ -1,70 +1,79 @@
 <template>
   <div class="qr-code-generator">
     <!-- 浜岀淮鐮佺敓鎴愯〃鍗� -->
-    <el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="qr-form">
+    <el-form :model="form"
+             :rules="rules"
+             ref="formRef"
+             label-width="120px"
+             class="qr-form">
       <el-row :gutter="20">
         <el-col :span="12">
-          <el-form-item label="鏍囪瘑绫诲瀷" prop="type">
-            <el-select v-model="form.type" placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷" style="width: 100%">
-              <el-option label="浜岀淮鐮�" value="qrcode"></el-option>
-              <el-option label="闃蹭吉鐮�" value="security"></el-option>
+          <el-form-item label="鏍囪瘑绫诲瀷"
+                        prop="type">
+            <el-select v-model="form.type"
+                       placeholder="璇烽�夋嫨鏍囪瘑绫诲瀷"
+                       style="width: 100%">
+              <el-option label="浜岀淮鐮�"
+                         value="qrcode"></el-option>
+              <el-option label="闃蹭吉鐮�"
+                         value="security"></el-option>
             </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="鍐呭" prop="content">
-            <el-input 
-              v-model="form.content" 
-              placeholder="璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�"
-              :type="form.type === 'security' ? 'textarea' : 'text'"
-              :rows="form.type === 'security' ? 3 : 1"
-            ></el-input>
+          <el-form-item label="鍐呭"
+                        prop="content">
+            <el-input v-model="form.content"
+                      placeholder="璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�"
+                      :type="form.type === 'security' ? 'textarea' : 'text'"
+                      :rows="form.type === 'security' ? 3 : 1"></el-input>
           </el-form-item>
         </el-col>
       </el-row>
-      
       <el-row :gutter="20">
         <el-col :span="12">
-          <el-form-item label="灏哄" prop="size">
-            <el-input-number 
-              v-model="form.size" 
-              :min="100" 
-              :max="500" 
-              :step="50"
-              style="width: 100%"
-            ></el-input-number>
+          <el-form-item label="灏哄"
+                        prop="size">
+            <el-input-number v-model="form.size"
+                             :min="100"
+                             :max="500"
+                             :step="50"
+                             style="width: 100%"></el-input-number>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="杈硅窛" prop="margin">
-            <el-input-number 
-              v-model="form.margin" 
-              :min="0" 
-              :max="10" 
-              :step="1"
-              style="width: 100%"
-            ></el-input-number>
+          <el-form-item label="杈硅窛"
+                        prop="margin">
+            <el-input-number v-model="form.margin"
+                             :min="0"
+                             :max="10"
+                             :step="1"
+                             style="width: 100%"></el-input-number>
           </el-form-item>
         </el-col>
       </el-row>
-      
       <el-row :gutter="20">
         <el-col :span="12">
-          <el-form-item label="鍓嶆櫙鑹�" prop="foregroundColor">
-            <el-color-picker v-model="form.foregroundColor" style="width: 100%"></el-color-picker>
+          <el-form-item label="鍓嶆櫙鑹�"
+                        prop="foregroundColor">
+            <el-color-picker v-model="form.foregroundColor"
+                             style="width: 100%"></el-color-picker>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="鑳屾櫙鑹�" prop="backgroundColor">
-            <el-color-picker v-model="form.backgroundColor" style="width: 100%"></el-color-picker>
+          <el-form-item label="鑳屾櫙鑹�"
+                        prop="backgroundColor">
+            <el-color-picker v-model="form.backgroundColor"
+                             style="width: 100%"></el-color-picker>
           </el-form-item>
         </el-col>
       </el-row>
-      
       <el-row :gutter="20">
         <el-col :span="24">
           <el-form-item>
-            <el-button type="primary" @click="generateCode" :loading="generating">
+            <el-button type="primary"
+                       @click="generateCode"
+                       :loading="generating">
               鐢熸垚{{ form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�' }}
             </el-button>
             <el-button @click="resetForm">閲嶇疆</el-button>
@@ -72,18 +81,17 @@
         </el-col>
       </el-row>
     </el-form>
-
     <!-- 鐢熸垚鐨勭爜鏄剧ず鍖哄煙 -->
-    <div v-if="generatedCodeUrl" class="code-display">
+    <div v-if="generatedCodeUrl"
+         class="code-display">
       <el-divider content-position="center">
         {{ form.type === 'qrcode' ? '鐢熸垚鐨勪簩缁寸爜' : '鐢熸垚鐨勯槻浼爜' }}
       </el-divider>
-      
       <div class="code-container">
         <div class="code-image">
-          <img :src="generatedCodeUrl" :alt="form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'" />
+          <img :src="generatedCodeUrl"
+               :alt="form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'" />
         </div>
-        
         <div class="code-info">
           <p><strong>鍐呭锛�</strong>{{ form.content }}</p>
           <p><strong>绫诲瀷锛�</strong>{{ form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�' }}</p>
@@ -91,60 +99,71 @@
           <p><strong>鐢熸垚鏃堕棿锛�</strong>{{ generateTime }}</p>
         </div>
       </div>
-      
       <div class="code-actions">
-        <el-button type="success" @click="downloadCode" icon="Download">
+        <el-button type="success"
+                   @click="downloadCode"
+                   icon="Download">
           涓嬭浇鍥剧墖
         </el-button>
-        <el-button type="primary" @click="copyToClipboard" icon="CopyDocument">
+        <el-button type="primary"
+                   @click="copyToClipboard"
+                   icon="CopyDocument">
           澶嶅埗鍐呭
         </el-button>
-        <el-button @click="printCode" icon="Printer">
+        <el-button @click="printCode"
+                   icon="Printer">
           鎵撳嵃
         </el-button>
       </div>
     </div>
-
     <!-- 鎵归噺鐢熸垚瀵硅瘽妗� -->
-    <el-dialog v-model="batchDialogVisible" title="鎵归噺鐢熸垚" width="600px">
-      <el-form :model="batchForm" label-width="120px">
+    <el-dialog v-model="batchDialogVisible"
+               title="鎵归噺鐢熸垚"
+               width="600px">
+      <el-form :model="batchForm"
+               label-width="120px">
         <el-form-item label="鐢熸垚鏁伴噺">
-          <el-input-number v-model="batchForm.quantity" :min="1" :max="100" style="width: 100%"></el-input-number>
+          <el-input-number v-model="batchForm.quantity"
+                           :min="1"
+                           :max="100"
+                           style="width: 100%"></el-input-number>
         </el-form-item>
         <el-form-item label="鍓嶇紑">
-          <el-input v-model="batchForm.prefix" placeholder="璇疯緭鍏ュ墠缂�锛屽锛歅ROD_"></el-input>
+          <el-input v-model="batchForm.prefix"
+                    placeholder="璇疯緭鍏ュ墠缂�锛屽锛歅ROD_"></el-input>
         </el-form-item>
         <el-form-item label="璧峰缂栧彿">
-          <el-input-number v-model="batchForm.startNumber" :min="1" style="width: 100%"></el-input-number>
+          <el-input-number v-model="batchForm.startNumber"
+                           :min="1"
+                           style="width: 100%"></el-input-number>
         </el-form-item>
       </el-form>
-      
       <template #footer>
         <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="generateBatchCodes">寮�濮嬬敓鎴�</el-button>
           <el-button @click="batchDialogVisible = false">鍙栨秷</el-button>
-          <el-button type="primary" @click="generateBatchCodes">寮�濮嬬敓鎴�</el-button>
         </div>
       </template>
     </el-dialog>
-
     <!-- 鎵归噺鐢熸垚缁撴灉 -->
-    <div v-if="batchCodes.length > 0" class="batch-results">
+    <div v-if="batchCodes.length > 0"
+         class="batch-results">
       <el-divider content-position="center">鎵归噺鐢熸垚缁撴灉</el-divider>
-      
       <div class="batch-grid">
-        <div 
-          v-for="(code, index) in batchCodes" 
-          :key="index" 
-          class="batch-item"
-        >
-          <img :src="code.url" :alt="code.content" />
+        <div v-for="(code, index) in batchCodes"
+             :key="index"
+             class="batch-item">
+          <img :src="code.url"
+               :alt="code.content" />
           <p class="batch-content">{{ code.content }}</p>
-          <el-button size="small" @click="downloadSingleCode(code)">涓嬭浇</el-button>
+          <el-button size="small"
+                     @click="downloadSingleCode(code)">涓嬭浇</el-button>
         </div>
       </div>
-      
       <div class="batch-actions">
-        <el-button type="success" @click="downloadAllCodes">涓嬭浇鍏ㄩ儴</el-button>
+        <el-button type="success"
+                   @click="downloadAllCodes">涓嬭浇鍏ㄩ儴</el-button>
         <el-button @click="clearBatchCodes">娓呯┖缁撴灉</el-button>
       </div>
     </div>
@@ -152,390 +171,396 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed, onMounted } from 'vue'
-import QRCode from 'qrcode'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { Download, CopyDocument, Printer } from '@element-plus/icons-vue'
+  import { ref, reactive, computed, onMounted } from "vue";
+  import QRCode from "qrcode";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Download, CopyDocument, Printer } from "@element-plus/icons-vue";
 
-// 瀹氫箟缁勪欢鍚嶇О
-defineOptions({
-  name: 'QRCodeGenerator'
-})
+  // 瀹氫箟缁勪欢鍚嶇О
+  defineOptions({
+    name: "QRCodeGenerator",
+  });
 
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
-  type: 'qrcode',
-  content: '',
-  size: 200,
-  margin: 2,
-  foregroundColor: '#000000',
-  backgroundColor: '#FFFFFF'
-})
+  // 琛ㄥ崟鏁版嵁
+  const form = reactive({
+    type: "qrcode",
+    content: "",
+    size: 200,
+    margin: 2,
+    foregroundColor: "#000000",
+    backgroundColor: "#FFFFFF",
+  });
 
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
-  type: [{ required: true, message: '璇烽�夋嫨鏍囪瘑绫诲瀷', trigger: 'change' }],
-  content: [{ required: true, message: '璇疯緭鍏ュ唴瀹�', trigger: 'blur' }]
-}
+  // 琛ㄥ崟楠岃瘉瑙勫垯
+  const rules = {
+    type: [{ required: true, message: "璇烽�夋嫨鏍囪瘑绫诲瀷", trigger: "change" }],
+    content: [{ required: true, message: "璇疯緭鍏ュ唴瀹�", trigger: "blur" }],
+  };
 
-// 鍝嶅簲寮忔暟鎹�
-const formRef = ref()
-const generating = ref(false)
-const generatedCodeUrl = ref('')
-const generateTime = ref('')
-const batchDialogVisible = ref(false)
-const batchForm = reactive({
-  quantity: 10,
-  prefix: '',
-  startNumber: 1
-})
-const batchCodes = ref([])
+  // 鍝嶅簲寮忔暟鎹�
+  const formRef = ref();
+  const generating = ref(false);
+  const generatedCodeUrl = ref("");
+  const generateTime = ref("");
+  const batchDialogVisible = ref(false);
+  const batchForm = reactive({
+    quantity: 10,
+    prefix: "",
+    startNumber: 1,
+  });
+  const batchCodes = ref([]);
 
-// 鐢熸垚浜岀淮鐮佹垨闃蹭吉鐮�
-const generateCode = async () => {
-  try {
-    await formRef.value.validate()
-    
-    if (!form.content.trim()) {
-      ElMessage.warning('璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�')
-      return
-    }
-    
-    generating.value = true
-    
-    if (form.type === 'qrcode') {
-      // 鐢熸垚浜岀淮鐮�
-      generatedCodeUrl.value = await QRCode.toDataURL(form.content, {
-        width: form.size,
-        margin: form.margin,
-        color: {
-          dark: form.foregroundColor,
-          light: form.backgroundColor
-        },
-        errorCorrectionLevel: 'M'
-      })
-    } else {
-      // 鐢熸垚闃蹭吉鐮侊紙浣跨敤浜岀淮鐮佹妧鏈紝浣嗗唴瀹规牸寮忎笉鍚岋級
-      const securityContent = generateSecurityCode(form.content)
-      generatedCodeUrl.value = await QRCode.toDataURL(securityContent, {
-        width: form.size,
-        margin: form.margin,
-        color: {
-          dark: form.foregroundColor,
-          light: form.backgroundColor
-        },
-        errorCorrectionLevel: 'H' // 闃蹭吉鐮佷娇鐢ㄦ渶楂樼籂閿欑骇鍒�
-      })
-    }
-    
-    generateTime.value = new Date().toLocaleString()
-    ElMessage.success('鐢熸垚鎴愬姛锛�')
-    
-  } catch (error) {
-    console.error('鐢熸垚澶辫触:', error)
-    ElMessage.error('鐢熸垚澶辫触锛�' + error.message)
-  } finally {
-    generating.value = false
-  }
-}
+  // 鐢熸垚浜岀淮鐮佹垨闃蹭吉鐮�
+  const generateCode = async () => {
+    try {
+      await formRef.value.validate();
 
-// 鐢熸垚闃蹭吉鐮佸唴瀹�
-const generateSecurityCode = (content) => {
-  const timestamp = Date.now()
-  const random = Math.random().toString(36).substr(2, 8)
-  return `SEC_${content}_${timestamp}_${random}`
-}
+      if (!form.content.trim()) {
+        ElMessage.warning("璇疯緭鍏ヨ缂栫爜鐨勫唴瀹�");
+        return;
+      }
 
-// 涓嬭浇鐢熸垚鐨勭爜
-const downloadCode = () => {
-  if (!generatedCodeUrl.value) {
-    ElMessage.warning('璇峰厛鐢熸垚鐮�')
-    return
-  }
-  
-  const a = document.createElement('a')
-  a.href = generatedCodeUrl.value
-  a.download = `${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}_${new Date().getTime()}.png`
-  document.body.appendChild(a)
-  a.click()
-  document.body.removeChild(a)
-  ElMessage.success('涓嬭浇鎴愬姛锛�')
-}
+      generating.value = true;
 
-// 澶嶅埗鍐呭鍒板壀璐存澘
-const copyToClipboard = async () => {
-  try {
-    await navigator.clipboard.writeText(form.content)
-    ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
-  } catch (error) {
-    // 闄嶇骇鏂规
-    const textArea = document.createElement('textarea')
-    textArea.value = form.content
-    document.body.appendChild(textArea)
-    textArea.select()
-    document.execCommand('copy')
-    document.body.removeChild(textArea)
-    ElMessage.success('鍐呭宸插鍒跺埌鍓创鏉�')
-  }
-}
-
-// 鎵撳嵃鐮�
-const printCode = () => {
-  if (!generatedCodeUrl.value) {
-    ElMessage.warning('璇峰厛鐢熸垚鐮�')
-    return
-  }
-  
-  const printWindow = window.open('', '_blank')
-  printWindow.document.write(`
-    <html>
-      <head>
-        <title>鎵撳嵃${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}</title>
-        <style>
-          body { text-align: center; padding: 20px; }
-          img { max-width: 100%; height: auto; }
-          .info { margin: 20px 0; }
-        </style>
-      </head>
-      <body>
-        <h2>${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}</h2>
-        <img src="${generatedCodeUrl.value}" alt="${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}" />
-        <div class="info">
-          <p><strong>鍐呭锛�</strong>${form.content}</p>
-          <p><strong>鐢熸垚鏃堕棿锛�</strong>${generateTime.value}</p>
-        </div>
-      </body>
-    </html>
-  `)
-  printWindow.document.close()
-  printWindow.print()
-}
-
-// 閲嶇疆琛ㄥ崟
-const resetForm = () => {
-  formRef.value.resetFields()
-  generatedCodeUrl.value = ''
-  generateTime.value = ''
-  batchCodes.value = []
-}
-
-// 鎵归噺鐢熸垚
-const generateBatchCodes = async () => {
-  if (!batchForm.prefix.trim()) {
-    ElMessage.warning('璇疯緭鍏ュ墠缂�')
-    return
-  }
-  
-  batchCodes.value = []
-  generating.value = true
-  
-  try {
-    for (let i = 0; i < batchForm.quantity; i++) {
-      const number = batchForm.startNumber + i
-      const content = `${batchForm.prefix}${number.toString().padStart(6, '0')}`
-      
-      let codeUrl
-      if (form.type === 'qrcode') {
-        codeUrl = await QRCode.toDataURL(content, {
+      if (form.type === "qrcode") {
+        // 鐢熸垚浜岀淮鐮�
+        generatedCodeUrl.value = await QRCode.toDataURL(form.content, {
           width: form.size,
           margin: form.margin,
           color: {
             dark: form.foregroundColor,
-            light: form.backgroundColor
-          }
-        })
+            light: form.backgroundColor,
+          },
+          errorCorrectionLevel: "M",
+        });
       } else {
-        const securityContent = generateSecurityCode(content)
-        codeUrl = await QRCode.toDataURL(securityContent, {
+        // 鐢熸垚闃蹭吉鐮侊紙浣跨敤浜岀淮鐮佹妧鏈紝浣嗗唴瀹规牸寮忎笉鍚岋級
+        const securityContent = generateSecurityCode(form.content);
+        generatedCodeUrl.value = await QRCode.toDataURL(securityContent, {
           width: form.size,
           margin: form.margin,
           color: {
             dark: form.foregroundColor,
-            light: form.backgroundColor
-          }
-        })
+            light: form.backgroundColor,
+          },
+          errorCorrectionLevel: "H", // 闃蹭吉鐮佷娇鐢ㄦ渶楂樼籂閿欑骇鍒�
+        });
       }
-      
-      batchCodes.value.push({
-        content,
-        url: codeUrl
-      })
+
+      generateTime.value = new Date().toLocaleString();
+      ElMessage.success("鐢熸垚鎴愬姛锛�");
+    } catch (error) {
+      console.error("鐢熸垚澶辫触:", error);
+      ElMessage.error("鐢熸垚澶辫触锛�" + error.message);
+    } finally {
+      generating.value = false;
     }
-    
-    ElMessage.success(`鎵归噺鐢熸垚瀹屾垚锛屽叡鐢熸垚 ${batchForm.quantity} 涓爜`)
-    batchDialogVisible.value = false
-    
-  } catch (error) {
-    console.error('鎵归噺鐢熸垚澶辫触:', error)
-    ElMessage.error('鎵归噺鐢熸垚澶辫触锛�' + error.message)
-  } finally {
-    generating.value = false
-  }
-}
+  };
 
-// 涓嬭浇鍗曚釜鎵归噺鐢熸垚鐨勭爜
-const downloadSingleCode = (code) => {
-  const a = document.createElement('a')
-  a.href = code.url
-  a.download = `${code.content}.png`
-  document.body.appendChild(a)
-  a.click()
-  document.body.removeChild(a)
-}
+  // 鐢熸垚闃蹭吉鐮佸唴瀹�
+  const generateSecurityCode = content => {
+    const timestamp = Date.now();
+    const random = Math.random().toString(36).substr(2, 8);
+    return `SEC_${content}_${timestamp}_${random}`;
+  };
 
-// 涓嬭浇鎵�鏈夋壒閲忕敓鎴愮殑鐮�
-const downloadAllCodes = async () => {
-  if (batchCodes.value.length === 0) {
-    ElMessage.warning('娌℃湁鍙笅杞界殑鐮�')
-    return
-  }
-  
-  try {
-    // 浣跨敤JSZip鎵撳寘涓嬭浇
-    const JSZip = await import('jszip')
-    const zip = new JSZip.default()
-    
-    batchCodes.value.forEach((code, index) => {
-      // 灏哹ase64杞崲涓篵lob
-      const base64Data = code.url.split(',')[1]
-      const byteCharacters = atob(base64Data)
-      const byteNumbers = new Array(byteCharacters.length)
-      for (let i = 0; i < byteCharacters.length; i++) {
-        byteNumbers[i] = byteCharacters.charCodeAt(i)
+  // 涓嬭浇鐢熸垚鐨勭爜
+  const downloadCode = () => {
+    if (!generatedCodeUrl.value) {
+      ElMessage.warning("璇峰厛鐢熸垚鐮�");
+      return;
+    }
+
+    const a = document.createElement("a");
+    a.href = generatedCodeUrl.value;
+    a.download = `${
+      form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"
+    }_${new Date().getTime()}.png`;
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+    ElMessage.success("涓嬭浇鎴愬姛锛�");
+  };
+
+  // 澶嶅埗鍐呭鍒板壀璐存澘
+  const copyToClipboard = async () => {
+    try {
+      await navigator.clipboard.writeText(form.content);
+      ElMessage.success("鍐呭宸插鍒跺埌鍓创鏉�");
+    } catch (error) {
+      // 闄嶇骇鏂规
+      const textArea = document.createElement("textarea");
+      textArea.value = form.content;
+      document.body.appendChild(textArea);
+      textArea.select();
+      document.execCommand("copy");
+      document.body.removeChild(textArea);
+      ElMessage.success("鍐呭宸插鍒跺埌鍓创鏉�");
+    }
+  };
+
+  // 鎵撳嵃鐮�
+  const printCode = () => {
+    if (!generatedCodeUrl.value) {
+      ElMessage.warning("璇峰厛鐢熸垚鐮�");
+      return;
+    }
+
+    const printWindow = window.open("", "_blank");
+    printWindow.document.write(`
+      <html>
+        <head>
+          <title>鎵撳嵃${form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"}</title>
+          <style>
+            body { text-align: center; padding: 20px; }
+            img { max-width: 100%; height: auto; }
+            .info { margin: 20px 0; }
+          </style>
+        </head>
+        <body>
+          <h2>${form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"}</h2>
+          <img src="${generatedCodeUrl.value}" alt="${
+      form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"
+    }" />
+          <div class="info">
+            <p><strong>鍐呭锛�</strong>${form.content}</p>
+            <p><strong>鐢熸垚鏃堕棿锛�</strong>${generateTime.value}</p>
+          </div>
+        </body>
+      </html>
+    `);
+    printWindow.document.close();
+    printWindow.print();
+  };
+
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    formRef.value.resetFields();
+    generatedCodeUrl.value = "";
+    generateTime.value = "";
+    batchCodes.value = [];
+  };
+
+  // 鎵归噺鐢熸垚
+  const generateBatchCodes = async () => {
+    if (!batchForm.prefix.trim()) {
+      ElMessage.warning("璇疯緭鍏ュ墠缂�");
+      return;
+    }
+
+    batchCodes.value = [];
+    generating.value = true;
+
+    try {
+      for (let i = 0; i < batchForm.quantity; i++) {
+        const number = batchForm.startNumber + i;
+        const content = `${batchForm.prefix}${number
+          .toString()
+          .padStart(6, "0")}`;
+
+        let codeUrl;
+        if (form.type === "qrcode") {
+          codeUrl = await QRCode.toDataURL(content, {
+            width: form.size,
+            margin: form.margin,
+            color: {
+              dark: form.foregroundColor,
+              light: form.backgroundColor,
+            },
+          });
+        } else {
+          const securityContent = generateSecurityCode(content);
+          codeUrl = await QRCode.toDataURL(securityContent, {
+            width: form.size,
+            margin: form.margin,
+            color: {
+              dark: form.foregroundColor,
+              light: form.backgroundColor,
+            },
+          });
+        }
+
+        batchCodes.value.push({
+          content,
+          url: codeUrl,
+        });
       }
-      const byteArray = new Uint8Array(byteNumbers)
-      
-      zip.file(`${code.content}.png`, byteArray)
-    })
-    
-    const content = await zip.generateAsync({ type: 'blob' })
-    const a = document.createElement('a')
-    a.href = URL.createObjectURL(content)
-    a.download = `鎵归噺${form.type === 'qrcode' ? '浜岀淮鐮�' : '闃蹭吉鐮�'}_${new Date().getTime()}.zip`
-    document.body.appendChild(a)
-    a.click()
-    document.body.removeChild(a)
-    URL.revokeObjectURL(a.href)
-    
-    ElMessage.success('鎵归噺涓嬭浇瀹屾垚锛�')
-  } catch (error) {
-    console.error('鎵归噺涓嬭浇澶辫触:', error)
-    ElMessage.error('鎵归噺涓嬭浇澶辫触锛岃閫愪釜涓嬭浇')
-  }
-}
 
-// 娓呯┖鎵归噺鐢熸垚缁撴灉
-const clearBatchCodes = () => {
-  batchCodes.value = []
-}
+      ElMessage.success(`鎵归噺鐢熸垚瀹屾垚锛屽叡鐢熸垚 ${batchForm.quantity} 涓爜`);
+      batchDialogVisible.value = false;
+    } catch (error) {
+      console.error("鎵归噺鐢熸垚澶辫触:", error);
+      ElMessage.error("鎵归噺鐢熸垚澶辫触锛�" + error.message);
+    } finally {
+      generating.value = false;
+    }
+  };
 
-// 鏆撮湶鏂规硶缁欑埗缁勪欢
-defineExpose({
-  generateCode,
-  downloadCode,
-  resetForm,
-  form
-})
+  // 涓嬭浇鍗曚釜鎵归噺鐢熸垚鐨勭爜
+  const downloadSingleCode = code => {
+    const a = document.createElement("a");
+    a.href = code.url;
+    a.download = `${code.content}.png`;
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+  };
+
+  // 涓嬭浇鎵�鏈夋壒閲忕敓鎴愮殑鐮�
+  const downloadAllCodes = async () => {
+    if (batchCodes.value.length === 0) {
+      ElMessage.warning("娌℃湁鍙笅杞界殑鐮�");
+      return;
+    }
+
+    try {
+      // 浣跨敤JSZip鎵撳寘涓嬭浇
+      const JSZip = await import("jszip");
+      const zip = new JSZip.default();
+
+      batchCodes.value.forEach((code, index) => {
+        // 灏哹ase64杞崲涓篵lob
+        const base64Data = code.url.split(",")[1];
+        const byteCharacters = atob(base64Data);
+        const byteNumbers = new Array(byteCharacters.length);
+        for (let i = 0; i < byteCharacters.length; i++) {
+          byteNumbers[i] = byteCharacters.charCodeAt(i);
+        }
+        const byteArray = new Uint8Array(byteNumbers);
+
+        zip.file(`${code.content}.png`, byteArray);
+      });
+
+      const content = await zip.generateAsync({ type: "blob" });
+      const a = document.createElement("a");
+      a.href = URL.createObjectURL(content);
+      a.download = `鎵归噺${
+        form.type === "qrcode" ? "浜岀淮鐮�" : "闃蹭吉鐮�"
+      }_${new Date().getTime()}.zip`;
+      document.body.appendChild(a);
+      a.click();
+      document.body.removeChild(a);
+      URL.revokeObjectURL(a.href);
+
+      ElMessage.success("鎵归噺涓嬭浇瀹屾垚锛�");
+    } catch (error) {
+      console.error("鎵归噺涓嬭浇澶辫触:", error);
+      ElMessage.error("鎵归噺涓嬭浇澶辫触锛岃閫愪釜涓嬭浇");
+    }
+  };
+
+  // 娓呯┖鎵归噺鐢熸垚缁撴灉
+  const clearBatchCodes = () => {
+    batchCodes.value = [];
+  };
+
+  // 鏆撮湶鏂规硶缁欑埗缁勪欢
+  defineExpose({
+    generateCode,
+    downloadCode,
+    resetForm,
+    form,
+  });
 </script>
 
 <style scoped>
-.qr-code-generator {
-  padding: 20px;
-}
+  .qr-code-generator {
+    padding: 20px;
+  }
 
-.qr-form {
-  background: #f8f9fa;
-  padding: 20px;
-  border-radius: 8px;
-  margin-bottom: 20px;
-}
+  .qr-form {
+    background: #f8f9fa;
+    padding: 20px;
+    border-radius: 8px;
+    margin-bottom: 20px;
+  }
 
-.code-display {
-  margin-top: 30px;
-}
+  .code-display {
+    margin-top: 30px;
+  }
 
-.code-container {
-  display: flex;
-  justify-content: center;
-  align-items: flex-start;
-  gap: 40px;
-  margin: 20px 0;
-}
-
-.code-image img {
-  border: 2px solid #e0e0e0;
-  border-radius: 8px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
-}
-
-.code-info {
-  text-align: left;
-  min-width: 200px;
-}
-
-.code-info p {
-  margin: 8px 0;
-  color: #666;
-}
-
-.code-actions {
-  text-align: center;
-  margin: 20px 0;
-}
-
-.code-actions .el-button {
-  margin: 0 10px;
-}
-
-.batch-results {
-  margin-top: 30px;
-}
-
-.batch-grid {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
-  gap: 20px;
-  margin: 20px 0;
-}
-
-.batch-item {
-  text-align: center;
-  padding: 15px;
-  border: 1px solid #e0e0e0;
-  border-radius: 8px;
-  background: #fff;
-}
-
-.batch-item img {
-  width: 100px;
-  height: 100px;
-  margin-bottom: 10px;
-}
-
-.batch-content {
-  font-size: 12px;
-  color: #666;
-  margin: 10px 0;
-  word-break: break-all;
-}
-
-.batch-actions {
-  text-align: center;
-  margin: 20px 0;
-}
-
-.batch-actions .el-button {
-  margin: 0 10px;
-}
-
-@media (max-width: 768px) {
   .code-container {
-    flex-direction: column;
-    align-items: center;
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
+    gap: 40px;
+    margin: 20px 0;
   }
-  
+
+  .code-image img {
+    border: 2px solid #e0e0e0;
+    border-radius: 8px;
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  }
+
+  .code-info {
+    text-align: left;
+    min-width: 200px;
+  }
+
+  .code-info p {
+    margin: 8px 0;
+    color: #666;
+  }
+
+  .code-actions {
+    text-align: center;
+    margin: 20px 0;
+  }
+
+  .code-actions .el-button {
+    margin: 0 10px;
+  }
+
+  .batch-results {
+    margin-top: 30px;
+  }
+
   .batch-grid {
-    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+    gap: 20px;
+    margin: 20px 0;
   }
-}
+
+  .batch-item {
+    text-align: center;
+    padding: 15px;
+    border: 1px solid #e0e0e0;
+    border-radius: 8px;
+    background: #fff;
+  }
+
+  .batch-item img {
+    width: 100px;
+    height: 100px;
+    margin-bottom: 10px;
+  }
+
+  .batch-content {
+    font-size: 12px;
+    color: #666;
+    margin: 10px 0;
+    word-break: break-all;
+  }
+
+  .batch-actions {
+    text-align: center;
+    margin: 20px 0;
+  }
+
+  .batch-actions .el-button {
+    margin: 0 10px;
+  }
+
+  @media (max-width: 768px) {
+    .code-container {
+      flex-direction: column;
+      align-items: center;
+    }
+
+    .batch-grid {
+      grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
+    }
+  }
 </style>

--
Gitblit v1.9.3