多租户商城-商户小程序端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

475 lines
15 KiB

2 years ago
  1. <template>
  2. <view class="invitePoster-box">
  3. <gloable-loading />
  4. <view class="poster-box flex-items-plus flex-column">
  5. <image
  6. class="header-img mar-top-10"
  7. :src="data.headImage"
  8. ></image>
  9. <label class="mar-top-30">发现一件好物快来和我一起拼</label>
  10. <image
  11. class="poster-img mar-top-50"
  12. :src="data.image"
  13. ></image>
  14. <view class="flex-row-plus flex-sp-between mar-top-40">
  15. <view class="flex-column-plus">
  16. <label class="title-lab fs28">{{ data.productName }}</label>
  17. <view class="spellNum flex-items-plus font-color-C5AA7B mar-top-30 fs24">{{ data.person }}人团</view>
  18. <view class="flex-row-plus mar-top-20 flex-items">
  19. <label class="font-color-C5AA7B fs24">¥</label>
  20. <label class="font-color-C5AA7B fs36 mar-left-5">{{ data.price }}</label>
  21. <label class="font-color-999 fs26 mar-left-20">原价¥{{ data.originalPrice }}</label>
  22. </view>
  23. </view>
  24. <view class="flex-column-plus flex-items-plus">
  25. <image
  26. style="width: 180upx;height: 180upx;"
  27. :src="qrcode"
  28. ></image>
  29. <label class="font-color-666">扫描二维码</label>
  30. </view>
  31. </view>
  32. <!-- #ifndef H5 -->
  33. <view
  34. @click="savePoster(1)"
  35. class="saveposter-but flex-items-plus mar-top-50"
  36. >保存海报
  37. </view>
  38. <!-- #endif -->
  39. <!-- #ifdef H5 -->
  40. <view
  41. @click="savePoster(2)"
  42. class="saveposter-but flex-items-plus mar-top-50"
  43. >预览海报
  44. </view>
  45. <!-- #endif -->
  46. </view>
  47. <view class="bor-reu-8 pad-bot-30 canvas-box">
  48. <canvas
  49. style="width: 375px; height: 560px;"
  50. canvas-id="posterCanvas"
  51. id="posterCanvas"
  52. ></canvas>
  53. </view>
  54. </view>
  55. </template>
  56. <script>
  57. import GloableLoading from "../../components/diyLoading";
  58. import { base64ToPath } from 'image-tools'
  59. const NET = require('../../utils/request')
  60. const API = require('../../config/api')
  61. export default {
  62. components: {GloableLoading},
  63. data() {
  64. return {
  65. data: {},
  66. canvasWidth: 0,
  67. codeImg: '',
  68. codeImg2: '',
  69. headImage: '',
  70. image: '',
  71. qrcode: '',
  72. qrcodeimg: '',
  73. loadingQrcode: true
  74. };
  75. },
  76. onLoad(options) {
  77. this.data = JSON.parse(options.data)
  78. this.getShare()
  79. },
  80. methods: {
  81. savePoster(type) {
  82. if (this.loadingQrcode) {
  83. uni.showToast({
  84. icon: "none",
  85. title: "请稍等,正在生成二维码..."
  86. })
  87. return
  88. }
  89. this.$showLoading()
  90. if (type == 1) {
  91. // uni.showLoading({
  92. // mask: true,
  93. // title:"生成图片中..."
  94. // })
  95. let that = this
  96. setTimeout(() => {
  97. // #ifdef H5 || MP-WEIXIN || APP-PLUS
  98. uni.canvasToTempFilePath({ //把画布转化成临时文件进行保存
  99. fileType: 'png', // 保存成的文件类型
  100. quality: 0, // 图片质量
  101. canvasId: 'posterCanvas', // 画布ID
  102. success: (res) => {
  103. this.$hideLoading()
  104. that.saveDownload(res.tempFilePath)
  105. },
  106. fail: () => {
  107. uni.showToast({
  108. title: '保存失败,稍后再试',
  109. duration: 2000,
  110. icon: 'none'
  111. })
  112. this.$hideLoading()
  113. // uni.hideLoading();
  114. }
  115. })
  116. // #endif
  117. // #ifdef MP-ALIPAY
  118. const CanvasContext = my.createCanvasContext('posterCanvas');
  119. CanvasContext.toTempFilePath({
  120. success: (res) => {
  121. my.saveImage({
  122. url: res.apFilePath,
  123. success: res => {
  124. // uni.hideLoading();
  125. this.$hideLoading()
  126. uni.showToast({
  127. title: '图片保存成功~',
  128. duration: 2000
  129. })
  130. },
  131. fail: err => {
  132. this.$hideLoading()
  133. console.error('saveImage err', err)
  134. },
  135. })
  136. },
  137. fail: () => {
  138. this.$hideLoading()
  139. uni.showToast({
  140. title: '保存失败,稍后再试',
  141. duration: 2000,
  142. icon: 'none'
  143. })
  144. // uni.hideLoading();
  145. }
  146. })
  147. // #endif
  148. }, 5000)
  149. } else if (type == 2) {
  150. // uni.showLoading({
  151. // mask: true,
  152. // title:"图片生成中..."
  153. // })
  154. let that = this
  155. setTimeout(() => {
  156. uni.canvasToTempFilePath({ //把画布转化成临时文件进行保存
  157. fileType: 'png', // 保存成的文件类型
  158. quality: 0, // 图片质量
  159. canvasId: 'posterCanvas', // 画布ID
  160. success: (res) => {
  161. uni.downloadFile({
  162. url: res.tempFilePath,//网络路径,下载下来
  163. success: (res1) => {
  164. this.$hideLoading()
  165. if (res1.statusCode === 200) {
  166. // uni.hideLoading();
  167. uni.showModal({
  168. title: '提示',
  169. content: '长按即可保存图片',
  170. confirmText: "确定",
  171. cancelText: '取消',
  172. success: (res) => {
  173. if (res.confirm) {
  174. uni.previewImage({
  175. current: res1.tempFilePath, // 当前显示图片的http链接
  176. urls: [res1.tempFilePath] // 需要预览的图片http链接列表
  177. })
  178. }
  179. }
  180. })
  181. }
  182. }
  183. })
  184. },
  185. fail: (err) => {
  186. this.$hideLoading()
  187. uni.showToast({
  188. title: '保存失败,稍后再试',
  189. duration: 2000,
  190. icon: 'none'
  191. })
  192. }
  193. })
  194. }, 5000)
  195. }
  196. },
  197. saveDownload(file) {
  198. const that = this
  199. // uni.showLoading({
  200. // mask: true,
  201. // title:"图片保存中..."
  202. // })
  203. this.$showLoading()
  204. uni.getImageInfo({
  205. src: file,
  206. success: (res1) => {
  207. // 2-保存图片至相册
  208. uni.saveImageToPhotosAlbum({ // 存成图片至手机
  209. filePath: res1.path, //画布保存的图片临时文件
  210. success: (res2) => {
  211. this.$hideLoading()
  212. // uni.hideLoading();
  213. uni.showToast({
  214. title: '图片保存成功~',
  215. duration: 2000
  216. })
  217. },
  218. fail: (res3) => {
  219. this.$hideLoading()
  220. if (res3.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
  221. // that.$store.dispatch('SetPhoneShow', 1)
  222. uni.showToast({
  223. title: '保存失败,请检查是否授权小程序保存图片!',
  224. duration: 3000,
  225. icon: 'none'
  226. })
  227. } else {
  228. uni.showToast({
  229. title: '保存失败,稍后再试',
  230. duration: 2000,
  231. icon: 'none'
  232. })
  233. }
  234. // uni.hideLoading();
  235. }
  236. })
  237. }
  238. })
  239. },
  240. getShare() {
  241. NET.request(API.getShare,
  242. {
  243. collageId: this.data.collageId,
  244. orderId: this.data.orderId,
  245. productId: this.data.productId,
  246. skuId: this.data.skuId,
  247. type: 0
  248. },
  249. "GET").then(res => {
  250. // #ifndef MP-WEIXIN
  251. this.qrcode = res.data.qrcode
  252. // #endif
  253. // #ifdef MP-WEIXIN
  254. this.qrcode = res.data.xcxQrcode
  255. // #endif
  256. this.getCanvas()
  257. this.loadingQrcode = false
  258. }).catch(res => {
  259. })
  260. },
  261. getCanvas() {
  262. let that = this
  263. // #ifndef MP-WEIXIN
  264. uni.getImageInfo({
  265. src: that.data.headImage,
  266. success: function (image) {
  267. that.headImage = image.path
  268. uni.getImageInfo({
  269. src: that.data.image,
  270. success: function (image2) {
  271. that.image = image2.path
  272. uni.getImageInfo({
  273. src: that.qrcode,
  274. success: function (image3) {
  275. that.qrcodeimg = image3.path
  276. setTimeout(() => {
  277. var ctx = uni.createCanvasContext('posterCanvas')
  278. ctx.setFillStyle('#FFFFFF')
  279. ctx.fillRect(0, 0, 375, 560)
  280. // ctx.drawImage(that.data.headImage, 0, 0, 150, 100)
  281. that.drawRound(ctx, 25, 160, 28, that.headImage)
  282. ctx.setFontSize(14)
  283. ctx.setFillStyle('#333333')
  284. ctx.fillText('发现一件好物,快来和我一起拼', 89, 120)
  285. ctx.drawImage(that.image, 25, 150, 310, 200)
  286. ctx.setFontSize(14)
  287. ctx.setFillStyle('#333333')
  288. ctx.fillText(that.data.productName, 40, 390)
  289. ctx.setFontSize(14)
  290. ctx.setFillStyle('#C5AA7B')
  291. ctx.fillText(that.data.person + '人团', 40, 430)
  292. ctx.setFontSize(24)
  293. ctx.setFillStyle('#C5AA7B')
  294. ctx.fillText('¥' + that.data.price, 40, 470)
  295. ctx.setFontSize(14)
  296. ctx.setFillStyle('#999999')
  297. ctx.fillText('原价:¥' + that.data.originalPrice, 120, 468)
  298. ctx.drawImage(that.qrcodeimg, 245, 370, 80, 80)
  299. ctx.setFontSize(14)
  300. ctx.setStrokeStyle('#666666')
  301. ctx.fillText('扫描二维码', 250, 468)
  302. ctx.draw()
  303. }, 1500)
  304. }
  305. });
  306. }
  307. });
  308. }
  309. });
  310. // #endif
  311. // #ifdef MP-WEIXIN
  312. uni.getImageInfo({
  313. src: that.data.image,
  314. success: function (image2) {
  315. that.image = image2.path
  316. uni.getImageInfo({
  317. src: that.qrcode,
  318. success: function (image3) {
  319. that.qrcodeimg = image3.path
  320. setTimeout(() => {
  321. var ctx = uni.createCanvasContext('posterCanvas')
  322. ctx.setFillStyle('#FFFFFF')
  323. ctx.fillRect(0, 0, 375, 560)
  324. // ctx.drawImage(that.data.headImage, 0, 0, 150, 100)
  325. // that.drawRound(ctx, 25, 160, 28, that.headImage)
  326. ctx.setFontSize(14)
  327. ctx.setFillStyle('#333333')
  328. ctx.fillText('发现一件好物,快来和我一起拼', 89, 120)
  329. ctx.drawImage(that.image, 25, 150, 310, 200)
  330. ctx.setFontSize(14)
  331. ctx.setFillStyle('#333333')
  332. let newStr = '',startPartIndex = 0
  333. for (let i = 0; i < that.data.productName.length; i++) {
  334. if(i%14=== 0){
  335. newStr += (that.data.productName.slice(startPartIndex,i) + '\n')
  336. startPartIndex = i
  337. }
  338. if(i === that.data.productName.length-1) newStr += that.data.productName.slice(startPartIndex)
  339. }
  340. const productNameArr = newStr.split('\n').filter(item=>item);
  341. productNameArr.forEach((productNameItem,productNameIndex)=>{
  342. let y = 390 + (productNameIndex * 22 )
  343. ctx.fillText(productNameItem, 40, y)
  344. })
  345. ctx.setFontSize(14)
  346. ctx.setFillStyle('#C5AA7B')
  347. ctx.fillText(that.data.person + '人团', 40, 430 + ((productNameArr.length - 1 )* 22))
  348. ctx.setFontSize(24)
  349. ctx.setFillStyle('#C5AA7B')
  350. ctx.fillText('¥' + that.data.price, 40, 470 + ((productNameArr.length-1) * 22))
  351. ctx.setFontSize(14)
  352. ctx.setFillStyle('#999999')
  353. ctx.fillText('原价:¥' + that.data.originalPrice, 120, 468+((productNameArr.length-1) * 22))
  354. ctx.drawImage(that.qrcodeimg, 245, 370+ (productNameArr.length-1) * 22, 80, 80)
  355. ctx.setFontSize(14)
  356. ctx.setStrokeStyle('#666666')
  357. ctx.fillText('扫描二维码', 250, 468 + (productNameArr.length-1) * 22)
  358. ctx.draw()
  359. }, 1500)
  360. }
  361. });
  362. }
  363. });
  364. // #endif
  365. },
  366. exportImg() {
  367. uni.canvasToTempFilePath({
  368. fileType: "jpg",
  369. canvasId: 'couponQrcode',
  370. success: function (res) {
  371. let that = this
  372. // 在H5平台下,tempFilePath 为 base64
  373. // #ifndef H5
  374. that.codeImg = res.tempFilePath
  375. // #endif
  376. // #ifdef H5
  377. base64ToPath(res.tempFilePath).then(path => {
  378. that.codeImg = path
  379. }).catch(error => {
  380. console.error(error)
  381. });
  382. // #endif
  383. }
  384. })
  385. },
  386. drawRound(ctx, r, x, y, img) {
  387. ctx.save() // 保存之前的
  388. var r = r // 半径*屏幕分辨率比例
  389. var d = 2 * r // 直径
  390. var cx = x + r // 圆弧坐标x
  391. var cy = y + r // 圆弧坐标 y
  392. ctx.arc(cx, cy, r, 0, 2 * Math.PI)
  393. ctx.clip() // 裁剪
  394. ctx.drawImage(img, x, y, d, d) // 画头像
  395. ctx.restore() // 返回上一状态
  396. },
  397. }
  398. }
  399. </script>
  400. <style lang="scss">
  401. .qrcode {
  402. padding: 0upx 0 20upx 0;
  403. display: flex;
  404. align-items: center;
  405. justify-content: center;
  406. }
  407. .title {
  408. text-align: center;
  409. }
  410. .canvas-box {
  411. position: absolute;
  412. top: -88888rpx;
  413. }
  414. page {
  415. background-color: #F7F7F7;
  416. }
  417. .invitePoster-box {
  418. .bor-reu-8 {
  419. border-radius: 8rpx;
  420. }
  421. .poster-box {
  422. background-color: #FFFFFF;
  423. margin: 30rpx 30rpx;
  424. width: 690rpx;
  425. padding: 40rpx 34rpx;
  426. border-radius: 8rpx;
  427. .header-img {
  428. width: 100rpx;
  429. height: 100rpx;
  430. border-radius: 50%;
  431. }
  432. .poster-img {
  433. width: 100%;
  434. height: 414rpx;
  435. }
  436. .title-lab {
  437. width: 400rpx;
  438. }
  439. .spellNum {
  440. background-color: #FFEDDF;
  441. border-radius: 22rpx;
  442. width: 144rpx;
  443. height: 44rpx;
  444. }
  445. .code-img {
  446. width: 142rpx;
  447. height: 142rpx;
  448. }
  449. .saveposter-but {
  450. border-radius: 5rpx;
  451. background-color: #C5AA7B;
  452. color: #FFFFFF;
  453. width: 420rpx;
  454. height: 66rpx;
  455. }
  456. }
  457. }
  458. </style>