shareQrCode.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <template>
  2. <view class="container">
  3. <view class="" style="height: 80rpx;">
  4. </view>
  5. <canvas :style="{ width: canvasW + 'px', height: canvasH + 'px',}" canvas-id="myCanvas" id="myCanvas" class="hb"></canvas>
  6. <!-- #ifndef MP -->
  7. <div class="preserve">
  8. <div class="line"></div>
  9. <div class="tip">长按保存图片</div>
  10. <div class="line"></div>
  11. </div>
  12. <!-- #endif -->
  13. <!-- #ifdef MP -->
  14. <view class='keep' @click='saveShareQrcode' v-if="!loading">保存海报</view>
  15. <!-- #endif -->
  16. </view>
  17. </template>
  18. <script>
  19. import {
  20. spreadBanner,
  21. getWxmpInviteQrcode
  22. } from '@/api/user.js';
  23. import {
  24. qrcode
  25. } from '@/api/user.js';
  26. import {
  27. mapState
  28. } from 'vuex';
  29. export default {
  30. // #ifdef MP
  31. onShareAppMessage: function(res) {
  32. // if (res.from === 'button') {
  33. // 保存邀请人
  34. let path = '/pages/index/index?' + 'spread=' + this.userInfo.uid;
  35. console.log('path', path)
  36. let data = {
  37. path: path,
  38. imageUrl: this.poster,
  39. title: this.userInfo.nickname + '邀请您进入母婴界严选'
  40. };
  41. console.log('---data---', data)
  42. return data;
  43. // }
  44. },
  45. // #endif
  46. data() {
  47. return {
  48. bl: 0.95,//画布比例
  49. canvasW: '',
  50. canvasH: '',
  51. bgimg: '',
  52. qrimg: '',
  53. shareList: [],
  54. swiperIndex: 0,
  55. poster: '', // 当前海报
  56. loading: true
  57. }
  58. },
  59. onLoad(option) {
  60. // console.log('---option---',option)
  61. // let path = '/pages/index/index?' + 'spread=' + this.userInfo.uid;
  62. // console.log('path',path)
  63. // if(option.scene){
  64. // // 存储邀请人
  65. // this.spread = opt.pid;
  66. // uni.setStorageSync('spread', opt.pid);
  67. // }
  68. this.loadData();
  69. },
  70. computed: {
  71. ...mapState(['userInfo']),
  72. },
  73. methods: {
  74. bindchange(e) {
  75. let shareList = this.shareList;
  76. this.swiperIndex = e.detail.current;
  77. // #ifdef MP
  78. this.poster = shareList[this.swiperIndex].poster;
  79. // #endif
  80. // // #ifndef MP
  81. // this.poster = shareList[this.swiperIndex].wap_poster;
  82. // // #endif
  83. console.log(this.poster)
  84. },
  85. // 保存海报
  86. savePosterPath: function() {
  87. let that = this;
  88. if (that.poster == '') {
  89. // that.poster = that.shareList[0].poster;
  90. that.poster = this.bgimg
  91. }
  92. uni.downloadFile({
  93. url: that.poster,
  94. success(resFile) {
  95. if (resFile.statusCode === 200) {
  96. uni.getSetting({
  97. success(res) {
  98. if (!res.authSetting['scope.writePhotosAlbum']) {
  99. uni.authorize({
  100. scope: 'scope.writePhotosAlbum',
  101. success() {
  102. uni.saveImageToPhotosAlbum({
  103. filePath: resFile.tempFilePath,
  104. success: function(res) {
  105. return that.$api.msg(
  106. '保存成功');
  107. },
  108. fail: function(res) {
  109. return that.$api.msg(res
  110. .errMsg);
  111. },
  112. complete: function(res) {},
  113. })
  114. },
  115. fail() {
  116. uni.showModal({
  117. title: '您已拒绝获取相册权限',
  118. content: '是否进入权限管理,调整授权?',
  119. success(res) {
  120. if (res.confirm) {
  121. uni.openSetting({
  122. success: function(
  123. res) {
  124. console
  125. .log(
  126. res
  127. .authSetting
  128. )
  129. }
  130. });
  131. } else if (res.cancel) {
  132. return that.$api.msg(
  133. '已取消!');
  134. }
  135. }
  136. })
  137. }
  138. })
  139. } else {
  140. uni.saveImageToPhotosAlbum({
  141. filePath: resFile.tempFilePath,
  142. success: function(res) {
  143. return that.$api.msg('保存成功');
  144. },
  145. fail: function(res) {
  146. return that.$api.msg(res.errMsg);
  147. },
  148. complete: function(res) {},
  149. })
  150. }
  151. },
  152. fail(res) {
  153. }
  154. })
  155. } else {
  156. return that.$api.msg(resFile.errMsg);
  157. }
  158. },
  159. fail(res) {
  160. return that.$api.msg(res.errMsg);
  161. }
  162. })
  163. },
  164. // #ifdef MP-WEIXIN
  165. // 保存画图图片到本地
  166. seav(url) {
  167. uni.showLoading({
  168. title: '生成中...',
  169. mask: true
  170. });
  171. uni.saveImageToPhotosAlbum({
  172. filePath: this.poster,
  173. complete(result) {
  174. uni.hideLoading();
  175. console.log(result);
  176. uni.showToast({
  177. title: '保存图片成功!',
  178. duration: 2000,
  179. icon: 'none'
  180. });
  181. }
  182. });
  183. },
  184. // #endif
  185. // 获取海报
  186. loadData() {
  187. let obj = this;
  188. uni.showLoading({
  189. title: '获取中',
  190. mask: true,
  191. });
  192. // spreadBanner({
  193. // // #ifdef H5
  194. // type: 2,
  195. // // #endif
  196. // // #ifdef MP
  197. // type: 1
  198. // // #endif
  199. // }).then(res =>{
  200. // uni.hideLoading();
  201. // obj.shareList = res.data;
  202. // console.log('obj.shareList',obj.shareList);
  203. // }).catch(err => {
  204. // uni.hideLoading();
  205. // });
  206. getWxmpInviteQrcode().then(res => {
  207. console.log(res)
  208. obj.bgimg = res.data.bgimg
  209. obj.qrcode = res.data.qrcode
  210. uni.hideLoading();
  211. obj.createPoster()
  212. })
  213. },
  214. async createPoster() {
  215. let that = this
  216. // 获取设备信息,主要获取宽度,赋值给canvasW 也就是宽度:100%
  217. this.SystemInfo = await this.getSystemInfo();
  218. // 获取商品主图,二维码信息,APP端会返回图片的本地路径(H5端只能返回原路径)
  219. this.goodsImg = await this.getImageInfo(that.bgimg);
  220. this.ewmImg = await this.getImageInfo(that.qrcode);
  221. this.canvasW = this.SystemInfo.windowWidth * that.bl; // 画布宽度
  222. this.ratio = this.SystemInfo.windowWidth / 750;
  223. let x = 750*this.goodsImg.height/this.goodsImg.width
  224. // this.canvasW =750 * this.ratio;
  225. this.canvasH = x * this.ratio * that.bl;
  226. this.ewmW = 220 * this.ratio;
  227. console.log(this.canvasH, 'this.canvasH')
  228. // this.canvasH = this.goodsImg.height + this.ewmW + 200; // 画布高度 = 主图高度+二维码高度 + 文字图片的间距(大概50)
  229. // 如果主图,二维码图片,设备信息都获取成功,开始绘制海报,这里需要用setTimeout延时绘制,否则可能会出现图片不显示。
  230. if (this.goodsImg.errMsg == 'getImageInfo:ok' && this.ewmImg.errMsg == 'getImageInfo:ok' && this
  231. .SystemInfo.errMsg == 'getSystemInfo:ok') {
  232. console.log('ok')
  233. uni.showToast({
  234. icon: 'loading',
  235. mask: true,
  236. duration: 10000,
  237. title: '海报绘制中',
  238. });
  239. setTimeout(() => {
  240. var ctx = uni.createCanvasContext('myCanvas', this);
  241. // 填充背景色,白色
  242. ctx.setFillStyle('#fff'); // 默认白色
  243. ctx.fillRect(0, 0, this.canvasW, this.canvasH) // fillRect(x,y,宽度,高度)
  244. // 绘制商品主图,二维码
  245. ctx.drawImage(this.goodsImg.path, 0, 0, this.canvasW, this
  246. .canvasH) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
  247. ctx.drawImage(this.ewmImg.path, (this.canvasW / 2 - this.ewmW / 2),this.canvasH - 85*this.ratio - this.ewmW,
  248. this.ewmW, this.ewmW) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度,二维码的宽,高)
  249. // 3、绘制商品标题,多余文字自动换行
  250. ctx.setFontSize(16); // setFontSize() 设置字体字号
  251. ctx.setFillStyle('#333'); // setFillStyle() 设置字体颜色
  252. ctx.draw(false, (ret) => { // draw方法 把以上内容画到 canvas 中。
  253. console.log(ret)
  254. uni.showToast({
  255. icon: 'none',
  256. title: '生成成功!',
  257. });
  258. that.loading = false
  259. that.fina = true
  260. uni.canvasToTempFilePath({ // 保存canvas为图片
  261. canvasId: 'myCanvas',
  262. quality: 1,
  263. fileType: 'jpg',
  264. complete: function(res) {
  265. // 在H5平台下,tempFilePath 为 base64, // 图片提示跨域 H5保存base64失败,APP端正常输出临时路径
  266. console.log(res)
  267. that.canvasShow = false
  268. that.shareQrcodeUrl = res.tempFilePath
  269. that.$forceUpdate()
  270. setTimeout(function() {
  271. console.log(that.shareQrcodeUrl, that
  272. .canvasShow)
  273. }, 2000)
  274. },
  275. })
  276. });
  277. }, 1500)
  278. } else {
  279. console.log('err')
  280. }
  281. },
  282. // 获取设备信息
  283. getSystemInfo() {
  284. return new Promise((req, rej) => {
  285. uni.getSystemInfo({
  286. success: function(res) {
  287. req(res)
  288. }
  289. });
  290. })
  291. },
  292. // 获取图片信息
  293. getImageInfo(image) {
  294. return new Promise((req, rej) => {
  295. uni.getImageInfo({
  296. src: image,
  297. success: function(res) {
  298. req(res)
  299. },
  300. });
  301. })
  302. },
  303. //保存图片
  304. saveShareQrcode() {
  305. console.log(this.shareQrcodeUrl)
  306. uni.saveImageToPhotosAlbum({
  307. filePath: this.shareQrcodeUrl,
  308. success: (res) => {
  309. uni.showToast({
  310. icon: 'none',
  311. position: 'bottom',
  312. title: "成功保存到相册",
  313. });
  314. },
  315. fail: (err) => {
  316. //重新提示用户打开保存图片的授权
  317. if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
  318. uni.showModal({
  319. title: '提示',
  320. content: '需要您授权保存相册',
  321. showCancel: false,
  322. success(res) {
  323. if (res.confirm) {
  324. uni.openSetting({
  325. success(settingdata) {
  326. if (settingdata.authSetting[
  327. 'scope.writePhotosAlbum']) {
  328. uni.showModal({
  329. title: '提示',
  330. content: '获取权限成功,再次保存图片即可成功',
  331. showCancel: false,
  332. })
  333. } else {
  334. uni.showModal({
  335. title: '提示',
  336. content: '获取权限失败,无法保存到相册',
  337. showCancel: false
  338. })
  339. }
  340. }
  341. })
  342. }
  343. }
  344. })
  345. }
  346. },
  347. })
  348. }
  349. }
  350. }
  351. </script>
  352. <style lang="scss">
  353. page {
  354. background: #a3a3a3;
  355. height: 100%;
  356. }
  357. .container {
  358. width: 100%;
  359. padding-bottom: 100rpx;
  360. .posters-box {
  361. width: 100%;
  362. height: 1000rpx;
  363. margin-top: 40rpx;
  364. .slide-image {
  365. width: 100%;
  366. height: 100%;
  367. border-radius: 15rpx;
  368. }
  369. }
  370. .posters-box .slide-image.active {
  371. transform: none;
  372. transition: all 0.2s ease-in 0s;
  373. }
  374. .posters-box .slide-image.quiet {
  375. transform: scale(0.8333333);
  376. transition: all 0.2s ease-in 0s;
  377. }
  378. .keep {
  379. font-size: 30rpx;
  380. background: $base-color;
  381. color: #fff;
  382. width: 750rpx;
  383. position: fixed;
  384. height: 100rpx;
  385. text-align: center;
  386. line-height: 100rpx;
  387. bottom: 0;
  388. left: 0;
  389. }
  390. }
  391. .preserve {
  392. color: #fff;
  393. text-align: center;
  394. margin-top: 38rpx;
  395. display: flex;
  396. align-items: center;
  397. justify-content: center;
  398. .line {
  399. width: 100rpx;
  400. height: 1px;
  401. background-color: #fff;
  402. }
  403. .tip {
  404. margin: 0 20rpx;
  405. font-size: 28rpx;
  406. }
  407. }
  408. .hb {
  409. margin: auto;
  410. border-radius: 20rpx;
  411. overflow: hidden;
  412. }
  413. </style>