| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- <template>
- <view class="content">
- <view class="inner">
- <view class="bg">
- <image class="w622 h622" src="@/static/image/bg_invitecard.png" mode=""></image>
- <view class="infor">
- <view class="title one-t">康复医学概论</view>
- <view class="name-title">
- <image class="w32 h32 " src="@/static/image/icon_doctor_fill.png" mode=""></image>
- <view class="one-t">王小明 | 消化内科 | 北京人民医院</view>
- </view>
- <view class="time-title">
- <image class="w32 h32 " src="@/static/image/icon_doctor_fill.png" mode=""></image>
- <view class="one-t">2025年12月13日 18:00</view>
- </view>
- </view>
- </view>
-
- <view class="code">
- <image class="w176 h176 " src="@/static/image/icon_doctor_fill.png" mode=""></image>
- <view class="tips">长按识别二维码,观看直播</view>
- </view>
- </view>
- <view class="share-box">
- <view class="weixin" style="margin-right: 176rpx;">
- <image class="w100 h100 " src="@/static/image/icon_share_wechat.png" mode=""></image>
- <text>微信好友</text>
- <button class="share" data-name="shareBtn" open-type="share"></button>
- </view>
- <view class="setimg" @tap="saveInviteCard">
- <image class="w100 h100 " src="@/static/image/icon_share_save.png" mode=""></image>
- <text>保存图片</text>
- </view>
- </view>
- <canvas type="2d" id="inviteCardCanvas" style="width: 622rpx; height: 920rpx; position: fixed; top: -9999rpx; left: -9999rpx;"></canvas>
- </view>
- </template>
- <script>
- import {
- getCompetitorById,saveCompetitor,updateCompetitor
- } from '@/api/companyUser.js'
- export default {
- data() {
- return {
- bgImg: "/static/image/bg_invitecard.png",
- doctorIcon: "/static/image/icon_doctor_fill.png",
- qrCodeImg: "/static/image/icon_doctor_fill.png", // 替换为真实二维码
- wechatIcon: "/static/image/icon_share_wechat.png",
- saveIcon: "/static/image/icon_share_save.png"
-
- };
- },
- onLoad(options) {
- // this.type = option.type;
- // this.form.userId=options.userId
- // this.form.companyUserId=options.companyUserId;
- // console.log(this.type)
- // if (this.type == 'edit') {
- // this.id=option.id;
- // this.getCompetitorInfo();
- // }
- uni.showShareMenu({
- withShareTicket:true,
- //小程序的原生菜单中显示分享按钮,才能够让发送给朋友与分享到朋友圈两个按钮可以点击
- menus:["shareAppMessage"] //不设置默认发送给朋友
- })
- },
- //发送给朋友
- onShareAppMessage(res) {
- // if(this.utils.isLogin()){
- // var user=JSON.parse( uni.getStorageSync('userInfo'))
- // return {
- // title: this.product.productName,
- // path: '/pages/shopping/productDetails?productId='+this.product.productId+"&userId="+user.userId,
- // imageUrl: 'https://user.test.ylrztop.com/images/logo.png' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
- // }
- // }
- },
- methods: {
- // 保存邀请卡图片
- async saveInviteCard() {
- try {
- uni.showLoading({ title: "生成图片中..." });
-
- // 1. 获取canvas上下文(Uniapp兼容写法)
- const query = uni.createSelectorQuery().in(this);
- const canvasRes = await new Promise((resolve) => {
- query.select("#inviteCardCanvas").node().exec((res) => {
- resolve(res[0]);
- });
- });
- if (!canvasRes.node) {
- throw new Error("获取Canvas失败");
- }
- const canvas = canvasRes.node;
- const ctx = canvas.getContext("2d");
-
- // 2. 适配设备像素比,保证图片高清
- const systemInfo = uni.getSystemInfoSync();
- const dpr = systemInfo.pixelRatio || 1;
- canvas.width = 622 * dpr;
- canvas.height = 920 * dpr; // 与canvas样式高度统一
- ctx.scale(dpr, dpr);
-
- // 3. 加载并绘制背景图
- const bgImg = await this.loadImage(this.bgImg,canvas);
- ctx.drawImage(bgImg, 0, 0, 622, 622);
-
- // 4. 绘制文字(标题/医生/时间)
- ctx.font = "bold 32rpx PingFang SC"; // 匹配样式中的字体和大小
- ctx.fillStyle = "#FFFFFF";
- ctx.fillText("康复医学概论", 46, 580); // 调整坐标匹配UI布局
-
- ctx.font = "24rpx PingFang SC";
- ctx.fillText("王小明 | 消化内科 | 北京人民医院", 46, 616);
- ctx.fillText("2025年12月13日 18:00", 46, 652);
-
- // 5. 绘制二维码
- const qrImg = await this.loadImage(this.qrCodeImg,canvas);
- const qrX = (622 - 176) / 2; // 二维码居中
- ctx.drawImage(qrImg, qrX, 622 + 32, 176, 176); // 匹配code区域的padding
-
- // 6. 绘制二维码提示文字
- ctx.font = "24rpx PingFang SC";
- ctx.fillStyle = "#999999";
- const tipsText = "长按识别二维码,观看直播";
- const textWidth = ctx.measureText(tipsText).width;
- const tipsX = (622 - textWidth) / 2;
- ctx.fillText(tipsText, tipsX, 622 + 32 + 176 + 16); // 匹配tips的margin-top
-
- // 7. 导出canvas为临时图片
- const tempFilePath = await new Promise((resolve, reject) => {
- uni.canvasToTempFilePath({
- canvas: canvas,
- x: 0,
- y: 0,
- width: 622,
- height: 920,
- destWidth: 622 * dpr,
- destHeight: 920 * dpr,
- success: (res) => resolve(res.tempFilePath),
- fail: (err) => reject(err)
- }, this);
- });
-
- uni.hideLoading();
-
- // 8. 申请相册权限并保存图片
- try {
- await uni.authorize({ scope: "scope.writePhotosAlbum" });
- } catch (authErr) {
- // 授权失败时引导用户手动开启
- uni.showModal({
- title: "提示",
- content: "需要相册权限才能保存图片,请前往设置开启",
- confirmText: "去设置",
- success: (res) => {
- if (res.confirm) uni.openSetting();
- }
- });
- return;
- }
-
- await uni.saveImageToPhotosAlbum({ filePath: tempFilePath });
- uni.showToast({ title: "图片保存成功", icon: "success" });
-
- } catch (err) {
- uni.hideLoading();
- uni.showToast({ title: "保存失败", icon: "none" });
- console.error("保存图片失败:", err);
- }
- },
- // 优化图片加载方法,适配Uniapp静态资源
- loadImage(src,canvas) {
- return new Promise((resolve, reject) => {
- // 处理@/static路径为绝对路径
- // const realSrc = src.replace("@", "");
- const img = canvas.createImage();
- // 小程序环境下添加跨域标识
- img.crossOrigin = "anonymous";
- img.src = src;
- img.onload = () => resolve(img);
- img.onerror = (err) => reject(err);
- });
- }
- }
- }
- </script>
- <style lang="scss">
- page {
- height: 100%;
- }
- .content {
- height: 100%;
- display: flex;
- flex-direction: column;
- .inner{
- width: 622rpx;
- height: 920rpx;
- margin: 64rpx;
- background: #FFFFFF;
- box-shadow: 0rpx 8rpx 32rpx 0rpx rgba(170,168,168,0.12);
- border-radius: 24rpx 24rpx 24rpx 24rpx;
- .bg{
- position: relative;
- // padding: 32rpx 46rpx;
- .infor{
- width: 100%;
- position: absolute;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- padding-left:46rpx;
- bottom: 24rpx;
-
- .title{
- font-family: PingFang SC, PingFang SC;
- font-weight: 600;
- font-size: 32rpx;
- color: #FFFFFF;
- margin-bottom: 26rpx;
- width: 80%;
- }
- .name-title,.time-title{
- width: 100%;
- display: flex;
- align-items: center;
- font-family: PingFang SC, PingFang SC;
- font-weight: 600;
- font-size: 24rpx;
- color: #FFFFFF;
- line-height: 36rpx;
- margin-bottom: 8rpx;
- image{
- margin-right: 14rpx;
- }
- .one-t{
- width: 80%;
- }
- }
-
- }
-
- }
- }
- .code{
- padding: 32rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
- background: #FFFFFF;
- .tips{
- margin-top: 16rpx;
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 24rpx;
- color: #999999;
- line-height: 36rpx;
- }
- }
- .share-box{
- margin-top: 108rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- .weixin,.setimg{
- display: flex;
- align-items: center;
- flex-direction: column;
- position: relative;
- text{
- margin-top: 18rpx;
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 28rpx;
- color: #666666;
- line-height: 44rpx;
- }
- }
- .share{
- display: inline-block;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
- }
- }
- }
- </style>
|