{
  "components": {
    "schemas": {
      "Error": {
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "description": "在「我的」页面复制；也接受 Authorization: Bearer 或 ?key=。",
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      },
      "SessionCookie": {
        "description": "网页登录后自动携带。",
        "in": "cookie",
        "name": "wx_sid",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "太阳码（WX_CODE）生成、解析与账号管理接口。右侧的 Try it 可直接在浏览器里发请求。",
    "title": "云链智码 API",
    "version": "1.1.0"
  },
  "openapi": "3.0.3",
  "paths": {
    "/api/decode": {
      "post": {
        "description": "上传图片解析太阳码。三种投喂方式任选其一：multipart 字段 file（也接受 image）、原始图片字节、\nJSON 的 image / url。加 family=auto 时先试太阳码再试普通二维码，prefer=qr 可让二维码优先。",
        "operationId": "decode",
        "parameters": [
          {
            "description": "传 auto 启用「太阳码 + 普通二维码」互补识别",
            "in": "query",
            "name": "family",
            "required": false,
            "schema": {
              "enum": [
                "auto"
              ],
              "example": "auto",
              "type": "string"
            }
          },
          {
            "description": "family=auto 时优先尝试的码型，默认 wx",
            "in": "query",
            "name": "prefer",
            "required": false,
            "schema": {
              "enum": [
                "wx",
                "qr"
              ],
              "example": "qr",
              "type": "string"
            }
          },
          {
            "description": "直接给公网图片地址，由服务端下载后解析",
            "in": "query",
            "name": "url",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "image": "data:image/png;base64,iVBORw0KGgo…"
              },
              "examples": {
                "默认": {
                  "summary": "最小可用示例",
                  "value": {
                    "image": "data:image/png;base64,iVBORw0KGgo…"
                  }
                }
              },
              "schema": {
                "properties": {
                  "image": {
                    "description": "data URL / 裸 base64 / http(s) 图片地址",
                    "type": "string"
                  },
                  "url": {
                    "description": "图片 URL，与 image 二选一（仅公网）",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            },
            "application/octet-stream": {
              "schema": {
                "format": "binary",
                "type": "string"
              }
            },
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "file": {
                    "description": "图片文件字段，也接受 image / logo / icon",
                    "format": "binary",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "box": {
                    "rx": 0.507,
                    "ry": 0.507,
                    "x": 0.499,
                    "y": 0.499
                  },
                  "corrections": 0,
                  "count": 23,
                  "ecLevel": "Q",
                  "family": "WX_CODE",
                  "mask": 14,
                  "mode": "ALPHANUMERIC",
                  "payload": "https://example.com/",
                  "qrText": "5M +*-F/2IH%%Q53E9:/-IP",
                  "typebits": 122236,
                  "version": 0
                },
                "schema": {
                  "properties": {
                    "box": {
                      "description": "码在图中的外接圆（归一化 0~1）；定位失败时整个字段不返回",
                      "properties": {
                        "rx": {
                          "description": "横向半径，按图片宽度归一化",
                          "type": "number"
                        },
                        "ry": {
                          "description": "纵向半径，按图片高度归一化",
                          "type": "number"
                        },
                        "x": {
                          "description": "圆心横坐标：0 左边缘、1 右边缘",
                          "type": "number"
                        },
                        "y": {
                          "description": "圆心纵坐标：0 上边缘、1 下边缘",
                          "type": "number"
                        }
                      },
                      "type": "object"
                    },
                    "corrections": {
                      "description": "RS 纠错修掉的码字数，0 表示原图很干净",
                      "type": "integer"
                    },
                    "count": {
                      "description": "数据段声明的字符数；QR_CODE 时没有该字段",
                      "type": "integer"
                    },
                    "ecLevel": {
                      "description": "纠错等级 L / M / Q / H",
                      "type": "string"
                    },
                    "family": {
                      "description": "码型：WX_CODE 太阳码；family=auto 时也可能是 QR_CODE",
                      "type": "string"
                    },
                    "mask": {
                      "description": "掩码编号：太阳码 0~31，二维码 0~7",
                      "type": "integer"
                    },
                    "mode": {
                      "description": "数据模式 NUMERIC / ALPHANUMERIC / BYTE；二维码多段时形如 ALPHANUMERIC+BYTE",
                      "type": "string"
                    },
                    "modules": {
                      "description": "仅 QR_CODE 出现：边长模块数 = 17 + 4 × version",
                      "type": "integer"
                    },
                    "payload": {
                      "description": "解出的最终内容（已做逆变换），业务只需用这个字段",
                      "type": "string"
                    },
                    "qrText": {
                      "description": "仅 ALPHANUMERIC 出现：码内承载的变换文本，调试用",
                      "type": "string"
                    },
                    "text": {
                      "description": "仅 QR_CODE 出现：二维码里的完整文本",
                      "type": "string"
                    },
                    "typebits": {
                      "description": "太阳码的 18 位格式信息位；QR_CODE 时没有该字段",
                      "type": "integer"
                    },
                    "url": {
                      "description": "仅 QR_CODE 出现：文本中的链接，没有链接则不存在",
                      "type": "string"
                    },
                    "version": {
                      "description": "版本号：太阳码 0~2，二维码 1~40",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                },
                "x-wxcode-example": "{\n  \"family\": \"WX_CODE\",                  // 码型：WX_CODE / QR_CODE（auto 时）\n  \"version\": 0,                         // 太阳码 0~2\n  \"ecLevel\": \"Q\",                       // 纠错等级 L/M/Q/H\n  \"mask\": 14,                           // 掩码 0~31\n  \"typebits\": 122236,                   // 18 位格式信息位\n  \"mode\": \"ALPHANUMERIC\",               // 数据模式\n  \"count\": 23,                          // 声明的字符数\n  \"qrText\": \"5M +*-F/2IH%%Q53E9:/-IP\",  // 仅字母数字模式：码内变换文本\n  \"payload\": \"https://example.com/\",    // 解出的最终内容（业务只用这个）\n  \"corrections\": 0,                     // RS 纠错修掉的码字数，0 表示很干净\n  \"box\": {                              // 码在图中的位置（0~1 归一化），定位失败不返回\n    \"x\": 0.499,                         // 圆心横坐标\n    \"y\": 0.499,                         // 圆心纵坐标\n    \"rx\": 0.507,                        // 横向半径\n    \"ry\": 0.507                         // 纵向半径\n  }\n}"
              }
            },
            "description": "识别成功：family 区分码型，payload 是最终内容",
            "x-wxcode-fields": [
              {
                "name": "family",
                "type": "string",
                "description": "码型：WX_CODE 太阳码；family=auto 时也可能是 QR_CODE"
              },
              {
                "name": "version",
                "type": "integer",
                "description": "版本号：太阳码 0~2，二维码 1~40"
              },
              {
                "name": "ecLevel",
                "type": "string",
                "description": "纠错等级 L / M / Q / H"
              },
              {
                "name": "mask",
                "type": "integer",
                "description": "掩码编号：太阳码 0~31，二维码 0~7"
              },
              {
                "name": "typebits",
                "type": "integer",
                "description": "太阳码的 18 位格式信息位；QR_CODE 时没有该字段"
              },
              {
                "name": "mode",
                "type": "string",
                "description": "数据模式 NUMERIC / ALPHANUMERIC / BYTE；二维码多段时形如 ALPHANUMERIC+BYTE"
              },
              {
                "name": "count",
                "type": "integer",
                "description": "数据段声明的字符数；QR_CODE 时没有该字段"
              },
              {
                "name": "qrText",
                "type": "string",
                "description": "仅 ALPHANUMERIC 出现：码内承载的变换文本，调试用"
              },
              {
                "name": "payload",
                "type": "string",
                "description": "解出的最终内容（已做逆变换），业务只需用这个字段"
              },
              {
                "name": "corrections",
                "type": "integer",
                "description": "RS 纠错修掉的码字数，0 表示原图很干净"
              },
              {
                "name": "box",
                "type": "object",
                "description": "码在图中的外接圆（归一化 0~1）；定位失败时整个字段不返回"
              },
              {
                "name": "box.x",
                "type": "number",
                "description": "圆心横坐标：0 左边缘、1 右边缘"
              },
              {
                "name": "box.y",
                "type": "number",
                "description": "圆心纵坐标：0 上边缘、1 下边缘"
              },
              {
                "name": "box.rx",
                "type": "number",
                "description": "横向半径，按图片宽度归一化"
              },
              {
                "name": "box.ry",
                "type": "number",
                "description": "纵向半径，按图片高度归一化"
              },
              {
                "name": "text",
                "type": "string",
                "description": "仅 QR_CODE 出现：二维码里的完整文本"
              },
              {
                "name": "url",
                "type": "string",
                "description": "仅 QR_CODE 出现：文本中的链接，没有链接则不存在"
              },
              {
                "name": "modules",
                "type": "integer",
                "description": "仅 QR_CODE 出现：边长模块数 = 17 + 4 × version"
              }
            ]
          },
          "400": {
            "content": {
              "application/json": {
                "example": {
                  "error": "未找到葵花码的 3 组定位图案"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"未找到葵花码的 3 组定位图案\"}"
              }
            },
            "description": "没识别到码 / 图片不合法 / 缺字段（family=auto 时错误文案会以「未识别到太阳码或普通二维码」开头）"
          },
          "403": {
            "content": {
              "application/json": {
                "example": {
                  "error": "拒绝访问内网 / 回环地址"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"拒绝访问内网 / 回环地址\"}"
              }
            },
            "description": "图片地址指向内网 / 回环地址"
          },
          "429": {
            "content": {
              "application/json": {
                "example": {
                  "error": "请求过于频繁，请稍后再试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"请求过于频繁，请稍后再试\"}"
              }
            },
            "description": "超过每分钟调用上限"
          }
        },
        "security": [
          {},
          {
            "ApiKey": []
          },
          {
            "SessionCookie": []
          }
        ],
        "summary": "解析太阳码 / 自动识别",
        "tags": [
          "解析"
        ],
        "x-order": 3,
        "x-wxcode-auth": "optional",
        "x-wxcode-request-example": "{\n  \"image\": \"data:image/png;base64,iVBORw0KGgo…\",  // 必填其一：data URL / 裸 base64 / http(s) 图片地址\n  // 也可以只给图片地址：\"url\": \"https://example.com/code.png\"\n  // 或者根本不发 JSON：直接 multipart -F 'file=@code.png'，或把图片字节当 body 发\n}",
        "x-wxcode-try": {
          "mode": "multipart",
          "fields": [
            {
              "name": "file",
              "in": "file",
              "label": "待解析图片",
              "type": "file",
              "required": true
            },
            {
              "name": "family",
              "in": "query",
              "label": "family",
              "type": "select",
              "value": "auto",
              "options": [
                "",
                "auto"
              ]
            }
          ]
        }
      }
    },
    "/api/encode": {
      "get": {
        "description": "与 POST /api/encode 能力完全一致，只是参数放在 query 里，适合 \u003cimg src=\"...\"\u003e。\n二进制响应同样带 X-WXCode-* 头。",
        "operationId": "encodeGet",
        "parameters": [
          {
            "description": "要编码的内容，必填。接口上限 8192 字节；但一枚码只能装几十字节（URL 约 58 字符、中文按字节约 44 字节），超了返回 400",
            "in": "query",
            "name": "text",
            "required": false,
            "schema": {
              "example": "https://example.com/",
              "type": "string"
            }
          },
          {
            "description": "输出格式，默认 png。png/jpg/gif 返回图片二进制，svg 返回矢量文本，json 返回结构体",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": [
                "png",
                "jpg",
                "svg",
                "gif",
                "json"
              ],
              "example": "png",
              "type": "string"
            }
          },
          {
            "description": "位图边长（像素），120~2000，默认 600；对 svg 无效",
            "in": "query",
            "name": "size",
            "required": false,
            "schema": {
              "example": 600,
              "type": "integer"
            }
          },
          {
            "description": "位图四周白边（像素），0~200，默认 0",
            "in": "query",
            "name": "margin",
            "required": false,
            "schema": {
              "example": 0,
              "type": "integer"
            }
          },
          {
            "description": "前景色（码点颜色），#rrggbb，默认 #000000",
            "in": "query",
            "name": "fg",
            "required": false,
            "schema": {
              "example": "#000000",
              "type": "string"
            }
          },
          {
            "description": "背景色，#rrggbb，默认 #ffffff",
            "in": "query",
            "name": "bg",
            "required": false,
            "schema": {
              "example": "#ffffff",
              "type": "string"
            }
          },
          {
            "description": "允许的最低纠错等级，默认 L；容量够时自动取更高等级（响应里的 level 是实际值）",
            "in": "query",
            "name": "level",
            "required": false,
            "schema": {
              "enum": [
                "L",
                "M",
                "Q",
                "H"
              ],
              "example": "L",
              "type": "string"
            }
          },
          {
            "description": "码格版本：auto（默认，取最小可容纳）/ 0 / 1 / 2（钉死版本，装不下会报错）",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "enum": [
                "auto",
                "0",
                "1",
                "2"
              ],
              "example": "auto",
              "type": "string"
            }
          },
          {
            "description": "掩码：-1 自动在 0~31 里按评分选最优，也可固定 0~31",
            "in": "query",
            "name": "mask",
            "required": false,
            "schema": {
              "example": -1,
              "type": "integer"
            }
          },
          {
            "description": "中心 logo：data URL / http(s) 地址 / 裸 base64 / 空字符串不画；multipart 时也可以传 logo 文件。服务器本地路径需开 ALLOW_LOCAL_IMAGE。GIF 动图 + format=gif 会逐帧保留",
            "in": "query",
            "name": "logo",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "logo 半径缩放，0.2~3.0，默认 1（半径 = 108/600 边长）",
            "in": "query",
            "name": "logoRatio",
            "required": false,
            "schema": {
              "example": 1,
              "type": "number"
            }
          },
          {
            "description": "角落徽标：default（内嵌图，SVG 写成 data URI、离线可用）/ native（写回远程 URL）/ none（不画）/ 自定义图片地址",
            "in": "query",
            "name": "badge",
            "required": false,
            "schema": {
              "example": "default",
              "type": "string"
            }
          },
          {
            "description": "笔画风格（只决定形状）：classic（默认，等宽胶囊，与微信原生一致）/ hand（手绘：笔线抖动、粗细不匀、徽标也手贴）/ dot（圆点）/ block（方块）/ line（线描：细环+中心点）。装饰性抖动都控制在半格内，不影响扫码",
            "in": "query",
            "name": "style",
            "required": false,
            "schema": {
              "enum": [
                "classic",
                "hand",
                "dot",
                "block",
                "line"
              ],
              "example": "classic",
              "type": "string"
            }
          },
          {
            "description": "配色（只决定墨色，可与任意笔画风格组合）：solid（默认，用 fg）/ rainbow（色环：按半径渐变，内圈青→外圈品红）/ random（彩虹：每一笔随机一色）/ ghost（隐形：墨色只比底色深几级，肉眼几乎看不出，徽标自动隐藏）。除 solid 外都不使用 fg",
            "in": "query",
            "name": "color",
            "required": false,
            "schema": {
              "enum": [
                "solid",
                "rainbow",
                "random",
                "ghost"
              ],
              "example": "solid",
              "type": "string"
            }
          },
          {
            "description": "隐形配色的深度：墨色比底色深几级（2~40，默认 6）。越小越隐形、越难扫：2~4 基本看不见但只有程序能解，8 以上手机更容易扫出来",
            "in": "query",
            "name": "ghost",
            "required": false,
            "schema": {
              "example": 6,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "codewords": 38,
                  "ecCodewords": 18,
                  "format": "json",
                  "level": "Q",
                  "levelIndex": 2,
                  "mask": 14,
                  "mode": "ALPHANUMERIC",
                  "pngBase64": "iVBORw0KGgoAAAANSUhEUg…（PNG 的 base64，不含 data: 前缀）",
                  "size": 600,
                  "svg": "\u003csvg width=\"600\" height=\"600\" …\u003e（完整 SVG 文本）",
                  "text": "https://example.com/",
                  "transformed": "5M +*-F/2IH%%Q53E9:/-IP",
                  "typebits": 122236,
                  "version": 0
                },
                "schema": {
                  "properties": {
                    "codewords": {
                      "description": "码字总数（数据码字 + 纠错码字）",
                      "type": "integer"
                    },
                    "ecCodewords": {
                      "description": "其中的纠错码字数",
                      "type": "integer"
                    },
                    "format": {
                      "description": "本次输出格式，固定 json",
                      "type": "string"
                    },
                    "level": {
                      "description": "实际纠错等级 L / M / Q / H，容量够时会高于请求的 level",
                      "type": "string"
                    },
                    "levelIndex": {
                      "description": "纠错等级下标：0=L、1=M、2=Q、3=H",
                      "type": "integer"
                    },
                    "logoAnimated": {
                      "description": "仅 logo 是动图时出现，固定 true",
                      "type": "boolean"
                    },
                    "logoFrames": {
                      "description": "仅 logo 是动图时出现：动图帧数",
                      "type": "integer"
                    },
                    "mask": {
                      "description": "实际掩码 0~31；请求 mask=-1 时按评分自动选优",
                      "type": "integer"
                    },
                    "mode": {
                      "description": "数据模式：NUMERIC 纯数字 / ALPHANUMERIC 字母数字 / BYTE 字节",
                      "type": "string"
                    },
                    "pngBase64": {
                      "description": "PNG 的 base64（不含 data: 前缀），配合 data:image/png;base64, 可预览",
                      "type": "string"
                    },
                    "size": {
                      "description": "位图边长（像素），与请求的 size 一致",
                      "type": "integer"
                    },
                    "svg": {
                      "description": "完整 SVG 文本，可直接另存为 .svg",
                      "type": "string"
                    },
                    "text": {
                      "description": "实际编码的内容，与请求的 text 一致",
                      "type": "string"
                    },
                    "transformed": {
                      "description": "仅 ALPHANUMERIC 出现：真正写进码里的变换文本",
                      "type": "string"
                    },
                    "typebits": {
                      "description": "18 位格式信息位（版本 + 纠错等级 + 掩码的编码）",
                      "type": "integer"
                    },
                    "version": {
                      "description": "码格版本 0 / 1 / 2，v0 最小",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                },
                "x-wxcode-example": "{\n  \"text\": \"https://example.com/\",            // 实际编码的内容\n  \"format\": \"json\",                          // 输出格式，固定 json\n  \"version\": 0,                              // 码格版本 0/1/2，v0 最小\n  \"level\": \"Q\",                              // 实际纠错等级（容量够时会升级）\n  \"levelIndex\": 2,                           // 等级下标 0=L 1=M 2=Q 3=H\n  \"mask\": 14,                                // 实际掩码 0~31\n  \"typebits\": 122236,                        // 18 位格式信息位\n  \"mode\": \"ALPHANUMERIC\",                    // 数据模式\n  \"transformed\": \"5M +*-F/2IH%%Q53E9:/-IP\",  // 仅字母数字模式：码内变换文本\n  \"codewords\": 38,                           // 码字总数（数据+纠错）\n  \"ecCodewords\": 18,                         // 其中纠错码字数\n  \"size\": 600,                               // 位图边长（像素）\n  \"svg\": \"\u003csvg width=\\\"600\\\" height=\\\"600\\\" …\u003e（完整 SVG 文本）\",\n  \"pngBase64\": \"iVBORw0KGgoAAAANSUhEUg…（PNG 的 base64，不含 data: 前缀）\"\n}"
              },
              "image/gif": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              },
              "image/jpeg": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              },
              "image/png": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              },
              "image/svg+xml": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "生成成功，返回内容由 format 决定（图片 / SVG / JSON），并带 X-WXCode-* 响应头",
            "x-wxcode-fields": [
              {
                "name": "text",
                "type": "string",
                "description": "实际编码的内容，与请求的 text 一致"
              },
              {
                "name": "format",
                "type": "string",
                "description": "本次输出格式，固定 json"
              },
              {
                "name": "version",
                "type": "integer",
                "description": "码格版本 0 / 1 / 2，v0 最小"
              },
              {
                "name": "level",
                "type": "string",
                "description": "实际纠错等级 L / M / Q / H，容量够时会高于请求的 level"
              },
              {
                "name": "levelIndex",
                "type": "integer",
                "description": "纠错等级下标：0=L、1=M、2=Q、3=H"
              },
              {
                "name": "mask",
                "type": "integer",
                "description": "实际掩码 0~31；请求 mask=-1 时按评分自动选优"
              },
              {
                "name": "typebits",
                "type": "integer",
                "description": "18 位格式信息位（版本 + 纠错等级 + 掩码的编码）"
              },
              {
                "name": "mode",
                "type": "string",
                "description": "数据模式：NUMERIC 纯数字 / ALPHANUMERIC 字母数字 / BYTE 字节"
              },
              {
                "name": "transformed",
                "type": "string",
                "description": "仅 ALPHANUMERIC 出现：真正写进码里的变换文本"
              },
              {
                "name": "codewords",
                "type": "integer",
                "description": "码字总数（数据码字 + 纠错码字）"
              },
              {
                "name": "ecCodewords",
                "type": "integer",
                "description": "其中的纠错码字数"
              },
              {
                "name": "size",
                "type": "integer",
                "description": "位图边长（像素），与请求的 size 一致"
              },
              {
                "name": "svg",
                "type": "string",
                "description": "完整 SVG 文本，可直接另存为 .svg"
              },
              {
                "name": "pngBase64",
                "type": "string",
                "description": "PNG 的 base64（不含 data: 前缀），配合 data:image/png;base64, 可预览"
              },
              {
                "name": "logoAnimated",
                "type": "boolean",
                "description": "仅 logo 是动图时出现，固定 true"
              },
              {
                "name": "logoFrames",
                "type": "integer",
                "description": "仅 logo 是动图时出现：动图帧数"
              }
            ]
          },
          "400": {
            "content": {
              "application/json": {
                "example": {
                  "error": "载荷超出一枚葵花码容量（v0..v2 均装不下，请缩短内容）"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"载荷超出一枚葵花码容量（v0..v2 均装不下，请缩短内容）\"}"
              }
            },
            "description": "内容为空 / 超出容量 / 参数非法"
          },
          "403": {
            "content": {
              "application/json": {
                "example": {
                  "error": "内容包含禁止发布的词语"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"内容包含禁止发布的词语\"}"
              }
            },
            "description": "内容命中黑名单关键词，或 logo / url 指向内网地址"
          },
          "429": {
            "content": {
              "application/json": {
                "example": {
                  "error": "请求过于频繁，请稍后再试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"请求过于频繁，请稍后再试\"}"
              }
            },
            "description": "单 IP 超过每分钟调用上限，响应带 Retry-After"
          },
          "503": {
            "content": {
              "application/json": {
                "example": {
                  "error": "服务繁忙，请稍后重试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"服务繁忙，请稍后重试\"}"
              }
            },
            "description": "同时编码 / 解析的任务已满，请稍后重试"
          }
        },
        "security": [
          {},
          {
            "ApiKey": []
          },
          {
            "SessionCookie": []
          }
        ],
        "summary": "生成太阳码（query，可直接放进 img）",
        "tags": [
          "生成"
        ],
        "x-order": 1,
        "x-wxcode-auth": "optional",
        "x-wxcode-request-example": "{{BASE_URL}}/api/encode?text=https%3A%2F%2Fexample.com%2F\u0026format=png\u0026size=400",
        "x-wxcode-try": {
          "mode": "query",
          "fields": [
            {
              "name": "text",
              "in": "query",
              "label": "内容",
              "type": "text",
              "value": "https://example.com/"
            },
            {
              "name": "format",
              "in": "query",
              "label": "格式",
              "type": "select",
              "value": "png",
              "options": [
                "png",
                "jpg",
                "svg",
                "gif",
                "json"
              ]
            },
            {
              "name": "size",
              "in": "query",
              "label": "尺寸 px",
              "type": "number",
              "value": 400
            },
            {
              "name": "style",
              "in": "query",
              "label": "笔画风格",
              "type": "select",
              "value": "classic",
              "options": [
                "classic",
                "hand",
                "dot",
                "block",
                "line"
              ]
            },
            {
              "name": "color",
              "in": "query",
              "label": "配色",
              "type": "select",
              "value": "solid",
              "options": [
                "solid",
                "rainbow",
                "random",
                "ghost"
              ]
            },
            {
              "name": "ghost",
              "in": "query",
              "label": "隐形深度",
              "type": "number",
              "value": 6
            }
          ]
        }
      },
      "post": {
        "description": "输入内容生成葵花码。请求体支持 JSON、普通表单或 multipart（multipart 时 logo 可传文件）；\nPNG / JPG / GIF 返回图片二进制，SVG 返回矢量文本，format=json 返回结构体。",
        "operationId": "encodePost",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "badge": "default",
                "bg": "#ffffff",
                "color": "solid",
                "fg": "#000000",
                "format": "png",
                "ghost": 6,
                "level": "L",
                "logo": "",
                "logoRatio": 1,
                "margin": 0,
                "mask": -1,
                "size": 600,
                "style": "classic",
                "text": "https://example.com/",
                "version": "auto"
              },
              "examples": {
                "默认": {
                  "summary": "最小可用示例",
                  "value": {
                    "badge": "default",
                    "bg": "#ffffff",
                    "color": "solid",
                    "fg": "#000000",
                    "format": "png",
                    "ghost": 6,
                    "level": "L",
                    "logo": "",
                    "logoRatio": 1,
                    "margin": 0,
                    "mask": -1,
                    "size": 600,
                    "style": "classic",
                    "text": "https://example.com/",
                    "version": "auto"
                  }
                }
              },
              "schema": {
                "properties": {
                  "badge": {
                    "description": "角落徽标：default（内嵌图，SVG 写成 data URI、离线可用）/ native（写回远程 URL）/ none（不画）/ 自定义图片地址",
                    "example": "default",
                    "type": "string"
                  },
                  "bg": {
                    "description": "背景色，#rrggbb，默认 #ffffff",
                    "example": "#ffffff",
                    "type": "string"
                  },
                  "color": {
                    "description": "配色（只决定墨色，可与任意笔画风格组合）：solid（默认，用 fg）/ rainbow（色环：按半径渐变，内圈青→外圈品红）/ random（彩虹：每一笔随机一色）/ ghost（隐形：墨色只比底色深几级，肉眼几乎看不出，徽标自动隐藏）。除 solid 外都不使用 fg",
                    "enum": [
                      "solid",
                      "rainbow",
                      "random",
                      "ghost"
                    ],
                    "example": "solid",
                    "type": "string"
                  },
                  "fg": {
                    "description": "前景色（码点颜色），#rrggbb，默认 #000000",
                    "example": "#000000",
                    "type": "string"
                  },
                  "format": {
                    "description": "输出格式，默认 png。png/jpg/gif 返回图片二进制，svg 返回矢量文本，json 返回结构体",
                    "enum": [
                      "png",
                      "jpg",
                      "svg",
                      "gif",
                      "json"
                    ],
                    "example": "png",
                    "type": "string"
                  },
                  "ghost": {
                    "description": "隐形配色的深度：墨色比底色深几级（2~40，默认 6）。越小越隐形、越难扫：2~4 基本看不见但只有程序能解，8 以上手机更容易扫出来",
                    "example": 6,
                    "type": "integer"
                  },
                  "level": {
                    "description": "允许的最低纠错等级，默认 L；容量够时自动取更高等级（响应里的 level 是实际值）",
                    "enum": [
                      "L",
                      "M",
                      "Q",
                      "H"
                    ],
                    "example": "L",
                    "type": "string"
                  },
                  "logo": {
                    "description": "中心 logo：data URL / http(s) 地址 / 裸 base64 / 空字符串不画；multipart 时也可以传 logo 文件。服务器本地路径需开 ALLOW_LOCAL_IMAGE。GIF 动图 + format=gif 会逐帧保留",
                    "type": "string"
                  },
                  "logoRatio": {
                    "description": "logo 半径缩放，0.2~3.0，默认 1（半径 = 108/600 边长）",
                    "example": 1,
                    "type": "number"
                  },
                  "margin": {
                    "description": "位图四周白边（像素），0~200，默认 0",
                    "example": 0,
                    "type": "integer"
                  },
                  "mask": {
                    "description": "掩码：-1 自动在 0~31 里按评分选最优，也可固定 0~31",
                    "example": -1,
                    "type": "integer"
                  },
                  "size": {
                    "description": "位图边长（像素），120~2000，默认 600；对 svg 无效",
                    "example": 600,
                    "type": "integer"
                  },
                  "style": {
                    "description": "笔画风格（只决定形状）：classic（默认，等宽胶囊，与微信原生一致）/ hand（手绘：笔线抖动、粗细不匀、徽标也手贴）/ dot（圆点）/ block（方块）/ line（线描：细环+中心点）。装饰性抖动都控制在半格内，不影响扫码",
                    "enum": [
                      "classic",
                      "hand",
                      "dot",
                      "block",
                      "line"
                    ],
                    "example": "classic",
                    "type": "string"
                  },
                  "text": {
                    "description": "要编码的内容，必填。接口上限 8192 字节；但一枚码只能装几十字节（URL 约 58 字符、中文按字节约 44 字节），超了返回 400",
                    "example": "https://example.com/",
                    "type": "string"
                  },
                  "version": {
                    "description": "码格版本：auto（默认，取最小可容纳）/ 0 / 1 / 2（钉死版本，装不下会报错）",
                    "enum": [
                      "auto",
                      "0",
                      "1",
                      "2"
                    ],
                    "example": "auto",
                    "type": "string"
                  }
                },
                "required": [
                  "text"
                ],
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "codewords": 38,
                  "ecCodewords": 18,
                  "format": "json",
                  "level": "Q",
                  "levelIndex": 2,
                  "mask": 14,
                  "mode": "ALPHANUMERIC",
                  "pngBase64": "iVBORw0KGgoAAAANSUhEUg…（PNG 的 base64，不含 data: 前缀）",
                  "size": 600,
                  "svg": "\u003csvg width=\"600\" height=\"600\" …\u003e（完整 SVG 文本）",
                  "text": "https://example.com/",
                  "transformed": "5M +*-F/2IH%%Q53E9:/-IP",
                  "typebits": 122236,
                  "version": 0
                },
                "schema": {
                  "properties": {
                    "codewords": {
                      "description": "码字总数（数据码字 + 纠错码字）",
                      "type": "integer"
                    },
                    "ecCodewords": {
                      "description": "其中的纠错码字数",
                      "type": "integer"
                    },
                    "format": {
                      "description": "本次输出格式，固定 json",
                      "type": "string"
                    },
                    "level": {
                      "description": "实际纠错等级 L / M / Q / H，容量够时会高于请求的 level",
                      "type": "string"
                    },
                    "levelIndex": {
                      "description": "纠错等级下标：0=L、1=M、2=Q、3=H",
                      "type": "integer"
                    },
                    "logoAnimated": {
                      "description": "仅 logo 是动图时出现，固定 true",
                      "type": "boolean"
                    },
                    "logoFrames": {
                      "description": "仅 logo 是动图时出现：动图帧数",
                      "type": "integer"
                    },
                    "mask": {
                      "description": "实际掩码 0~31；请求 mask=-1 时按评分自动选优",
                      "type": "integer"
                    },
                    "mode": {
                      "description": "数据模式：NUMERIC 纯数字 / ALPHANUMERIC 字母数字 / BYTE 字节",
                      "type": "string"
                    },
                    "pngBase64": {
                      "description": "PNG 的 base64（不含 data: 前缀），配合 data:image/png;base64, 可预览",
                      "type": "string"
                    },
                    "size": {
                      "description": "位图边长（像素），与请求的 size 一致",
                      "type": "integer"
                    },
                    "svg": {
                      "description": "完整 SVG 文本，可直接另存为 .svg",
                      "type": "string"
                    },
                    "text": {
                      "description": "实际编码的内容，与请求的 text 一致",
                      "type": "string"
                    },
                    "transformed": {
                      "description": "仅 ALPHANUMERIC 出现：真正写进码里的变换文本",
                      "type": "string"
                    },
                    "typebits": {
                      "description": "18 位格式信息位（版本 + 纠错等级 + 掩码的编码）",
                      "type": "integer"
                    },
                    "version": {
                      "description": "码格版本 0 / 1 / 2，v0 最小",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                },
                "x-wxcode-example": "{\n  \"text\": \"https://example.com/\",            // 实际编码的内容\n  \"format\": \"json\",                          // 输出格式，固定 json\n  \"version\": 0,                              // 码格版本 0/1/2，v0 最小\n  \"level\": \"Q\",                              // 实际纠错等级（容量够时会升级）\n  \"levelIndex\": 2,                           // 等级下标 0=L 1=M 2=Q 3=H\n  \"mask\": 14,                                // 实际掩码 0~31\n  \"typebits\": 122236,                        // 18 位格式信息位\n  \"mode\": \"ALPHANUMERIC\",                    // 数据模式\n  \"transformed\": \"5M +*-F/2IH%%Q53E9:/-IP\",  // 仅字母数字模式：码内变换文本\n  \"codewords\": 38,                           // 码字总数（数据+纠错）\n  \"ecCodewords\": 18,                         // 其中纠错码字数\n  \"size\": 600,                               // 位图边长（像素）\n  \"svg\": \"\u003csvg width=\\\"600\\\" height=\\\"600\\\" …\u003e（完整 SVG 文本）\",\n  \"pngBase64\": \"iVBORw0KGgoAAAANSUhEUg…（PNG 的 base64，不含 data: 前缀）\"\n}"
              },
              "image/gif": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              },
              "image/jpeg": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              },
              "image/png": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              },
              "image/svg+xml": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "生成成功，返回内容由 format 决定（图片 / SVG / JSON），并带 X-WXCode-* 响应头",
            "x-wxcode-fields": [
              {
                "name": "text",
                "type": "string",
                "description": "实际编码的内容，与请求的 text 一致"
              },
              {
                "name": "format",
                "type": "string",
                "description": "本次输出格式，固定 json"
              },
              {
                "name": "version",
                "type": "integer",
                "description": "码格版本 0 / 1 / 2，v0 最小"
              },
              {
                "name": "level",
                "type": "string",
                "description": "实际纠错等级 L / M / Q / H，容量够时会高于请求的 level"
              },
              {
                "name": "levelIndex",
                "type": "integer",
                "description": "纠错等级下标：0=L、1=M、2=Q、3=H"
              },
              {
                "name": "mask",
                "type": "integer",
                "description": "实际掩码 0~31；请求 mask=-1 时按评分自动选优"
              },
              {
                "name": "typebits",
                "type": "integer",
                "description": "18 位格式信息位（版本 + 纠错等级 + 掩码的编码）"
              },
              {
                "name": "mode",
                "type": "string",
                "description": "数据模式：NUMERIC 纯数字 / ALPHANUMERIC 字母数字 / BYTE 字节"
              },
              {
                "name": "transformed",
                "type": "string",
                "description": "仅 ALPHANUMERIC 出现：真正写进码里的变换文本"
              },
              {
                "name": "codewords",
                "type": "integer",
                "description": "码字总数（数据码字 + 纠错码字）"
              },
              {
                "name": "ecCodewords",
                "type": "integer",
                "description": "其中的纠错码字数"
              },
              {
                "name": "size",
                "type": "integer",
                "description": "位图边长（像素），与请求的 size 一致"
              },
              {
                "name": "svg",
                "type": "string",
                "description": "完整 SVG 文本，可直接另存为 .svg"
              },
              {
                "name": "pngBase64",
                "type": "string",
                "description": "PNG 的 base64（不含 data: 前缀），配合 data:image/png;base64, 可预览"
              },
              {
                "name": "logoAnimated",
                "type": "boolean",
                "description": "仅 logo 是动图时出现，固定 true"
              },
              {
                "name": "logoFrames",
                "type": "integer",
                "description": "仅 logo 是动图时出现：动图帧数"
              }
            ]
          },
          "400": {
            "content": {
              "application/json": {
                "example": {
                  "error": "载荷超出一枚葵花码容量（v0..v2 均装不下，请缩短内容）"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"载荷超出一枚葵花码容量（v0..v2 均装不下，请缩短内容）\"}"
              }
            },
            "description": "内容为空 / 超出容量 / 参数非法"
          },
          "403": {
            "content": {
              "application/json": {
                "example": {
                  "error": "内容包含禁止发布的词语"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"内容包含禁止发布的词语\"}"
              }
            },
            "description": "内容命中黑名单关键词，或 logo / url 指向内网地址"
          },
          "429": {
            "content": {
              "application/json": {
                "example": {
                  "error": "请求过于频繁，请稍后再试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"请求过于频繁，请稍后再试\"}"
              }
            },
            "description": "单 IP 超过每分钟调用上限，响应带 Retry-After"
          },
          "503": {
            "content": {
              "application/json": {
                "example": {
                  "error": "服务繁忙，请稍后重试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"服务繁忙，请稍后重试\"}"
              }
            },
            "description": "同时编码 / 解析的任务已满，请稍后重试"
          }
        },
        "security": [
          {},
          {
            "ApiKey": []
          },
          {
            "SessionCookie": []
          }
        ],
        "summary": "生成太阳码（图片 / JSON）",
        "tags": [
          "生成"
        ],
        "x-order": 0,
        "x-wxcode-auth": "optional",
        "x-wxcode-request-example": "{\n  \"text\": \"https://example.com/\",  // 必填：要编码的内容（接口上限 8192 字节）\n  \"format\": \"png\",                 // 输出格式：png / jpg / svg / gif / json\n  \"size\": 600,                     // 位图边长 120~2000（svg 忽略）\n  \"margin\": 0,                     // 位图四周白边 0~200\n  \"fg\": \"#000000\",                 // 前景色（码点）#rrggbb\n  \"bg\": \"#ffffff\",                 // 背景色 #rrggbb\n  \"level\": \"L\",                    // 允许的最低纠错等级 L/M/Q/H，容量够会自动升级\n  \"version\": \"auto\",               // auto 取最小可容纳；也可钉死 0 / 1 / 2\n  \"mask\": -1,                      // -1 自动选最优掩码；0~31 固定\n  \"logo\": \"\",                      // 中心 logo：data URL / http(s) / 裸 base64，空=不画\n  \"logoRatio\": 1,                  // logo 半径缩放 0.2~3，1 表示 108/600\n  \"badge\": \"default\",              // 角落徽标：default / native / none / 图片地址\n  \"style\": \"classic\",              // 笔画风格：classic / hand / dot / block / line\n  \"color\": \"solid\",                // 配色：solid（用 fg）/ rainbow（色环）/ random（彩虹）/ ghost（隐形）\n  \"ghost\": 6                       // 隐形深度：墨色比底色深几级（color=ghost 时生效）\n}",
        "x-wxcode-try": {
          "mode": "json",
          "fields": [
            {
              "name": "text",
              "in": "body",
              "label": "内容",
              "type": "textarea",
              "value": "https://example.com/"
            },
            {
              "name": "format",
              "in": "body",
              "label": "格式",
              "type": "select",
              "value": "png",
              "options": [
                "png",
                "jpg",
                "svg",
                "gif",
                "json"
              ]
            },
            {
              "name": "size",
              "in": "body",
              "label": "尺寸 px",
              "type": "number",
              "value": 600
            },
            {
              "name": "style",
              "in": "body",
              "label": "笔画风格",
              "type": "select",
              "value": "classic",
              "options": [
                "classic",
                "hand",
                "dot",
                "block",
                "line"
              ]
            },
            {
              "name": "color",
              "in": "body",
              "label": "配色",
              "type": "select",
              "value": "solid",
              "options": [
                "solid",
                "rainbow",
                "random",
                "ghost"
              ]
            },
            {
              "name": "ghost",
              "in": "body",
              "label": "隐形深度",
              "type": "number",
              "value": 6
            }
          ]
        }
      }
    },
    "/api/encode/batch": {
      "post": {
        "description": "一次最多 50 条，逐条独立、逐条计费。顶层参数作用于全部条目，items[].text 为每条内容，\nitems 里也可以用 format / size / margin / fg / bg / logo / logoRatio / badge / style / color / ghost 覆盖顶层值。",
        "operationId": "encodeBatch",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "format": "json",
                "items": [
                  {
                    "text": "https://a.example.com/1"
                  },
                  {
                    "text": "https://b.example.com/2"
                  }
                ],
                "margin": 0,
                "size": 300
              },
              "examples": {
                "默认": {
                  "summary": "最小可用示例",
                  "value": {
                    "format": "json",
                    "items": [
                      {
                        "text": "https://a.example.com/1"
                      },
                      {
                        "text": "https://b.example.com/2"
                      }
                    ],
                    "margin": 0,
                    "size": 300
                  }
                }
              },
              "schema": {
                "properties": {
                  "badge": {
                    "description": "角落徽标 default / native / none / 图片地址",
                    "example": "default",
                    "type": "string"
                  },
                  "bg": {
                    "description": "公共背景色 #rrggbb",
                    "example": "#ffffff",
                    "type": "string"
                  },
                  "color": {
                    "description": "公共配色：solid（用 fg）/ rainbow（色环）/ random（彩虹）/ ghost（隐形）",
                    "enum": [
                      "solid",
                      "rainbow",
                      "random",
                      "ghost"
                    ],
                    "example": "solid",
                    "type": "string"
                  },
                  "fg": {
                    "description": "公共前景色 #rrggbb",
                    "example": "#000000",
                    "type": "string"
                  },
                  "format": {
                    "description": "公共输出格式，默认 png；建议用 json 以便一次拿到 svg + pngBase64",
                    "enum": [
                      "png",
                      "jpg",
                      "svg",
                      "gif",
                      "json"
                    ],
                    "example": "json",
                    "type": "string"
                  },
                  "ghost": {
                    "description": "隐形深度 2~40，默认 6",
                    "example": 6,
                    "type": "integer"
                  },
                  "items": {
                    "description": "内容数组，每项至少要有 text，可逐条覆盖公共参数",
                    "example": [
                      {
                        "text": "https://a.example.com/1"
                      },
                      {
                        "text": "https://b.example.com/2"
                      }
                    ],
                    "items": {
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "level": {
                    "description": "允许的最低纠错等级",
                    "enum": [
                      "L",
                      "M",
                      "Q",
                      "H"
                    ],
                    "example": "L",
                    "type": "string"
                  },
                  "logo": {
                    "description": "公共 logo：data URL / http(s) / 裸 base64",
                    "type": "string"
                  },
                  "logoRatio": {
                    "description": "logo 半径缩放 0.2~3",
                    "example": 1,
                    "type": "number"
                  },
                  "margin": {
                    "description": "公共白边，0~200，默认 0",
                    "example": 0,
                    "type": "integer"
                  },
                  "mask": {
                    "description": "-1 自动，0~31 固定",
                    "example": -1,
                    "type": "integer"
                  },
                  "size": {
                    "description": "公共位图边长，120~2000，默认 600",
                    "example": 300,
                    "type": "integer"
                  },
                  "style": {
                    "description": "公共笔画风格，默认 classic；可选 dot / block / line / hand",
                    "enum": [
                      "classic",
                      "hand",
                      "dot",
                      "block",
                      "line"
                    ],
                    "example": "classic",
                    "type": "string"
                  },
                  "version": {
                    "description": "auto / 0 / 1 / 2",
                    "enum": [
                      "auto",
                      "0",
                      "1",
                      "2"
                    ],
                    "example": "auto",
                    "type": "string"
                  }
                },
                "required": [
                  "items"
                ],
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "charged": 1,
                  "failed": 1,
                  "ok": 1,
                  "results": [
                    {
                      "bytes": 32313,
                      "index": 0,
                      "level": "M",
                      "mask": 7,
                      "mode": "ALPHANUMERIC",
                      "ms": 19,
                      "ok": true,
                      "pngBase64": "iVBORw0KGgoAAAANSUhEUg…",
                      "svg": "\u003csvg width=\"300\" height=\"300\" …\u003e",
                      "text": "https://a.example.com/1",
                      "version": 0
                    },
                    {
                      "error": "内容过长（上限 8192 字节）",
                      "index": 1,
                      "ok": false,
                      "text": "https://b.example.com/2"
                    }
                  ],
                  "total": 2
                },
                "schema": {
                  "properties": {
                    "charged": {
                      "description": "本次实际扣掉的额度条数；示例 / 重复 / 失败的内容不计",
                      "type": "integer"
                    },
                    "failed": {
                      "description": "失败的条数",
                      "type": "integer"
                    },
                    "ok": {
                      "description": "成功的条数",
                      "type": "integer"
                    },
                    "results": {
                      "description": "逐条结果，顺序与请求的 items 一致",
                      "items": {
                        "properties": {
                          "bytes": {
                            "description": "该条图片字节数；format=svg 时不出现",
                            "type": "integer"
                          },
                          "error": {
                            "description": "失败原因；成功时不出现",
                            "type": "string"
                          },
                          "index": {
                            "description": "对应请求 items 的下标，从 0 开始",
                            "type": "integer"
                          },
                          "level": {
                            "description": "该条实际纠错等级",
                            "type": "string"
                          },
                          "mask": {
                            "description": "该条实际掩码",
                            "type": "integer"
                          },
                          "mode": {
                            "description": "该条数据模式",
                            "type": "string"
                          },
                          "ms": {
                            "description": "该条耗时（毫秒）",
                            "type": "integer"
                          },
                          "ok": {
                            "description": "该条是否成功；失败的条目其余字段都不出现",
                            "type": "boolean"
                          },
                          "pngBase64": {
                            "description": "该条图片的 base64；format 不是 svg 时才有",
                            "type": "string"
                          },
                          "svg": {
                            "description": "该条 SVG 文本；format=svg 或 json 时才有",
                            "type": "string"
                          },
                          "text": {
                            "description": "该条要编码的内容",
                            "type": "string"
                          },
                          "version": {
                            "description": "该条的码格版本",
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "total": {
                      "description": "提交的总条数（= ok + failed）",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                },
                "x-wxcode-example": "{\n  \"ok\": 1,                                      // 成功条数\n  \"failed\": 1,                                  // 失败条数\n  \"total\": 2,                                   // 总条数 = ok + failed\n  \"charged\": 1,                                 // 实际扣的额度（示例/重复/失败不计）\n  \"results\": [                                  // 逐条结果，顺序与 items 一致\n    {\n      \"index\": 0,                               // 对应 items 下标，从 0 开始\n      \"text\": \"https://a.example.com/1\",        // 该条内容\n      \"ok\": true,                               // 该条是否成功\n      \"version\": 0,                             // 该条码格版本\n      \"level\": \"M\",                             // 该条实际纠错等级\n      \"mask\": 7,                                // 该条实际掩码\n      \"mode\": \"ALPHANUMERIC\",                   // 该条数据模式\n      \"svg\": \"\u003csvg width=\\\"300\\\" height=\\\"300\\\" …\u003e\",  // 该条 SVG（format=svg/json）\n      \"pngBase64\": \"iVBORw0KGgoAAAANSUhEUg…\",  // 该条图片 base64（非 svg）\n      \"bytes\": 32313,                           // 该条图片字节数\n      \"ms\": 19                                  // 该条耗时（毫秒）\n    },\n    {\n      \"index\": 1,                               // 第 2 条\n      \"text\": \"https://b.example.com/2\",\n      \"ok\": false,                              // 失败\n      \"error\": \"内容过长（上限 8192 字节）\"  // 失败原因\n    }\n  ]\n}"
              }
            },
            "description": "逐条结果：整体仍是 200，单条成败看 results[].ok",
            "x-wxcode-fields": [
              {
                "name": "ok",
                "type": "integer",
                "description": "成功的条数"
              },
              {
                "name": "failed",
                "type": "integer",
                "description": "失败的条数"
              },
              {
                "name": "total",
                "type": "integer",
                "description": "提交的总条数（= ok + failed）"
              },
              {
                "name": "charged",
                "type": "integer",
                "description": "本次实际扣掉的额度条数；示例 / 重复 / 失败的内容不计"
              },
              {
                "name": "results",
                "type": "array",
                "description": "逐条结果，顺序与请求的 items 一致"
              },
              {
                "name": "results[].index",
                "type": "integer",
                "description": "对应请求 items 的下标，从 0 开始"
              },
              {
                "name": "results[].text",
                "type": "string",
                "description": "该条要编码的内容"
              },
              {
                "name": "results[].ok",
                "type": "boolean",
                "description": "该条是否成功；失败的条目其余字段都不出现"
              },
              {
                "name": "results[].error",
                "type": "string",
                "description": "失败原因；成功时不出现"
              },
              {
                "name": "results[].version",
                "type": "integer",
                "description": "该条的码格版本"
              },
              {
                "name": "results[].level",
                "type": "string",
                "description": "该条实际纠错等级"
              },
              {
                "name": "results[].mask",
                "type": "integer",
                "description": "该条实际掩码"
              },
              {
                "name": "results[].mode",
                "type": "string",
                "description": "该条数据模式"
              },
              {
                "name": "results[].svg",
                "type": "string",
                "description": "该条 SVG 文本；format=svg 或 json 时才有"
              },
              {
                "name": "results[].pngBase64",
                "type": "string",
                "description": "该条图片的 base64；format 不是 svg 时才有"
              },
              {
                "name": "results[].bytes",
                "type": "integer",
                "description": "该条图片字节数；format=svg 时不出现"
              },
              {
                "name": "results[].ms",
                "type": "integer",
                "description": "该条耗时（毫秒）"
              }
            ]
          },
          "400": {
            "content": {
              "application/json": {
                "example": {
                  "error": "items 不能为空"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"items 不能为空\"}"
              }
            },
            "description": "items 为空 / 超过 50 条 / JSON 不合法"
          },
          "413": {
            "content": {
              "application/json": {
                "example": {
                  "error": "请求体超过大小上限"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"请求体超过大小上限\"}"
              }
            },
            "description": "请求体超过 4MB 上限"
          },
          "429": {
            "content": {
              "application/json": {
                "example": {
                  "error": "请求过于频繁，请稍后再试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"请求过于频繁，请稍后再试\"}"
              }
            },
            "description": "超过每分钟调用上限"
          }
        },
        "security": [
          {},
          {
            "ApiKey": []
          },
          {
            "SessionCookie": []
          }
        ],
        "summary": "批量生成太阳码",
        "tags": [
          "生成"
        ],
        "x-order": 2,
        "x-wxcode-auth": "optional",
        "x-wxcode-request-example": "{\n  \"format\": \"json\",                         // 公共格式：建议 json，可一次拿到 svg + pngBase64\n  \"size\": 300,                              // 公共边长，120~2000\n  \"margin\": 0,                              // 公共白边\n  \"items\": [                                // 必填，1~50 条，逐条独立处理\n    { \"text\": \"https://a.example.com/1\" },  // 第 1 条\n    { \"text\": \"https://b.example.com/2\" }   // 第 2 条（可用 format/size/logo 覆盖顶层）\n  ]\n}",
        "x-wxcode-try": {
          "mode": "json-editor",
          "template": "{\n  \"format\": \"json\",\n  \"size\": 300,\n  \"items\": [\n    {\"text\": \"https://a.example.com/1\"},\n    {\"text\": \"https://b.example.com/2\"}\n  ]\n}"
        }
      }
    },
    "/api/qr": {
      "post": {
        "description": "读取普通 QR。微信「加好友」名片会解出 https://u.wechat.com/... 这类链接，\nurl 字段可直接丢给 /api/encode 再生成太阳码。",
        "operationId": "qr",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "image": "data:image/png;base64,iVBORw0KGgo…"
              },
              "examples": {
                "默认": {
                  "summary": "最小可用示例",
                  "value": {
                    "image": "data:image/png;base64,iVBORw0KGgo…"
                  }
                }
              },
              "schema": {
                "properties": {
                  "image": {
                    "description": "data URL / 裸 base64 / http(s) 图片地址",
                    "type": "string"
                  },
                  "url": {
                    "description": "图片 URL，与 image 二选一（仅公网）",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            },
            "application/octet-stream": {
              "schema": {
                "format": "binary",
                "type": "string"
              }
            },
            "multipart/form-data": {
              "schema": {
                "properties": {
                  "file": {
                    "description": "二维码图片文件（也接受 image）",
                    "format": "binary",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "corrections": 0,
                  "ecLevel": "M",
                  "mask": 3,
                  "mode": "BYTE",
                  "modules": 33,
                  "text": "https://u.wechat.com/xxxxxxxxxxxx",
                  "url": "https://u.wechat.com/xxxxxxxxxxxx",
                  "version": 4
                },
                "schema": {
                  "properties": {
                    "corrections": {
                      "description": "RS 纠错修掉的码字数，0 表示原图很干净",
                      "type": "integer"
                    },
                    "ecLevel": {
                      "description": "纠错等级 L / M / Q / H",
                      "type": "string"
                    },
                    "mask": {
                      "description": "掩码 0~7",
                      "type": "integer"
                    },
                    "mode": {
                      "description": "数据模式 NUMERIC / ALPHANUMERIC / BYTE，多段时用 + 连接",
                      "type": "string"
                    },
                    "modules": {
                      "description": "边长模块数 = 17 + 4 × version",
                      "type": "integer"
                    },
                    "text": {
                      "description": "二维码里的完整文本",
                      "type": "string"
                    },
                    "url": {
                      "description": "文本中的 http(s) 链接；没有链接则不存在，可直接丢给 /api/encode",
                      "type": "string"
                    },
                    "version": {
                      "description": "QR 版本 1~40",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                },
                "x-wxcode-example": "{\n  \"text\": \"https://u.wechat.com/xxxxxxxxxxxx\",  // 二维码里的完整文本\n  \"url\": \"https://u.wechat.com/xxxxxxxxxxxx\",   // 其中的链接，可直接给 /api/encode\n  \"version\": 4,                                 // QR 版本 1~40\n  \"ecLevel\": \"M\",                               // 纠错等级\n  \"mask\": 3,                                    // 掩码 0~7\n  \"mode\": \"BYTE\",                               // 数据模式\n  \"modules\": 33,                                // 模块边长 = 17 + 4 × version\n  \"corrections\": 0                              // RS 修掉的码字数\n}"
              }
            },
            "description": "识别成功，返回二维码文本与其中的链接",
            "x-wxcode-fields": [
              {
                "name": "text",
                "type": "string",
                "description": "二维码里的完整文本"
              },
              {
                "name": "url",
                "type": "string",
                "description": "文本中的 http(s) 链接；没有链接则不存在，可直接丢给 /api/encode"
              },
              {
                "name": "version",
                "type": "integer",
                "description": "QR 版本 1~40"
              },
              {
                "name": "ecLevel",
                "type": "string",
                "description": "纠错等级 L / M / Q / H"
              },
              {
                "name": "mask",
                "type": "integer",
                "description": "掩码 0~7"
              },
              {
                "name": "mode",
                "type": "string",
                "description": "数据模式 NUMERIC / ALPHANUMERIC / BYTE，多段时用 + 连接"
              },
              {
                "name": "modules",
                "type": "integer",
                "description": "边长模块数 = 17 + 4 × version"
              },
              {
                "name": "corrections",
                "type": "integer",
                "description": "RS 纠错修掉的码字数，0 表示原图很干净"
              }
            ]
          },
          "400": {
            "content": {
              "application/json": {
                "example": {
                  "error": "没找到二维码的定位图案"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"没找到二维码的定位图案\"}"
              }
            },
            "description": "没找到定位图案 / 校验失败 / 图片不合法"
          },
          "429": {
            "content": {
              "application/json": {
                "example": {
                  "error": "请求过于频繁，请稍后再试"
                },
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "x-wxcode-example": "{\"error\":\"请求过于频繁，请稍后再试\"}"
              }
            },
            "description": "超过每分钟调用上限"
          }
        },
        "security": [
          {},
          {
            "ApiKey": []
          },
          {
            "SessionCookie": []
          }
        ],
        "summary": "解析普通二维码（好友码）",
        "tags": [
          "解析"
        ],
        "x-order": 4,
        "x-wxcode-auth": "optional",
        "x-wxcode-request-example": "{\n  \"image\": \"data:image/png;base64,iVBORw0KGgo…\",  // 必填其一：data URL / 裸 base64 / http(s) 图片地址\n  // 也可以只给图片地址：\"url\": \"https://example.com/code.png\"\n  // 或者根本不发 JSON：直接 multipart -F 'file=@code.png'，或把图片字节当 body 发\n}",
        "x-wxcode-try": {
          "mode": "multipart",
          "fields": [
            {
              "name": "file",
              "in": "file",
              "label": "二维码图片",
              "type": "file",
              "required": true
            }
          ]
        }
      }
    }
  },
  "servers": [
    {
      "description": "当前站点",
      "url": "https://khm.lxwowbp.cn"
    }
  ],
  "tags": [
    {
      "description": "生成太阳码图片或 JSON",
      "name": "生成"
    },
    {
      "description": "太阳码、普通二维码识别",
      "name": "解析"
    }
  ],
  "x-wxcode-request-id": "X-Request-ID",
  "x-wxcode-version": "1.1.0"
}