Uniapp微信小程序:自定义海报生成方案。支持保存到本地,二维码生成,富文本解析(个人学习记录) 📅 发布时间:2026/7/15 13:10:52 👁️ 浏览次数: 示例代码template view classpage :style{ paddingTop: 180 rpx } !-- 页面主体内容 -- view classpage-content !-- 标题区域 -- view classtitle邀请好友加入龙集/view view classsub-title邀请好友扫码有惊喜/view !-- 海报生成容器l-painter -- l-painter csswidth:680rpx; height: 800rpx; position: absolute;top:0rpx; zIndex: 1;background: #FFFFFF; failhandlePainterFail donehandlePainterDone pathTypeurl refposterRef performance !-- 海报背景图 -- !-- l-painter-image src../static/icons/qrcode_bg.png csswidth: 680rpx; height: 800rpx;position: absolute; top: 50%; left: 50%;transform: translate(-50%,-50%); zIndex: 1 / -- !-- Logo -- !-- l-painter-image src../static/icons/会员卡.png csswidth: 82px; height: 82rpx; position: absolute; top: 44rpx; left: 50%; transform: translateX(-50%); zIndex: 1 / -- !-- 主标题 -- l-painter-text text龙集 cssfont-size: 44rpx; line-height: 64rpx; font-weight: 600; color: #333; position: absolute; top: 138rpx; left: 50%; transform: translateX(-50%);zIndex: 1 / !-- 副标题 -- l-painter-text text邀请好友扫码有惊喜 cssfont-size: 28rpx; line-height: 40rpx; color: #999; position: absolute; top: 214rpx; left: 50%; transform: translateX(-50%); / !-- 二维码 -- l-painter-qrcode cssposition: absolute;top:350rpx;zIndex: 9;width: 260rpx; height: 260rpx;margin:0 auto; :textqrcodeContent :options{ useDynamicSize: true, areaColor: transparent, backgroundColor: transparent, foregroundColor: #400303, margin: 30 } / /l-painter !-- 操作按钮区域 -- view classqr-option view classitem view classsaveIamge clickhandleSavePoster保存图片/view /view /view /view /view /template script setup import { ref } from vue; // 二维码内容 const qrcodeContent ref(code:58086544); // 海报相关状态 const posterRef ref(null); // 海报组件引用 const isPosterRendered ref(false); // 海报是否绘制完成 const isSavingPoster ref(false); // 是否正在保存海报 const tempPosterPath ref(); // 海报临时文件路径 /** * 海报绘制失败回调 */ const handlePainterFail () { console.error([海报绘制] 失败); isPosterRendered.value false; uni.showToast({ title: 海报生成失败, icon: none }); }; /** * 海报绘制完成回调 */ const handlePainterDone () { console.log([海报绘制] 完成); isPosterRendered.value true; // 标记绘制完成 }; /** * 保存海报到相册 */ const handleSavePoster async () { // 校验1海报未绘制完成 if (!isPosterRendered.value) { uni.showToast({ title: 海报正在生成请稍后, icon: none, duration: 1500 }); return; } // 校验2正在保存中防止重复点击 if (isSavingPoster.value) return; try { isSavingPoster.value true; uni.showLoading({ title: 保存中..., mask: true }); // 生成海报临时文件路径 const posterRes await posterRef.value.canvasToTempFilePath({ fileType: jpg, quality: 1, pathType: url }); // 校验临时路径是否生成成功 if (posterRes posterRes.tempFilePath) { tempPosterPath.value posterRes.tempFilePath; await saveImageToAlbum(); // 保存到相册 } else { uni.showToast({ title: 获取海报临时路径失败, icon: none }); } } catch (error) { console.error([海报保存] 生成临时路径失败, error); uni.showToast({ title: 海报保存失败, icon: none, duration: 2000 }); } finally { isSavingPoster.value false; // 解锁保存状态 uni.hideLoading(); // 隐藏加载提示 } }; /** * 保存图片到相册权限处理 */ const saveImageToAlbum () { return new Promise((resolve, reject) { // #ifndef H5 // 1. 获取用户授权设置 uni.getSetting({ success: (settingRes) { // 已授权相册权限 if (settingRes.authSetting[scope.writePhotosAlbum]) { doSaveToAlbum(resolve, reject); } // 未授权发起授权请求 else { uni.authorize({ scope: scope.writePhotosAlbum, success: () doSaveToAlbum(resolve, reject), fail: () handleAuthFail(resolve, reject) }); } }, fail: () { uni.showToast({ title: 获取授权状态失败, icon: none, duration: 2000 }); reject(获取授权状态失败); } }); // #endif }); }; /** * 处理相册授权失败逻辑 */ const handleAuthFail (resolve, reject) { uni.showModal({ title: 授权提示, content: 需要授权相册权限才能保存图片请前往设置开启, confirmText: 去设置, cancelText: 取消, success: (modalRes) { if (modalRes.confirm) { // 打开设置页面 uni.openSetting({ success: (openRes) { if (openRes.authSetting[scope.writePhotosAlbum]) { doSaveToAlbum(resolve, reject); } else { uni.showToast({ title: 未开启授权保存失败, icon: none }); reject(用户未开启相册授权); } }, fail: () { uni.showToast({ title: 打开设置失败, icon: none }); reject(打开设置页面失败); } }); } else { reject(用户取消授权); } }, fail: () reject(模态框调用失败) }); }; /** * 实际执行保存到相册操作 */ const doSaveToAlbum (resolve, reject) { uni.saveImageToPhotosAlbum({ filePath: tempPosterPath.value, success: () { resolve(); uni.showToast({ title: 已保存到相册, icon: success, duration: 2000 }); }, fail: (error) { console.error([相册保存] 失败, error); reject(error); uni.showToast({ title: 保存相册失败, icon: none, duration: 2000 }); } }); }; /script style langscss scoped .page { min-height: 100vh; background-color: #F8F8FA; box-sizing: border-box; position: relative; } .page-content { text-align: center; padding: 35rpx; .title { font-weight: 600; font-size: 48rpx; color: #3D3D3D; line-height: 70rpx; margin-top: 54rpx; } .sub-title { font-weight: 400; font-size: 24rpx; color: #333333; line-height: 34rpx; margin-top: 12rpx; margin-bottom: 30rpx; } .qr-option { margin-top: 60rpx; display: flex; padding: 0 40rpx; justify-content: space-around; .item { display: flex; flex-direction: column; align-items: center; gap: 6rpx; .saveIamge { font-size: 36rpx; line-height: 52rpx; color: #3D3D3D; width: 322rpx; height: 118rpx; background: #FFFFFF; display: flex; justify-content: center; align-items: center; border-radius: 100rpx; } } } } /style依赖插件https://ext.dcloud.net.cn/plugin?id2389
【JavaEE安全】Spring Boot 安全实战:Actuator 监控泄漏与 Swagger 接口利用 警告:以下内容仅用于安全研究与授权测试,未经许可的攻击行为属于违法行为。一、Spring Boot Actuator:监控端点与信息泄漏 1.1 Actuator 核心端点与风险 Actuator 提供了一系列生产环境监控端点,若暴露不当,会导致严重… 2026/5/17 9:19:41
【JavaEE安全】Spring Boot 安全实战:JWT 身份鉴权与打包部署 警告:以下内容仅用于安全研究与授权测试,未经许可的攻击行为属于违法行为。一、JWT 身份鉴权:原理与实战 1.1 JWT 结构与工作流 JWT(JSON Web Token)是一种用于身份验证的开放标准,它将用户信息编码为 JSON… 2026/7/11 22:45:51
专业治厌学,口碑选左养右学 当孩子进入青春期,一句“我不想去学校了”足以让无数家长陷入焦虑与无助。孩子不喜欢学校氛围、产生厌学情绪,已成为10-18岁年龄段家庭面临的普遍难题。这不仅关乎学业中断,更深层次地涉及孩子的心理健康、亲子关系危机以及未来的发展轨迹。面… 2026/7/12 13:01:40
WindowResizer:解决Windows窗口尺寸问题的终极免费工具 WindowResizer:解决Windows窗口尺寸问题的终极免费工具 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 你是否曾经因为某些应用程序窗口太小而眯着眼睛看屏幕ÿ… 2026/7/15 13:10:09
为什么97%的ChatGPT用户从未激活「逻辑缓存层」?:2024最新架构级表达优化路径曝光,仅限前500名开发者 更多请点击: https://codechina.net 第一章:逻辑缓存层的本质与认知断层 逻辑缓存层并非物理存储的简单代理,而是业务语义与数据访问契约之间的翻译中枢。它承载着状态一致性边界、读写语义抽象、以及领域上下文感知等隐性契约,却… 2026/7/15 13:08:08
为什么科研 Agent 不能只会搜论文,还必须会“追引用” 导语 这两周,Agent 生态讨论得最多的已经不是“能不能接工具”,而是“工具返回的证据能不能复核”。对科研场景来说,找到一篇论文只是入口,真正决定 Agent 是否可靠的,是它能不能继续回到原文、展开参考文献、查看谁引… 2026/7/15 13:06:07
SpringBoot整合MySQL事务,实战用法+异常处理 前言实际开发几乎不用手写 BEGIN/COMMIT,全部使用 Spring 声明式事务。本篇带你从零掌握 SpringBoot 事务实战。一、核心注解Transactional加在方法/类上,自动开启事务、异常自动回滚。二、实战转账代码Service public class AccountService {Autowiredp… 2026/7/15 13:01:41
X(原Twitter)推荐算法架构演进:从特征工程到Grok Transformer的范式转变 1. X推荐算法的演进背景 每天有超过5亿条推文在X平台上发布,而系统需要从中筛选出最相关的1500条推文推送给用户。这个看似简单的数字背后,隐藏着一套复杂的推荐系统。从早期的Twitter到现在的X,推荐算法经历了从传统特征工程到Grok Transfor… 2026/7/15 13:01:41
重新思考Windows系统激活:KMS_VL_ALL_AIO的智能范式转变 重新思考Windows系统激活:KMS_VL_ALL_AIO的智能范式转变 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 在数字化时代,系统激活不再应该是技术门槛,而应是智能… 2026/7/15 12:59:41
行星减速机的工作原理是什么?从齿轮运动关系到减速比计算 一、行星齿轮机构的组成 标准行星齿轮机构主要包括: 太阳轮; 行星轮; 内齿圈; 行星架。 太阳轮位于机构中心。 多个行星轮围绕太阳轮均匀布置,行星轮内侧与太阳轮外啮合,外侧与内齿圈内啮合。 行星轮通过轴… 2026/7/15 0:03:00
阅读Java开源框架源码的心得分享! 前几日闲来无事有幸看到了一位博主分享自己阅读开源框架源码的心得,看了之后也引发了我的一些深度思考。我们为什么要看源码?我们该怎么样去看源码? 其中前者那位博主描述的我觉得很全了(如下图所示),就不做… 2026/7/15 0:03:00
【LINUX】驱动 【LINUX驱动】【字符设备】【中断】【Platform】【网课 设备树】【GPIO】【PINCTRL】【INPUT】【IIC】【SPI】【网络驱动】【屏幕驱动】【一 设备树】【二 内核模块编译】【三 基本驱动框架】【四 Platform总线设备驱动框架】【五 驱动子系统】【六 综合】 2026/7/15 0:07:01
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/13 8:31:55
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/14 18:25:04
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/14 5:09:41