浏览代码

优化二维码生成样式

yawuga 1 月之前
父节点
当前提交
ec01d254de
共有 1 个文件被更改,包括 213 次插入68 次删除
  1. 213 68
      src/views/base/batch/index.vue

+ 213 - 68
src/views/base/batch/index.vue

@@ -326,19 +326,46 @@
     </el-dialog>
 
      <!-- 生成二维码弹窗 -->
-    <el-dialog :title="qrTitle" :visible.sync="qrVisible" width="420px" append-to-body>
-      <div class="qr-card" ref="qrCard">
-        <div class="qr-header">
-          <div class="brand-name">{{ qrData.brandName }}</div>
-          <div class="brand-en">{{ qrData.brandEn }}</div>
-        </div>
-        <div class="qr-content">
-          <div class="scan-tip">扫码查看溯源信息</div>
-          <div class="batch-info">批次号:{{ qrData.batchNo }}</div>
-          <div class="origin">{{ qrData.origin }}</div>
-        </div>
-        <div class="qr-code-wrapper">
-          <canvas id="qrCanvas"></canvas>
+    <el-dialog :title="qrTitle" :visible.sync="qrVisible" width="520px" append-to-body>
+      <div class="qr-label-wrapper">
+        <!-- 外层圆角标签 -->
+        <div class="qr-label" ref="qrCard">
+          <!-- 内层线框 + 四角折角 -->
+          <div class="qr-label-inner">
+            <!-- 四角折角装饰 -->
+            <div class="corner corner-tl"></div>
+            <div class="corner corner-tr"></div>
+            <div class="corner corner-bl"></div>
+            <div class="corner corner-br"></div>
+
+            <!-- 上半区:左侧信息 + 右侧二维码 -->
+            <div class="label-top">
+              <!-- 左侧品牌信息 -->
+              <div class="label-left">
+                <div class="brand-name">{{ qrData.brandName }}</div>
+                <div class="brand-en">{{ qrData.brandEn }}</div>
+                <div class="divider-line"></div>
+                <div class="scan-tip">扫码查看溯源信息</div>
+              </div>
+
+              <!-- 右侧二维码 -->
+              <div class="label-right">
+                <div class="qr-code-area">
+                  <canvas id="qrCanvas"></canvas>
+                </div>
+              </div>
+            </div>
+
+            <!-- 主分隔线 -->
+            <div class="main-divider"></div>
+
+            <!-- 下半区:批次信息 -->
+            <div class="label-bottom">
+              <div class="batch-row">批次: {{ qrData.batchNo }}</div>
+              <div class="label-bottom-divider"></div>
+              <div class="origin-row">{{ qrData.origin }}原产</div>
+            </div>
+          </div>
         </div>
       </div>
       <div slot="footer" class="dialog-footer">
