# QR 码渲染修复说明

## 问题

之前内嵌的 minified 版 qrcode-generator 库有两个坑：

1. **`typeNumber=0` 不支持** — `getPatternPosition(0)` 访问 `a[-1]` 报 `Cannot read properties of undefined (reading 'length')`
2. **`d.M = 0` 是 falsy** — `d[c]||d.L` 导致传 `'M'` 时实际走 `'L'`

用 for 循环 1→40 绕开了第一个问题，但生成的二维码仍然扫不上。

## 修复方案

### 1. 删掉 inline minified 库，换 CDN 标准版

```html
<script src="https://cdn.jsdelivr.net/npm/qrcode-generator@1.4.4/qrcode.min.js"></script>
```

标准版完整支持 `typeNumber=0`（自动选最小版本）和正确的纠错级别映射。

### 2. renderQR 重写

```javascript
function renderQR(el, text, size) {
  el.innerHTML = '';
  if (!text || text.indexOf('mock') !== -1) return;
  try {
    var qr = qrcode(0, 'M');
    qr.addData(text);
    qr.make();
    var mc = qr.getModuleCount();
    var margin = 4;
    var dpr = window.devicePixelRatio || 1;
    var cellSize = Math.max(Math.floor(size * dpr / (mc + margin * 2)), 2);
    var realSize = cellSize * (mc + margin * 2);
    var canvas = document.createElement('canvas');
    canvas.width = canvas.height = realSize;
    canvas.style.width = canvas.style.height = Math.ceil(realSize / dpr) + 'px';
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, realSize, realSize);
    ctx.fillStyle = '#000';
    for (var r = 0; r < mc; r++)
      for (var c = 0; c < mc; c++)
        if (qr.isDark(r, c))
          ctx.fillRect((c + margin) * cellSize, (r + margin) * cellSize, cellSize, cellSize);
    // canvas转img，防HtmlDialog渲染坑
    var img = document.createElement('img');
    img.src = canvas.toDataURL('image/png');
    img.style.width = canvas.style.width;
    img.style.height = canvas.style.height;
    img.style.imageRendering = 'pixelated';
    el.appendChild(img);
  } catch(e) {
    el.textContent = '二维码生成失败: ' + e.message;
  }
}
```

### 3. 调用处

```javascript
renderQR($('qrPlaceholder'), o.qr_code_url || '', 260);
```

## 关键改进点

| 项目 | 旧 | 新 |
|------|------|------|
| 库来源 | inline minified（被魔改） | CDN 标准版 1.4.4 |
| typeNumber | 循环 1→40 试错 | `0`（自动检测） |
| 纠错级别 | `'L'`（被迫，因为 M=0 falsy） | `'M'`（标准 API 正确处理） |
| 渲染尺寸 | 固定 cellSize≥3 | `size * dpr` 适配高清屏 |
| 输出方式 | canvas 直出 → img | canvas 绘制 → `toDataURL` → img |
| 抗模糊 | `image-rendering: pixelated` | 同 + dpr 物理像素放大 |
| quiet zone | 4 module margin | 同 |

## 降级方案

如果 HtmlDialog 加载 CDN 失败（断网环境），把 `qrcode.min.js` 下载到 `html/` 目录，改为：

```html
<script src="qrcode.min.js"></script>
```

## 修改文件

- `plugins/src/rdc_main/html/payment_dialog.html`
