ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

二维码在企业系统里怎么用?资产标签、产品页和客户入口

2026/9/27 22:48:29 拓冰建站 浏览量
二维码在企业系统里怎么用?资产标签、产品页和客户入口 二维码在企业系统里很常见贴在设备上扫一下报修贴在产品包装上扫一下看说明书放在展会物料上扫一下打开产品页放在客户服务卡上扫一下提交售后单。但二维码不是“把 URL 生成成一张图片”这么简单。如果二维码里直接写死页面地址后续页面改版、对象下架、权限变化、统计分析、码被复制滥用都会变得很麻烦。更稳的做法是把二维码当成业务入口二维码只保存一个短码或 token扫码后先到服务端解析再根据业务类型、状态、权限和访问场景跳转。本文用三个场景串起来讲设备标签扫码报修产品标签扫码打开公开展示页客户入口扫码提交售后。它们都使用二维码但边界完全不同设备报修可能需要登录和内部权限产品展示页可以公开访问售后入口可能允许匿名提交但要防刷。示例环境Java 17、Spring Boot 风格服务层、MySQL 8.x。本文会给出表结构、轻量代码骨架和 SQL 验证重点放在二维码入口设计而不是生成二维码图片的工具细节。目录二维码先分清三种入口输入案例设备报修、产品页和客户入口二维码里不要直接写死最终URLMySQL表结构二维码、目标对象和扫码日志实现骨架扫码先解析再跳转权限、失效和防复制SQL验证上线后查扫码入口是否健康异常边界和上线验收小结和延伸阅读一、二维码先分清三种入口二维码不是一种业务它只是入口。入口背后的访问规则不同设计也应该不同。入口类型常见场景访问规则内部业务入口设备报修、资产盘点、仓库入库需要登录按组织和角色校验权限公开展示入口产品介绍页、说明书、活动页可匿名访问但要能下架和统计半公开服务入口售后登记、客户反馈、预约申请可匿名提交但要防刷、防伪和限流如果把这三类都做成“扫码打开一个固定 URL”早期很快后期很难管。内部业务会担心越权公开页面会担心链接失效售后入口会担心被恶意提交。所以二维码系统要先保存入口类型再决定是否登录、是否校验权限、是否允许匿名、是否记录扫码日志、是否允许目标变更。图1内部业务、公开展示和半公开服务入口的权限边界不同。二、输入案例设备报修、产品页和客户入口本文固定三组输入分别对应三类入口。入口1设备报修 二维码编号QR-ASSET-20260926-001 业务类型ASSET_REPAIR 目标对象设备 AS-1008 访问规则需要登录员工只能提交报修管理员可查看设备详情 入口2产品展示页 二维码编号QR-PRODUCT-20260926-002 业务类型PRODUCT_PAGE 目标对象产品 P-2026-EN 访问规则公开访问产品下架后跳转到下架说明页 入口3客户售后入口 二维码编号QR-SERVICE-20260926-003 业务类型CUSTOMER_SERVICE 目标对象客户服务表单 访问规则允许匿名需要验证码或限流记录来源渠道这三个入口说明了一个关键点二维码图案可以长得一样但服务端解析规则不能一样。设备报修关注内部权限产品页关注公开可访问和可下架客户售后关注匿名提交和防刷。把这些规则写在二维码图片里做不到必须回到服务端解析。三、二维码里不要直接写死最终URL二维码内容建议是一个短链接或短码例如https://example.com/q/8f3K2p而不是https://example.com/product/detail?id1008langen短码方式有几个好处。第一目标可变。产品页改版、路径调整、对象迁移都可以在后台更新目标不需要重新印刷二维码。第二可以下架。产品停产、设备报废、活动结束后二维码可以显示下架说明而不是继续打开旧页面。第三可以统计。服务端能记录扫码时间、来源、设备、渠道和跳转结果。第四可以做权限判断。内部入口扫码后先登录再判断用户是否能访问该设备或工单。第五可以防滥用。半公开入口可以加验证码、频控、签名、一次性 token 或短期有效链接。当然短码不等于绝对安全。短码要足够随机不能用连续数字内部数据不能因为知道短码就直接访问敏感场景还要结合登录态和权限。图2二维码保存短码服务端负责解析目标、权限、状态和统计。四、MySQL表结构二维码、目标对象和扫码日志二维码至少要有主表和扫码日志表。主表记录入口规则日志表记录访问结果。CREATETABLEbiz_qr_code(idBIGINTPRIMARYKEYAUTO_INCREMENT,tenant_idBIGINTNOTNULL,qr_codeVARCHAR(64)NOTNULL,entry_typeVARCHAR(64)NOTNULL,target_typeVARCHAR(64)NOTNULL,target_idBIGINTNULL,target_keyVARCHAR(120)NULL,titleVARCHAR(160)NOTNULL,statusVARCHAR(32)NOTNULL,access_modeVARCHAR(32)NOTNULL,expire_timeDATETIMENULL,redirect_urlVARCHAR(500)NULL,create_byBIGINTNOTNULL,create_timeDATETIMENOTNULL,update_byBIGINTNULL,update_timeDATETIMENULL,UNIQUEKEYuk_qr_code(qr_code),KEYidx_qr_target(tenant_id,target_type,target_id),KEYidx_qr_status(tenant_id,status));CREATETABLEbiz_qr_scan_log(idBIGINTPRIMARYKEYAUTO_INCREMENT,tenant_idBIGINTNULL,qr_codeVARCHAR(64)NOTNULL,entry_typeVARCHAR(64)NOTNULL,target_typeVARCHAR(64)NULL,target_idBIGINTNULL,scan_user_idBIGINTNULL,anonymous_idVARCHAR(120)NULL,client_ipVARCHAR(64)NULL,user_agentVARCHAR(300)NULL,result_codeVARCHAR(64)NOTNULL,redirect_urlVARCHAR(500)NULL,create_timeDATETIMENOTNULL,KEYidx_qr_scan_code(qr_code,create_time),KEYidx_qr_scan_result(result_code,create_time));字段含义要清楚。qr_code是短码不建议用自增ID。可以用随机字符串或带签名的 token降低被猜测的概率。entry_type表示入口类型例如ASSET_REPAIR、PRODUCT_PAGE、CUSTOMER_SERVICE。服务端根据入口类型选择不同解析策略。access_mode表示访问方式例如LOGIN_REQUIRED、PUBLIC、ANONYMOUS_FORM。它决定是否需要登录、是否允许匿名、是否需要验证码或限流。status用来控制二维码是否有效。常见状态包括ACTIVE、DISABLED、EXPIRED、ARCHIVED。扫码日志不要只记成功。失败、下架、无权限、过期、被限流也要记录。否则上线后只能看到“有人扫了”看不出为什么转化低。图3二维码主表定义入口规则扫码日志记录访问结果和转化情况。五、实现骨架扫码先解析再跳转扫码入口的服务端逻辑可以很薄但边界要完整。publicQrResolveResultresolve(StringqrCode,ScanContextcontext){QrCodeEntryentryqrCodeRepository.getByCode(qrCode);if(entrynull){scanLogRepository.insert(ScanLog.failed(qrCode,context,NOT_FOUND));returnQrResolveResult.notFound();}if(!ACTIVE.equals(entry.status())||entry.isExpired()){scanLogRepository.insert(ScanLog.failed(entry,context,DISABLED_OR_EXPIRED));returnQrResolveResult.disabled(entry.title());}QrResolveResultresultswitch(entry.entryType()){caseASSET_REPAIR-resolveAssetRepair(entry,context);casePRODUCT_PAGE-resolveProductPage(entry,context);caseCUSTOMER_SERVICE-resolveCustomerService(entry,context);default-QrResolveResult.failed(UNSUPPORTED_ENTRY_TYPE);};scanLogRepository.insert(ScanLog.from(entry,context,result));returnresult;}内部设备报修需要登录和权限privateQrResolveResultresolveAssetRepair(QrCodeEntryentry,ScanContextcontext){if(context.userId()null){returnQrResolveResult.loginRequired(/mobile/login?next/q/entry.qrCode());}AssetassetassetRepository.getById(entry.targetId());dataScopeChecker.requireReadable(context.userId(),asset.tenantId(),asset.deptId());returnQrResolveResult.redirect(/mobile/repair/create?assetIdasset.id());}公开产品页不需要登录但要判断产品是否上架privateQrResolveResultresolveProductPage(QrCodeEntryentry,ScanContextcontext){ProductPagepageproductPageRepository.getById(entry.targetId());if(pagenull||!PUBLISHED.equals(page.status())){returnQrResolveResult.redirect(/public/product/offline);}returnQrResolveResult.redirect(/public/product/page.slug());}这里代码不多重点是不要让二维码绕过正常业务权限。二维码只是入口不是授权凭证。六、权限、失效和防复制二维码上线后最常见的三个问题是码被复制、目标下架、匿名入口被刷。码被复制如果二维码贴在设备上别人拍照转发理论上也能打开入口。所以内部业务入口不能只靠二维码判断权限必须登录后再校验用户对设备或工单的访问权限。目标下架产品页、活动页、说明书都可能下架。二维码不能变成 404。更好的体验是跳转到“产品已下架/活动已结束”的说明页同时记录扫码日志。匿名入口被刷售后登记、预约申请这类入口如果允许匿名提交要加验证码、IP 限流、设备指纹、提交频率限制。否则二维码一旦外泄表单可能被恶意刷爆。静态码和动态码的取舍静态码适合长期标签例如设备标签、产品包装。它的优势是可打印、可长期使用。动态码适合短期访问例如一次性登录、临时授权、支付确认。它的优势是可过期、防复制能力更强。二维码内容是否加签如果二维码里包含业务参数建议做签名和过期时间。但对长期静态码来说更推荐只放随机短码服务端查表判断状态和权限。图4二维码不能替代权限失效、下架、防刷都要回到服务端处理。七、SQL验证上线后查扫码入口是否健康二维码上线后要能看到每类入口的扫码结果。查看最近扫码结果分布SELECTentry_type,result_code,COUNT(*)AScntFROMbiz_qr_scan_logWHEREcreate_timeDATE_SUB(NOW(),INTERVAL7DAY)GROUPBYentry_type,result_codeORDERBYentry_type,cntDESC;如果NO_PERMISSION很多说明用户扫到了入口但权限配置不合理如果DISABLED_OR_EXPIRED很多说明线下物料可能还在流通。检查仍被扫描的下架二维码SELECTq.qr_code,q.title,q.status,COUNT(l.id)ASscan_countFROMbiz_qr_code qJOINbiz_qr_scan_log lONl.qr_codeq.qr_codeWHEREq.statusACTIVEANDl.create_timeDATE_SUB(NOW(),INTERVAL30DAY)GROUPBYq.qr_code,q.title,q.statusORDERBYscan_countDESC;检查匿名入口是否异常高频SELECTqr_code,client_ip,COUNT(*)AScntFROMbiz_qr_scan_logWHEREentry_typeCUSTOMER_SERVICEANDcreate_timeDATE_SUB(NOW(),INTERVAL1DAY)GROUPBYqr_code,client_ipHAVINGCOUNT(*)50;检查二维码是否绑定了不存在的目标SELECTq.id,q.qr_code,q.target_type,q.target_idFROMbiz_qr_code qLEFTJOINproduct_page pONq.target_typePRODUCT_PAGEANDp.idq.target_idWHEREq.target_typePRODUCT_PAGEANDp.idISNULL;预期结果empty set图5扫码日志要能查结果分布、下架扫码、异常高频和目标缺失。八、异常边界和上线验收二维码入口至少要考虑这些边界。二维码丢失或被复制内部入口必须登录和校验权限。不能因为用户拿到二维码图片就能查看内部资料。目标对象被删除扫码时不能报 500。应该显示目标不存在或已下架并记录日志方便运营处理旧物料。二维码状态被停用停用后应该立即生效。不要让缓存继续解析到旧目标。线下物料已印刷二维码一旦贴出去很难回收。所以不要把最终页面地址写死在二维码里服务端解析可以给后续调整留余地。公开页面 SEO 和语言产品页可能要支持中文、英文、移动端适配和分享预览。二维码入口可以根据参数或浏览器语言跳转不同页面但要保证默认页面可用。上线验收可以按下面清单执行二维码内容是短码或短链接不是最终业务 URL。内部入口扫码后需要登录。内部入口登录后按业务权限校验。公开入口可以匿名访问但目标下架后有说明页。半公开表单有验证码或频控。二维码停用后立即无法继续跳转到原目标。扫码成功、失败、无权限、下架、限流都有日志。二维码目标可在后台变更。缓存不会让停用状态延迟生效太久。SQL 能查出异常高频扫码和目标缺失。九、小结和延伸阅读二维码在企业系统里不是一张图片而是一个业务入口。它可以贴在设备上、产品上、展会物料上也可以作为客户服务入口。但入口背后的权限、状态、统计、失效和防刷必须由服务端接住。实际落地时建议二维码只放短码扫码后进入统一解析服务。解析服务根据入口类型判断是否登录、是否可访问、目标是否有效、是否需要限流再决定跳转到哪里。这样二维码印出去以后系统仍然有调整、下架、统计和治理的空间。延伸阅读OWASPAuthentication Cheat SheetOWASPAuthorization Cheat SheetMySQL 8.4CREATE TABLE