@@ -570,8 +597,8 @@ export default {
       qrTitle: "生成二维码",
       // 二维码数据
       qrData: {
-        brandName: "爱智农",
-        brandEn: "AIZHONGNONG",
+        brandName: "佳友厚苑",
+        brandEn: "JIAYOU HOUYUAN",
         batchNo: "",
         origin: "",
         qrUrl: ""
@@ -784,25 +811,25 @@ export default {
     /** 生成二维码 */
     async handleGenerateQrCode(row) {
       this.qrData.batchNo = row.batchNo
-      this.qrData.farmRegion = row.farmRegion || '未知产地'
+      this.qrData.origin = row.farmRegion || '未知产地'
       // 这里替换成你的溯源页面地址,可以根据实际域名配置
      // const baseUrl = window.location.origin
       const baseUrl = 'https://nxy.gbdfarm.com:9001'
       this.qrData.qrUrl = `${baseUrl}/${row.id}`
-      
+
       this.qrVisible = true
-      
+
       // 等待 DOM 渲染后生成二维码
       this.$nextTick(async () => {
         const canvas = document.getElementById('qrCanvas')
         if (canvas) {
           try {
             await QRCode.toCanvas(canvas, this.qrData.qrUrl, {
-              width: 150,
-              height: 150,
-              margin: 2,
+              width: 140,
+              height: 140,
+              margin: 1,
               color: {
-                dark: '#333333',
+                dark: '#000000',
                 light: '#ffffff'
               }
             })
@@ -1158,80 +1185,198 @@ export default {
 }
 </script>
 <style scoped>
-.qr-card {
+/* 二维码标签包装器 */
+.qr-label-wrapper {
   display: flex;
-  justify-content: space-between;
+  justify-content: center;
   align-items: center;
-  padding: 30px 20px;
-  border: 2px solid #e0e0e0;
-  border-radius: 12px;
-  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
-  font-size: 14px;
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  padding: 16px;
 }
 
-.qr-header {
-  flex: 1;
-  text-align: left;
-  padding-right: 15px;
+/* 外层圆角标签 - 3:2 比例 (60mm x 40mm) */
+.qr-label {
+  width: 390px;
+  height: 260px;
+  background: #ffffff;
+  border: 1.5px solid #000000;
+  border-radius: 8px;
+  padding: 5px;
+  box-shadow: none;
+  box-sizing: border-box;
+  overflow: hidden;
+  aspect-ratio: 3 / 2;
+  flex: 0 0 auto;
+  flex-shrink: 0;
 }
 
-.brand-name {
-  font-size: 22px;
-  font-weight: bold;
-  color: #333;
-  margin-bottom: 8px;
-  letter-spacing: 1px;
+/* 内层线框 */
+.qr-label-inner {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border: 1px solid #000000;
+  border-radius: 4px;
+  padding: 14px 16px 12px;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
 }
 
-.brand-en {
-  font-size: 12px;
-  color: #666;
-  margin-bottom: 15px;
-  letter-spacing: 0.5px;
+/* 四角折角装饰 */
+.corner {
+  position: absolute;
+  width: 12px;
+  height: 12px;
+  border: 1px solid #000000;
+}
+.corner-tl {
+  top: -1px;
+  left: -1px;
+  border-right: none;
+  border-bottom: none;
+  border-radius: 4px 0 0 0;
+}
+.corner-tr {
+  top: -1px;
+  right: -1px;
+  border-left: none;
+  border-bottom: none;
+  border-radius: 0 4px 0 0;
+}
+.corner-bl {
+  bottom: -1px;
+  left: -1px;
+  border-right: none;
+  border-top: none;
+  border-radius: 0 0 0 4px;
+}
+.corner-br {
+  bottom: -1px;
+  right: -1px;
+  border-left: none;
+  border-top: none;
+  border-radius: 0 0 4px 0;
 }
 
-.qr-content {
+/* 上半区 */
+.label-top {
   flex: 1;
-  text-align: left;
-  padding: 0 15px;
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
 }
 
-.scan-tip {
-  margin-bottom: 12px;
-  color: #333;
-  font-weight: 500;
-  font-size: 13px;
+/* 左侧品牌信息 */
+.label-left {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  padding-right: 14px;
 }
 
-.batch-info {
+.brand-name {
+  font-size: 28px;
+  font-weight: 900;
+  color: #000000;
+  letter-spacing: 8px;
+  margin-bottom: 2px;
+  line-height: 1.1;
+  white-space: nowrap;
+}
+
+.brand-en {
+  font-size: 10px;
+  color: #000000;
+  letter-spacing: 5px;
   margin-bottom: 10px;
   font-weight: 600;
-  color: #2c3e50;
+  white-space: nowrap;
+}
+
+.divider-line {
+  width: 100%;
+  height: 1.5px;
+  background: #000000;
+  margin-bottom: 10px;
+}
+
+.scan-tip {
   font-size: 15px;
+  color: #000000;
+  letter-spacing: 2px;
+  font-weight: 700;
+  line-height: 1.3;
 }
 
-.origin {
-  color: #666;
-  font-size: 13px;
+/* 右侧二维码 */
+.label-right {
+  width: 120px;
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 
-.qr-code-wrapper {
-  width: 160px;
-  height: 160px;
+.qr-code-area {
+  width: 110px;
+  height: 110px;
   display: flex;
   align-items: center;
   justify-content: center;
-  background: #fff;
-  border: 1px solid #ddd;
-  border-radius: 8px;
-  padding: 8px;
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  padding: 3px;
+  border: 1px solid #000000;
 }
 
+.qr-code-area canvas,
 #qrCanvas {
-  width: 150px;
-  height: 150px;
+  width: 102px !important;
+  height: 102px !important;
+}
+
+/* 主分隔线 */
+.main-divider {
+  width: 100%;
+  height: 1.5px;
+  background: #000000;
+  margin: 10px 0;
+}
+
+/* 下半区 */
+.label-bottom {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 0;
+  box-sizing: border-box;
+}
+
+.batch-row {
+  font-size: 17px;
+  color: #000000;
+  font-weight: 800;
+  letter-spacing: 2px;
+  margin-bottom: 8px;
+  width: 100%;
+  text-align: center;
+  line-height: 1.3;
+}
+
+.label-bottom-divider {
+  width: 100%;
+  height: 1px;
+  background: #000000;
+  margin-bottom: 8px;
+}
+
+.origin-row {
+  font-size: 16px;
+  color: #000000;
+  letter-spacing: 4px;
+  font-weight: 700;
+  text-align: center;
+  width: 100%;
+  line-height: 1.3;
 }
 
 .dialog-footer {