fix: 扫码取码兼容带域名的完整 URL 二维码
二维码内容有两种可能,旧逻辑只做「去掉非字母数字后截前 16 位」,扫到带域名 的 URL 时会把 "https"、主机名一起当成 SN 的前半段,截出来是个完全不存在的 号,永远提示「未找到该产品」。 - 先把 "协议://主机名" 整段剥掉,否则域名会被当成候选 SN (如 trackbackirisrscn 这类 17 位串,恰好能通过长度校验) - 在剩余内容里找长度 >= 8 的连续字母数字串,取最长的一段; 等长时取靠后的 —— URL 里 SN 通常在路径末尾
This commit is contained in:
@ -75,13 +75,44 @@ export default {
|
||||
},
|
||||
handleSearch() { this.doQuery(this.serialNumber.trim()); },
|
||||
|
||||
// 📷 从扫码原始文本中提取设备身份证(SN)
|
||||
// 二维码内容有两种可能,必须都兼容:
|
||||
// ① 裸 SN → ABC1234567890DEF
|
||||
// ② 带域名的完整 URL → https://track.iris-rs.cn/sn/ABC1234567890DEF?from=label
|
||||
// 旧逻辑只是「去掉非字母数字后截前 16 位」,扫到 ② 时会把 "https"、域名
|
||||
// 一起当成 SN 的前半段,截出来是个完全不存在的号,永远提示"未找到该产品"。
|
||||
extractSerial(raw) {
|
||||
const text = String(raw || "").trim();
|
||||
if (!text) return "";
|
||||
|
||||
// 关键一步:先把 "协议://主机名" 整段剥掉,否则域名会被当成候选 SN
|
||||
// (如 trackbackirisrscn 这种 17 位串,恰好能通过长度校验)。
|
||||
let body = text;
|
||||
const origin = text.match(/^[a-z][a-z0-9+.-]*:\/\/[^/?#]+/i);
|
||||
if (origin) body = text.slice(origin[0].length);
|
||||
|
||||
// 在剩余内容里找长度 >= 8 的连续字母数字串(身份证至少 8 位)。
|
||||
// 取最长的一段;等长时取靠后的 —— URL 里 SN 通常在路径末尾。
|
||||
const runs = body.match(/[a-zA-Z0-9]{8,}/g) || [];
|
||||
if (!runs.length) return "";
|
||||
let best = runs[0];
|
||||
for (const run of runs) {
|
||||
if (run.length >= best.length) best = run;
|
||||
}
|
||||
return best.slice(0, 16);
|
||||
},
|
||||
|
||||
// 📷 全屏相机扫码
|
||||
handleScanCamera() {
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
scanType: ["qrCode", "barCode"],
|
||||
success: (res) => {
|
||||
const sn = (res.result || "").replace(/[^a-zA-Z0-9]/g, "").slice(0, 16);
|
||||
const sn = this.extractSerial(res.result);
|
||||
if (!sn) {
|
||||
uni.showToast({ title: "无法识别二维码内容,请确认扫的是设备标签", icon: "none", duration: 2500 });
|
||||
return;
|
||||
}
|
||||
this.doQuery(sn);
|
||||
},
|
||||
fail: (err) => {
|
||||
|
||||
Reference in New Issue
Block a user