前端uniapp生成海报并保存相册
uiapp插件
目录
- 图片
- qrcode.vue源码完整版
- 封装源码qrcodeSwiper.vue
- 最后
图片
qrcode.vue源码完整版
<template><view class="qrcode"><div class="qrcode_swiper SourceHanSansSC-Normal"><!-- <cc-scroolCard :dataInfo="datas" :swiperIndex="swiperIndex" @change="swiperChangeClick"></cc-scroolCard> --><!-- // 下面全是引入swiper数据 start!!!!!!! --><view class="swiper-wrap" v-if="imgList.length"><!-- previous-margin="111rpx" next-margin="111rpx" 控制左右间距 --><swiper class="image-container" previous-margin="111rpx" next-margin="111rpx" circular@change="swiperChange"><!-- currentIndex索引默认0 data --><swiper-item :class="currentIndex == index ? 'swiper-item' : 'swiper-item-side'"v-for="(item, index) in imgList" :key="index"><view class="item-content" :class="currentIndex == index ? 'item-img' : 'item-img-side'"><image :src="item.file_path" lazy-load :style="dontFirstAnimation ? 'animation: none;' : ''"mode="aspectFill"></image><!-- 保存图片背景颜色是canvas绘画上去的,而不是css样式,但是css也必须设置颜色,因为要显示 --><image :src="bgwhite" class="bgwhiteImg"><view class="bottom-box flex-center"><!-- 二维码图片 --><image :src="qrcode" class="code"></image><view class="right-inner"><view class="invite-top">我的邀请码</view><view class="invite-center">{{inviteCode}}</view><view class="font-color-46 invite-bottom">长按识别二维码加入中闽天品</view></view></view></image></view></swiper-item></swiper></view><!-- 画布 --><view style="width: 100%;z-index: 500;position: fixed;left: 0;top: -1000vh;"><view style="width: 100%;height: 1624upx;position: relative;background-color: #FFFFFF;"><canvas style="width: 400rpx;height: 710rpx;" canvas-id="myCanvas" ref="myBox"></canvas></view></view><!-- // 上面全是引入swiper数据 end!!!!!!! --></div><!-- 我的邀请码 --><view class="myinvitationcode"><view class="myinvitationcode_lft"><view class="myinvitationcode_lft_top">我的邀请码</view><view class="myinvitationcode_lft_btm">{{invite_code}}</view></view><view class="myinvitationcode_rgt" @tap="copy(invite_code)"><text class="myinvitationcode_rgt_txt">复制</text></view><!-- <view style="width: 100rpx; height: 100rpx; border: 1rpx solid red;" @tap="getSwiper">跳转</view> --></view><!-- 邀请步骤 --><view class="invitationsteps"><view class="invitationsteps_lft"><text class="invitationsteps_lft_one">邀请步骤</text><text class="invitationsteps_lft_two">1.分享邀请海报给好友</text><text class="invitationsteps_lft_two">2.好友通过海报下载APP</text><text class="invitationsteps_lft_two">3.好友注册APP时填写您的邀请码</text></view><view class="invitationsteps_rgt"><image :src="qrcode_url" mode="aspectFill" class="poster_image"></image></view></view><!-- 保存按钮 --><view class="btns-wrap"><!-- 下面这个要 --><!-- <button class="btn-red" type="default" @click="savePosterImg">保存图片</button>--><!-- #ifdef MP || APP-PLUS --><!-- <button class="btn-red" type="default" @click="downLoad">保存图片</button> --><!-- <button type="default" @click="downLoad"><image src="../../../static/poster/posterDownload.png" mode="aspectFill"></image><text>保存图片</text></button> --><view class="wrapBtn" type="default" @click="downLoad"><image src="../../../static/poster/posterDownload.png" mode="aspectFill"></image><text>保存图片到相册</text></view><!-- #endif --><!-- <button class="btn-red" type="default" @click="savePosterImg">保存图片</button> --><!-- H5 不加保存了 下面这个不要 --><!-- #ifdef H5 --><!-- <view class="f34 tc ww100" type="default">长按保存图片</view> --><!-- #endif --></view></view>
</template><script>// import bwSwiper from '@/wxcomponents/bw-swiper/bw-swiper.vue';export default {components: {// bwSwiper},data() {return {qrcode_url: '',// user_id: '',invite_code: '',// 下面全是引入swiper数据 start!!!!!!!// 接口获取swiper图片数组imgList: [],// 本地测试假数据// imgList: [// {// currentIndex: 0,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// },// {// currentIndex: 1,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// },// {// currentIndex: 2,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// },// {// currentIndex: 3,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// },// ],// 轮播图索引index默认选中0,第一个currentIndex: 0,dontFirstAnimation: true,codeTwo: '',inviteCode: '', //邀请码// canvas绘制的图片路径picture: uni.getStorageSync('tempFilePath'),// 接口获取二维码图片qrcode: '', // view上面也要绑定image 绑定src路径bgwhite: '', // swiper底部白色背景图,要绑定image 绑定src路径// 上面全是引入swiper数据 end !!!!!!!}},onShow() {// 下面全是引入swiper数据 start!!!this.getCavasSwiperImgData();// 上面全是引入swiper数据 end!!!},mounted() {/*获取数据1*/this.getData();// this.user_id = uni.getStorageSync('user_id');// 获取我的邀请码this.getMycodeData();},methods: {/*获取数据*/getData() {let self = this;uni.showLoading({title: '加载中',});let source = self.getPlatform();self._get('plus.agent.qrcode/poster', {source: source}, function(data) {uni.hideLoading();self.qrcode_url = data.data.qrcode;});},// 复制按钮https://blog.csdn.net/Zhuangvi/article/details/113089000copy(value) {uni.setClipboardData({data: value + '', // 接受字符串类型 value转化为字符串success: () => {uni.showToast({title: '复制成功',duration: 2000,icon: 'success'});}});},// 获取我的邀请码getMycodeData() {let self = this;uni.showLoading({title: '加载中'});self._post('user.index/detail', {source: self.getPlatform()}, function(res) {//#ifdef MP-WEIXINif (res.data.getPhone) {//#ifdef MP-WEIXINself.gotoPage('/pages/login/bindmobile');//#endif//#ifndef MP-WEIXINself.bindMobile();//#endifreturn;}//#endif// self.detail = res.data.userInfo;// swiper 数据 end !!!!// swiper里面的 邀请码self.inviteCode = res.data.userInfo.invite_code;// swiper 数据 end !!!!// 图片下面的 我的邀请码self.invite_code = res.data.userInfo.invite_code// console.log(res, 'resssself.invite_code');uni.hideLoading();});},// 跳转自己封装的海报swiper组件// getSwiper() {// console.log(111);// uni.navigateTo({// url: '/pages/agent/qrcode/qrcodeSwiper/qrcodeSwiper',// })// },// 下面全是引入swiper数据 start!!!!!// 获取背景图 二维码后 执行 => cavas画布绘画// 必须先获取图片后在 执行 => cavas画布绘画 => 否则空白图片async getCavasSwiperImgData() {let self = this;// uni.showLoading({// title: '加载中',// });let source = self.getPlatform();self._get('plus.agent.qrcode/poster', {source: source},res => {// 必须是es6语法否则报错,如何这个不行就缓存普通函数funtion,报错显示this.setcanvas();未找到uni.hideLoading();if (res.data) {// console.log(res,'111获取swiper数组路径&&&222二维码路径');self.imgList = res.data.poster;self.qrcode = res.data.qrcode;self.bgwhite = res.data.back;// let qrcode_Path = uni.setStorageSync('qrcodePath',res.data.qrcode);// qrcode 二维码路径 放到本地存储防止 data取值为空uni.setStorageSync('qrcodePath', res.data.qrcode);// 获取底部白色背景图uni.setStorageSync('bgwhitePath', res.data.back);// 必须先获取图片二维码文字完后执行 => 后 canvas绘画 this.setcanvas() 这个方法this.setcanvas();}});},// 这里面应该获取数字和二维码 这个是原始案例没用到注释即可 里面有需要兼容编译// async userFission() {// let source = ''// // #ifdef APP-PLUS// source = 'app'// // #endif// // // #ifdef MP-WEIXIN// // source = 'wx'// // // #endif// // #ifdef H5// source = 'h5'// // #endif// this._post('user.user/getMyInvitationInfo', {// category_id: 5,// source: source// }, res => {// if (res.data) {// const {// rtn// } = res.data;// this.codeTwo = rtn.invitation_code_img;// this.inviteCode = rtn.invitation_code;// this.imgList = rtn.supplier_bg;// // 必须先获取图片二维码文字完后执行 => 后 canvas绘画 this.setcanvas() 这个方法// this.setcanvas();// }// });// },/**该方法用来绘制一个有填充色的圆角矩形*@param cxt:canvas的上下文环境 *@param x:左上角x轴坐标 *@param y:左上角y轴坐标 *@param width:矩形的宽度 *@param height:矩形的高度 *@param radius:圆的半径 *@param fillColor:填充颜色 **/fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {//圆的直径必然要小于矩形的宽高 if (2 * radius > width || 2 * radius > height) {return false;}cxt.save();cxt.translate(x, y);//绘制圆角矩形的各个边 this.drawRoundRectPath(cxt, width, height, radius);cxt.fillStyle = fillColor || "#fff"; //若是给定了值就用给定的值否则给予默认值 cxt.fill();cxt.restore();},drawRoundRectPath(cxt, width, height, radius) {cxt.beginPath(0);//从右下角顺时针绘制,弧度从0到1/2PI cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);//矩形下边线 cxt.lineTo(radius, height);//左下角圆弧,弧度从1/2PI到PI cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);//矩形左边线 cxt.lineTo(0, radius);//左上角圆弧,弧度从PI到3/2PI cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);//上边线 cxt.lineTo(width - radius, 0);//右上角圆弧 cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);//右边线 cxt.lineTo(width, height - radius);cxt.closePath();},// 1.获取图片下载下来 通过异步[return new Promise]返回到 绘制返回到下面 // => setcanvas() 里面 =>ctx.drawImage(await this.downloadFiles 的await是等待的意思 return new Promise返回图片绘制downloadFiles(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');return new Promise(function(resolve, reject) {uni.downloadFile({url: url.file_path,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 获取二维码downloadQrcode(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');// console.log(url, '获取二维码图片路径');return new Promise(function(resolve, reject) {uni.downloadFile({url: url,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 这里是绘制async setcanvas() {let bg_img = this.imgList[this.currentIndex];// console.log(bg_img, '滑动的每一个对象');// 获取整个canvas上面viewlet ctx = uni.createCanvasContext('myCanvas');// var ctx = uni.createCanvasContext('myCanvas', this);// 上面报错就用这个// 这个是背景图swiper !!! 获取每个swiper下面item滑动选中的哪一个ctx.drawImage(await this.downloadFiles(bg_img, this), 0, 0, uni.upx2px(400), uni.upx2px(710)); //绘制图 uni.upx2px(750) *// ctx.drawImage(this.codeTwo, uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 注释1// ctx.drawImage(await this.downloadFiles(this.codeTwo, this), uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));// ctx.drawImage(this.qrcode, uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 底部白色背景图1// ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni// .upx2px(350), uni// .upx2px(100));ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni.upx2px(350), uni.upx2px(100));// qrcode 二维码路径 放到本地存储防止 data取值为空let qrcode_Path = uni.getStorageSync('qrcodePath');// 可以二维码// ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(35), uni.upx2px(600), uni.upx2px(82), uni.upx2px(82));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#848484";// ctx.fillText('我的邀请码', uni.upx2px(130), uni.upx2px(606));ctx.fillText('我的邀请码', uni.upx2px(135), uni.upx2px(620));ctx.font = 'normal 10px sans-serif';ctx.fillStyle = "#FF2741";// ctx.fillText(this.inviteCode, uni.upx2px(130), uni.upx2px(640));ctx.fillText(this.inviteCode, uni.upx2px(135), uni.upx2px(648));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#282828";// ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(130), uni.upx2px(670));ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(135), uni.upx2px(675));ctx.draw(false, () => {// console.log('绘制完成')// 注释2// console.error(bg_img)this.getFail();})// // 注释2// console.log(bg_img, 'bg_imgbg_img');},//点击画布宽高设置 图片 getFail(type) {let self = this;uni.canvasToTempFilePath({ // 把画布转化成临时文件1x: 0,y: 0,width: uni.upx2px(400), // 截取的画布的宽height: uni.upx2px(710), // 截取的画布的高destWidth: uni.upx2px(360) * 3, // 保存成的画布宽度destHeight: uni.upx2px(680) * 3, // 保存成的画布高度fileType: 'png', // 保存成的文件类型quality: 1, // 图片质量canvasId: 'myCanvas', // 画布ID success(res) {// 绘画图片路径self.picture = res.tempFilePath;// 绘制最后路径// console.log(res, '绘制完成图片路径');uni.setStorageSync('tempFilePath', res.tempFilePath);self.picture = uni.setStorageSync('tempFilePath', res.tempFilePath);},fail(fail) {uni.showToast({title: '保存失败,稍后再试', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}})},// 点击下载保存相册按钮downLoad() {// console.log(this.imgList[this.currentIndex],'this.imgList[this.currentIndex]');console.log(uni.getStorageSync('tempFilePath'), 'getStorageSync下载按钮未取到路径啊啊');let self = this;// 2-保存图片至相册uni.saveImageToPhotosAlbum({ // 存成图片至手机1// filePath: this.picture,// filePath: pathw,// filePath:'data:image/png;base64,base64'+ uni.getStorageSync('tempFilePath'),filePath: uni.getStorageSync('tempFilePath'), // 未取到路径myPromisesuccess(res2) {uni.hideLoading();uni.showToast({title: '保存成功', //'保存成功'duration: 500})},fail(res3) {console.log(res3, 'res3AAAAAA');if (res3.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {uni.showToast({title: '保存失败,稍后再试1', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();} else {uni.showToast({title: '保存失败,稍后再试2', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}}})},copyCode() {uni.setClipboardData({data: this.inviteCode,success: () => {uni.showToast({title: '复制成功'})}});},swiperChange(e) {this.dontFirstAnimation = falsethis.currentIndex = e.detail.currentthis.setcanvas()// 切换调用图片二维码数据this.getCavasSwiperImgData();},// 上面全是引入swiper数据 end !!!!!}}
</script><style lang="scss" scoped>page {background: #F8F8F8;}.qrcode {width: 100%;// height: 100vh !important;}// 下面全是引入swiper数据 start!!!!!!.qrcode_swiper {margin-top: 71rpx;// height: 500rpx;// border:1rpx solid red;.swiper-wrap {padding-top: 20rpx;}.image-container {width: 750rpx;// height: 939rpx;height: 756rpx;}.item-img {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-big .3s;}// 中间选中.swiper-item {// width: 528rpx;width: 540rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;}.item-img-side {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-mini .3s;// transform: scale(0.85);transform: scale(0.85);// @keyframes to-mini 也要改 在最下面scale(0.85)// 两侧底部有白边超出父元素隐藏overflow: hidden;}// 两边.swiper-item-side {width: 528rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;// transform: scale(0.85);transform: scale(0.85);}.item-content {position: relative;image {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 20rpx;}.bgwhiteImg {margin-left: 20rpx;// border-radius: 20rpx;}.bottom-box {position: absolute;left: 50%;transform: translateX(-50%);bottom: 31rpx;padding: 16rpx 19rpx;background-color: #FFFFFF;width: 492rpx;border-radius: 10rpx;// height: 140rpx;display: flex;box-sizing: border-box;.code {width: 111rpx;height: 108rpx;margin-right: 12rpx;flex-shrink: 0;}.right-inner {height: 80rpx;display: flex;flex-direction: column;justify-content: space-between;.invite-top {font-size: 25rpx;font-family: Microsoft YaHei;font-weight: 400;color: #848484;// line-height: 22rpx;}.invite-center {font-size: 28rpx;font-family: Microsoft YaHei;font-weight: bold;color: #FF2741;// line-height: 1.5;}.invite-bottom {font-size: 25rpx;font-family: Microsoft YaHei;font-weight: bold;color: #282828;// line-height: 1.5;// 强制不换行white-space: nowrap;}}}}@keyframes to-mini {from {transform: scale(1);}to {// transform: scale(0.85);transform: scale(0.85);}}@keyframes to-big {from {// transform: scale(0.85);transform: scale(0.85);}to {transform: scale(1);}}}// 上面全是引入swiper数据 end !!!!!// 我的邀请码.myinvitationcode {// margin-top: 56rpx;width: 700rpx;height: 178rpx;background: #FFFFFF;border-radius: 10rpx;margin: 56rpx auto;display: flex;align-items: center;justify-content: space-between;.myinvitationcode_lft {margin-left: 49rpx;display: flex;flex-direction: column;.myinvitationcode_lft_top {font-size: 26rpx;font-family: Microsoft YaHei;font-weight: 400;color: #727272;line-height: 38rpx;}.myinvitationcode_lft_btm {font-size: 45rpx;font-family: Microsoft YaHei;font-weight: bold;color: #000000;line-height: 1.2;}}.myinvitationcode_rgt {margin-right: 49rpx;width: 168rpx;height: 70rpx;// background: #FF2741;// background: rgb(223, 216, 239);background: #000;// opacity: 0.1;border-radius: 35rpx;display: flex;justify-content: center;align-items: center;.myinvitationcode_rgt_txt {font-size: 32rpx;font-family: Microsoft YaHei;font-weight: 400;// color: FF2741;// color: rgb(223, 51, 93);color: #fff;// line-height: 24rpx;}}}// 邀请步骤.invitationsteps {display: flex;justify-content: space-between;flex-direction: row;align-items: center;.invitationsteps_lft {margin-left: 31rpx;display: flex;flex-direction: column;.invitationsteps_lft_one {font-size: 28rpx;font-family: Microsoft YaHei;font-weight: bold;color: #9F9F9F;line-height: 38rpx;}.invitationsteps_lft_two {font-size: 28rpx;font-family: Microsoft YaHei;font-weight: 400;color: #AFAEAE;line-height: 38rpx;}}.invitationsteps_rgt {margin-right: 53rpx;width: 185rpx;height: 185rpx;}}// .poster_img {// width: 100%;// height: 100vh !important;// position: absolute;// }// .poster_image {// width: 100%;// height: 100vh !important;// }// uni-image {// width: 100%;// height: 100vh !important;// position: absolute;// }// .qrcode_img_box {// width: 100%;// display: flex;// justify-content: center;// .qrcode_img {// width: 80%;// position: relative;// border-radius: 15rpx;// position: fixed;// bottom: 150rpx;// z-index: 999;// background-color: #fff;// // width: 100rpx !important;// // height: 100rpx !important;// display: flex;// padding: 20rpx;// // margin: 20rpx;// .qrcode_img_left {// width: 150rpx;// height: 150rpx;// }// .qrcode_img_right {// display: flex;// flex-direction: column;// justify-content: space-around;// margin-left: 20rpx;// .qrcode_img_right_top {// color: #ccc;// font-size: 30rpx// }// .qrcode_img_right_center {// color: rgb(223, 70, 109);// font-size: 30rpx;// font-weight: 800;// }// .qrcode_img_right_tbtm {// color: #000;// font-size: 30rpx;// }// }// }// }.btns-wrap {position: fixed;height: 88rpx;right: 0;bottom: 35rpx;left: 0;display: flex;z-index: 10;}// button样式// .btns-wrap button {// width: 700rpx;// height: 94rpx;// background: linear-gradient(90deg, #FF2C43, #FC5B5A);// border-radius: 10rpx;// margin: 0 auto;// display: flex;// justify-content: center;// align-items: center;// }// .btns-wrap button image{// width: 33rpx;// height: 33rpx;// }// .btns-wrap button text {// font-size: 28rpx;// font-family: Microsoft YaHei;// font-weight: 400;// color: #FFFFFF;// line-height: 88rpx;// }.wrapBtn {width: 700rpx;height: 94rpx;background: linear-gradient(90deg, #FF2C43, #FC5B5A);border-radius: 10rpx;margin: 0 auto;display: flex;justify-content: center;align-items: center;}.wrapBtn image {width: 35rpx;height: 35rpx;}.wrapBtn text {font-size: 35rpx;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;line-height: 27rpx;// margin-left: 13rpx;margin-left: 10rpx;}.btns-wrap .btn-red {width: 100%;height: 88rpx;line-height: 88rpx;border-radius: 0;}
</style>
封装源码qrcodeSwiper.vue
<template><view class="page-view SourceHanSansSC-Normal"><!-- <base-head title="邀请好友"></base-head><bg-img :combg="true"></bg-img> --><view class="swiper-wrap" v-if="imgList.length"><!-- previous-margin="111rpx" next-margin="111rpx" 控制左右间距 --><swiper class="image-container" previous-margin="111rpx" next-margin="111rpx" circular@change="swiperChange"><!-- currentIndex索引默认0 data --><swiper-item :class="currentIndex == index ? 'swiper-item' : 'swiper-item-side'"v-for="(item, index) in imgList" :key="index"><view class="item-content" :class="currentIndex == index ? 'item-img' : 'item-img-side'"><image :src="item.file_path" lazy-load :style="dontFirstAnimation ? 'animation: none;' : ''"mode="aspectFill"></image><!-- 保存图片背景颜色是canvas绘画上去的,而不是css样式,但是css也必须设置颜色,因为要显示 --><image :src="bgwhite" class="bgwhiteImg"><view class="bottom-box flex-center"><!-- 二维码图片 --><image :src="qrcode" class="code"></image><view class="right-inner"><view class="invite-top">我的邀请码</view><view class="invite-center">{{inviteCode}}</view><view class="font-color-46 invite-bottom">长按识别二维码加入中闽天品</view></view></view></image></view></swiper-item></swiper></view><view class="section-wrap"><view class="group-three-wrap flex-item-center" v-if="imgList.length"><view class="flex-item-center btn" @tap="downLoad"><!-- <image src="https://app.moai.pro/static/moai/xiazai.png"></image> --><text class="font-color-fff">保存到手机</text></view></view></view><!-- 画布 --><view style="width: 100%;z-index: 500;position: fixed;left: 0;top: -1000vh;"><view style="width: 100%;height: 1624upx;position: relative;background-color: #FFFFFF;"><canvas style="width: 400rpx;height: 710rpx;" canvas-id="myCanvas" ref="myBox"></canvas></view></view></view>
</template><script>export default {data() {return {// 接口获取swiper图片数组imgList: [],// 本地测试假数据// imgList: [// {// currentIndex: 0,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// },// {// currentIndex: 1,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// },// {// currentIndex: 2,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// },// {// currentIndex: 3,// file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// },// ],// 轮播图索引index默认选中0,第一个currentIndex: 0,dontFirstAnimation: true,codeTwo: '',inviteCode: '', //邀请码// canvas绘制的图片路径picture: uni.getStorageSync('tempFilePath'),// 接口获取二维码图片qrcode: '', // view上面也要绑定image 绑定src路径bgwhite: '', // swiper底部白色背景图,要绑定image 绑定src路径}},onShow() {this.getCavasSwiperImgData();// this.userFission();// 之前是注释状态},onLoad() {// console.log(this.imgList,'swiper路径');// console.log(this.qrcode,'二维码路径');this.getMycodeData();},methods: {// 获取背景图 二维码后 执行 => cavas画布绘画 // 必须先获取图片后在 执行 => cavas画布绘画 => 否则空白图片async getCavasSwiperImgData() {let self = this;uni.showLoading({title: '加载中',});let source = self.getPlatform();self._get('plus.agent.qrcode/poster', {source: source},res => {// 必须是es6语法否则报错,如何这个不行就缓存普通函数funtion,报错显示this.setcanvas();未找到uni.hideLoading();if (res.data) {// console.log(res,'111获取swiper数组路径&&&222二维码路径');self.imgList = res.data.poster;self.qrcode = res.data.qrcode;self.bgwhite = res.data.back;// let qrcode_Path = uni.setStorageSync('qrcodePath',res.data.qrcode);// qrcode 二维码路径 放到本地存储防止 data取值为空uni.setStorageSync('qrcodePath', res.data.qrcode);// 获取底部白色背景图uni.setStorageSync('bgwhitePath', res.data.back);// 必须先获取图片二维码文字完后执行 => 后 canvas绘画 this.setcanvas() 这个方法this.setcanvas();}});},// 这里面应该获取数字和二维码 这个是原始案例没用到注释即可// async userFission() {// let source = ''// // #ifdef APP-PLUS// source = 'app'// // #endif// // // #ifdef MP-WEIXIN// // source = 'wx'// // // #endif// // #ifdef H5// source = 'h5'// // #endif// this._post('user.user/getMyInvitationInfo', {// category_id: 5,// source: source// }, res => {// if (res.data) {// const {// rtn// } = res.data;// this.codeTwo = rtn.invitation_code_img;// this.inviteCode = rtn.invitation_code;// this.imgList = rtn.supplier_bg;// // 必须先获取图片二维码文字完后执行 => 后 canvas绘画 this.setcanvas() 这个方法// this.setcanvas();// }// });// },/**该方法用来绘制一个有填充色的圆角矩形*@param cxt:canvas的上下文环境 *@param x:左上角x轴坐标 *@param y:左上角y轴坐标 *@param width:矩形的宽度 *@param height:矩形的高度 *@param radius:圆的半径 *@param fillColor:填充颜色 **/fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {//圆的直径必然要小于矩形的宽高 if (2 * radius > width || 2 * radius > height) {return false;}cxt.save();cxt.translate(x, y);//绘制圆角矩形的各个边 this.drawRoundRectPath(cxt, width, height, radius);cxt.fillStyle = fillColor || "#fff"; //若是给定了值就用给定的值否则给予默认值 cxt.fill();cxt.restore();},drawRoundRectPath(cxt, width, height, radius) {cxt.beginPath(0);//从右下角顺时针绘制,弧度从0到1/2PI cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);//矩形下边线 cxt.lineTo(radius, height);//左下角圆弧,弧度从1/2PI到PI cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);//矩形左边线 cxt.lineTo(0, radius);//左上角圆弧,弧度从PI到3/2PI cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);//上边线 cxt.lineTo(width - radius, 0);//右上角圆弧 cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);//右边线 cxt.lineTo(width, height - radius);cxt.closePath();},// 1.获取图片下载下来 通过异步[return new Promise]返回到 绘制返回到下面 // => setcanvas() 里面 =>ctx.drawImage(await this.downloadFiles 的await是等待的意思 return new Promise返回图片绘制downloadFiles(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');return new Promise(function(resolve, reject) {uni.downloadFile({url: url.file_path,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 获取二维码downloadQrcode(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');console.log(url, '获取二维码图片路径');return new Promise(function(resolve, reject) {uni.downloadFile({url: url,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 这里是绘制async setcanvas() {let bg_img = this.imgList[this.currentIndex];// console.log(bg_img, '滑动的每一个对象');// 获取整个canvas上面viewlet ctx = uni.createCanvasContext('myCanvas');// var ctx = uni.createCanvasContext('myCanvas', this);// 上面报错就用这个// 这个是背景图swiper !!! 获取每个swiper下面item滑动选中的哪一个ctx.drawImage(await this.downloadFiles(bg_img, this), 0, 0, uni.upx2px(400), uni.upx2px(710)); //绘制图 uni.upx2px(750) *// ctx.drawImage(this.codeTwo, uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 注释1// ctx.drawImage(await this.downloadFiles(this.codeTwo, this), uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));// ctx.drawImage(this.qrcode, uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 底部白色背景图1// ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni// .upx2px(350), uni// .upx2px(100));ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni.upx2px(350), uni.upx2px(100));// qrcode 二维码路径 放到本地存储防止 data取值为空let qrcode_Path = uni.getStorageSync('qrcodePath');// 可以二维码// ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(28), uni.upx2px(590), uni// .upx2px(82), uni.upx2px(82));ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(35), uni.upx2px(600), uni.upx2px(82), uni.upx2px(82));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#848484";// ctx.fillText('我的邀请码', uni.upx2px(130), uni.upx2px(606));ctx.fillText('我的邀请码', uni.upx2px(135), uni.upx2px(620));ctx.font = 'normal 10px sans-serif';ctx.fillStyle = "#FF2741";// ctx.fillText(this.inviteCode, uni.upx2px(130), uni.upx2px(640));ctx.fillText(this.inviteCode, uni.upx2px(135), uni.upx2px(648));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#282828";// ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(130), uni.upx2px(670));ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(135), uni.upx2px(675));ctx.draw(false, () => {console.log('绘制完成')// 注释2// console.error(bg_img)this.getFail();})// // 注释2// console.log(bg_img, 'bg_imgbg_img');},//点击画布宽高设置 图片 getFail(type) {let self = this;uni.canvasToTempFilePath({ // 把画布转化成临时文件1x: 0,y: 0,width: uni.upx2px(400), // 截取的画布的宽height: uni.upx2px(710), // 截取的画布的高destWidth: uni.upx2px(400) * 3, // 保存成的画布宽度destHeight: uni.upx2px(710) * 3, // 保存成的画布高度fileType: 'jpg', // 保存成的文件类型quality: 1, // 图片质量canvasId: 'myCanvas', // 画布ID success(res) {// 绘画图片路径self.picture = res.tempFilePath;// 绘制最后路径console.log(res, '绘制完成图片路径');uni.setStorageSync('tempFilePath', res.tempFilePath);self.picture = uni.setStorageSync('tempFilePath', res.tempFilePath);},fail(fail) {uni.showToast({title: '保存失败,稍后再试', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}})},// 点击下载保存相册按钮downLoad() {// console.log(this.imgList[this.currentIndex],'this.imgList[this.currentIndex]');console.log(uni.getStorageSync('tempFilePath'), 'getStorageSync下载按钮未取到路径啊啊');let self = this;// 2-保存图片至相册uni.saveImageToPhotosAlbum({ // 存成图片至手机1// filePath: this.picture,// filePath: pathw,// filePath:'data:image/png;base64,base64'+ uni.getStorageSync('tempFilePath'),filePath: uni.getStorageSync('tempFilePath'), // 未取到路径myPromisesuccess(res2) {uni.hideLoading();uni.showToast({title: '保存成功', //'保存成功'duration: 2000})},fail(res3) {console.log(res3, 'res3AAAAAA');if (res3.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {uni.showToast({title: '保存失败,稍后再试1', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();} else {uni.showToast({title: '保存失败,稍后再试2', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}}})},copyCode() {uni.setClipboardData({data: this.inviteCode,success: () => {uni.showToast({title: '复制成功'})}});},swiperChange(e) {this.dontFirstAnimation = falsethis.currentIndex = e.detail.currentthis.setcanvas()// 切换调用图片二维码数据this.getCavasSwiperImgData();},// 获取我的邀请码getMycodeData() {let self = this;uni.showLoading({title: '加载中'});self._post('user.index/detail', {source: self.getPlatform()}, function(res) {//#ifdef MP-WEIXINif (res.data.getPhone) {//#ifdef MP-WEIXINself.gotoPage('/pages/login/bindmobile');//#endif//#ifndef MP-WEIXINself.bindMobile();//#endifreturn;}//#endif// self.detail = res.data.userInfo;// invite_codeself.inviteCode = res.data.userInfo.invite_code// console.log(self.detail, 'detail');console.log(res, 'resss');uni.hideLoading();});},}}
</script><style lang="scss">page {background: #FFFFFF;}.page-view {}.section-wrap {padding: 111rpx 25rpx 44rpx;.group-three-wrap {display: flex;justify-content: center;.btn {width: 600rpx;height: 88rpx;background: #FFA615;border-radius: 44rpx;display: flex;align-items: center;justify-content: center;color: #FFFFFF;font-size: 28rpx;image {width: 26rpx;height: 26rpx;margin-right: 12rpx;}}}}.swiper-wrap {padding-top: 20rpx;}.image-container {width: 750rpx;// height: 939rpx;height: 756rpx;}.item-img {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-big .3s;}// 中间选中.swiper-item {// width: 528rpx;width: 540rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;}.item-img-side {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-mini .3s;// transform: scale(0.85);transform: scale(0.85);// @keyframes to-mini 也要改 在最下面scale(0.85)// swiper图两侧底部有白边超出父元素隐藏overflow:hidden;}// 两边.swiper-item-side {width: 528rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;// transform: scale(0.85);transform: scale(0.85);}.item-content {position: relative;image {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 20rpx;}.bgwhiteImg {margin-left: 20rpx;// border-radius: 20rpx;}.bottom-box {position: absolute;left: 50%;transform: translateX(-50%);bottom: 31rpx;padding: 16rpx 19rpx;background-color: #FFFFFF;width: 492rpx;border-radius: 10rpx;// height: 140rpx;display: flex;box-sizing: border-box;.code {width: 111rpx;height: 108rpx;margin-right: 12rpx;flex-shrink: 0;}.right-inner {height: 80rpx;display: flex;flex-direction: column;justify-content: space-between;.invite-top {font-size: 15rpx;font-family: Microsoft YaHei;font-weight: 400;color: #848484;line-height: 22rpx;}.invite-center {font-size: 21rpx;font-family: Microsoft YaHei;font-weight: bold;color: #FF2741;// line-height: 32rpx;line-height: 2.5;}.invite-bottom {font-size: 16rpx;font-family: Microsoft YaHei;font-weight: bold;color: #282828;// line-height: 22rpx;line-height: 1.5;// 强制不换行white-space: nowrap;}}}}@keyframes to-mini {from {transform: scale(1);}to {// transform: scale(0.85);transform: scale(0.85);}}@keyframes to-big {from {// transform: scale(0.85);transform: scale(0.85);}to {transform: scale(1);}}
</style>
最后
感觉文章好的话记得点个心心和关注和收藏,有错的地方麻烦指正一下,如果需要转载,请标明出处,多谢!!!
相关文章:

前端uniapp生成海报并保存相册
uiapp插件 目录 图片qrcode.vue源码完整版封装源码qrcodeSwiper.vue最后 图片 qrcode.vue源码完整版 <template><view class"qrcode"><div class"qrcode_swiper SourceHanSansSC-Normal"><!-- <cc-scroolCard :dataInfo"dat…...

0基础学习VR全景平台篇 第104篇:720全景后期软件安装
上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 摄影进入数码时代,后期软件继承“暗房工艺”,成为摄影师表达内在情感的必备工具。 首先说明,全景摄影与平面摄影的一个显著的区别是全景图片需…...
CMakeLists编译前拷贝文件或目录
${CMAKE_CURRENT_BINARY_DIR} 编译工程目录 file(COPY python/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/python/ FILES_MATCHING PATTERN "*.exe") file(COPY python/Lib DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/python/) file(COPY python/Libs DESTINATION $…...

mysql面试题35:MySQL有关权限的表有哪些?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL有关权限的表有哪些? MySQL中与权限相关的表主要包括以下几个: user表:存储MySQL用户的基本信息,包括用户名、密码等。可以使用以下命令…...
ES6:什么是Symbol_
引言 在编程领域,我们经常听到关于"Symbol"的术语,但你知道它到底是什么吗?Symbol是一种基本数据类型,它在JavaScript中被引入,用于表示唯一的标识符。本文将介绍Symbol的概念、用途以及如何在代码中使用它…...

E. Li Hua and Array
Problem - E - Codeforces 思路:观察给定的函数,其实就是求与这个数互质的数的个数,即欧拉函数,我们发现一个数迭代欧拉函数不会很多,那么对于第一个操作来说我们可以直接暴力修改,而对于第二个操作来说&am…...

【项目】在线oj
1. 创建项目 创建maven项目。 引入依赖(mysql connector和servlet): <dependencies><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><ar…...

第十章-输入输出系统
Ⅰ.锁 本质是互斥操作 原因:针对公共资源访问时,临界区若不加以互斥限制,可能导致执行过程中突然的中断导致出现异常。 1.互斥过程 设定互斥量M为二值信号量,0/1,P-,V,现有两个进程A、B共同…...

TensorFlow学习:使用官方模型进行图像分类、使用自己的数据对模型进行微调
前言 上一篇文章 TensorFlow案例学习:对服装图像进行分类 中我们跟随官方文档学习了如何进行预处理数据、构建模型、训练模型等。但是对于像我这样的业余玩家来说训练一个模型是非常困难的。所以为什么我们不站在巨人的肩膀上,使用已经训练好了的成熟模…...

Matlab地理信息绘图—研究区域绘制
文章目录 m_map工具箱Matlab绘制研究区域结果显示 m_map工具箱 m_map是 MATLAB 中用于制作地图和地理数据可视化的工具包。这个工具包提供了一组函数和工具,使得用户能够在 MATLAB 中轻松创建地图,并在地图上显示各种地理和气象数据。以下是 m_map 工具包…...

[CSAWQual 2019]Web_Unagi - 文件上传+XXE注入(XML编码绕过)
[CSAWQual 2019]Web_Unagi 1 解题流程1.1 分析1.2 解题 2 思考总结 1 解题流程 这篇博客讲了xml进行编码转换绕过的原理:https://www.shawroot.cc/156.html 1.1 分析 页面可以上传,上传一句话php失败,点击示例发现是xml格式,那…...

ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的问题解决
winR打开窗口输入 services.msc 停止mysql 找到data文件,清空其中全部文件。没有data文件,手动创建 输入 mysqld --remove mysql 移除服务; 注册服务,mysqld -install; 并开始初始化,mysqld --initi…...
什么是函数库和动态链接库?
函数库和动态链接库(也称为共享库)是在软件开发中常见的两种代码重用技术,它们有助于组织、共享和管理代码。在本文中,我们将详细解释函数库和动态链接库的概念、用途以及它们的工作原理。 ## 什么是函数库? 函数库是…...
POM配置
dependencies 所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承 dependencyManagement 只是声明依赖,并不会自动引入,因此子项目需要显示声明依赖。在子项目中声明了依赖项,且没有指定具体版本&#x…...

微电网单台并网逆变器PQ控制matlab仿真模型
微❤关注“电气仔推送”获得资料(专享优惠) 微电网运行在并网模式下且公共电网供应正常时,因为公共电网给定了电 压和频率的参考值,所有的逆变器可以使用PQ控制方式。 当系统频率为额定频率f0时,系统稳定在A点&#x…...

计算机毕业设计选什么题目好?springboot 旅游网站
✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…...

Android Fragment中使用Arouter跳转到Activity后返回Fragment不回调onActivityResult
Fragment中通过路由跳转到Activity 跳转传递参数 通过Arouter跳转 Postcard postcard ARouter.getInstance().build(RouterConstant.ACTION_TRANSMANAGERACTIVITY1);Bundle bundle new Bundle();bundle.putInt("code", 404);postcard.with(bundle); //设置bundlef…...

hive add columns 后查询不到新字段数据的问题
分区表add columns 查询不到新增字段数据的问题; 5.1元数据管理 (1)基本架构 Hive的2个重要组件:hiveService2 和metastore,一个负责转成MR进行执行,一个负责元数据服务管理 beeline-->hiveService2/spar…...

【linux】权限相关问题
【linux】权限相关问题 一.用户的分类sudo 二.文件执行的权限i. 文件的分类ii.人的分类三.修改创建文件的权限chmod更改文件创造的默认权限(umask) 三.删除(粘滞位) 一.用户的分类 在我们使用linux的时候,有用户类型的区分,不同用…...

“.NET视频总结:认识框架的结构和组件,掌握开发工具的奥妙“一
目录 第一单元:二十一世纪程序执行 背景: 总结: 第二单元:对象导向与类别设计 背景: 总结: 第三单元:使用类别与基底类别库 总结: 第四单元:Windows开发程序 背景: 总结: 第五单元:防护式程序设计 背景: 总结: 第六…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...