cm-share-popup.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <view class="cm-share-popup">
  3. <!-- 分享弹窗 -->
  4. <simple-share-popup ref="sharePopup" :posterUrl="posterUrl" @click="onPopupClick" @close="onClose">
  5. <slot name="title"></slot>
  6. </simple-share-popup>
  7. <!-- 海报画布 -->
  8. <canvas canvas-id="poster" class="poster-canvas"></canvas>
  9. </view>
  10. </template>
  11. <script>
  12. import DrawPoster from './draw-poster.js'
  13. import {mapState} from 'vuex'
  14. import { codeQueryStr } from '@/pages/goods/mixins/share.helper.js'
  15. import simpleSharePopup from './simple-share-popup/simple-share-popup.vue'
  16. export default {
  17. name: 'cm-share-popup',
  18. components: {
  19. simpleSharePopup
  20. },
  21. props: {
  22. data: {
  23. type: Object,
  24. default: () => {}
  25. },
  26. type: {
  27. type: String,
  28. default: 'normal',
  29. validator: value => {
  30. return ['product', 'normal', 'activity'].indexOf(value) > -1
  31. }
  32. }
  33. },
  34. data() {
  35. return {
  36. posterUrl: '',
  37. posterData: {
  38. /* 用户信息 */
  39. image: '', // 用户头像
  40. qrCode: '', // 用户二维码
  41. linkMan: '', // 用户名
  42. contractMobile: '', // 用户手机号
  43. /* 页面参数 */
  44. query: '/', // 查询参数字符串
  45. path: '', // 页面路径
  46. qrCodeImage: '', //页面二维码,小程序二维码
  47. /* 产品参数 */
  48. porductName: '', // 产品名
  49. productPrice: '', // 产品价格
  50. productOriginPrice: '', // 产品原价
  51. productImage: '', // 产品图片
  52. /* 活动参数 */
  53. activityName: '', // 活动名称
  54. activityImage: 'https://picsum.photos/400/400' //活动封面
  55. }
  56. }
  57. },
  58. computed: {
  59. ...mapState(['userInfo'])
  60. },
  61. methods: {
  62. // 分享操作
  63. onPopupClick(e) {
  64. if (e.type === 'create-poster') {
  65. console.log('生成海报')
  66. this.createPoster()
  67. } else {
  68. console.log('普通分享')
  69. this.$refs.sharePopup.close()
  70. this.onShare()
  71. }
  72. },
  73. // 打开弹窗
  74. open() {
  75. this.$refs.sharePopup.open()
  76. this.$emit('open')
  77. },
  78. close() {
  79. this.$refs.sharePopup.close()
  80. },
  81. onClose() {
  82. uni.hideLoading()
  83. this.$emit('close')
  84. },
  85. onShare() {
  86. this.$emit('share')
  87. console.log('分享')
  88. },
  89. // 创建海报
  90. async createPoster() {
  91. try {
  92. uni.showLoading({ title: '正在生成海报' })
  93. if (!this.posterUrl) {
  94. this.posterData = { ...this.posterData, ...this.data }
  95. const userProfile = await this.SellerService.GetSellerHome({ userId: this.userInfo.userId })
  96. console.log('userProfile', userProfile)
  97. this.posterData.image = '' // 用户头像
  98. this.posterData.qrCode = '' // 用户二维码
  99. this.posterData.linkMan = '' // 用户名
  100. this.posterData.contractMobile = '' // 用户手机号
  101. // const { data: qrCodeImage } = await this.SellerService.wxUnlimited({
  102. // page: this.posterData.path || 'pages/index/index',
  103. // scene: codeQueryStr(this.posterData.query),
  104. // check_path: process.env.NODE_ENV === 'production', // 是否校验页面
  105. // env_version: process.env.NODE_ENV === 'production' ? 'release' : 'trial', // 正式版 or 开发版
  106. // width: 200, // 二维码宽度
  107. // auto_color: false, // 自动颜色
  108. // line_color: { 'r': 0, 'g': 0, 'b': 0 }, // 线条颜色
  109. // is_hyaline: true // 透明底
  110. // })
  111. // const { data: qrCodeImage } = await generateWxUnlimited({
  112. // pagePath: this.posterData.path,
  113. // queryStr: this.posterData.query
  114. // })
  115. // this.posterData.qrCodeImage = qrCodeImage
  116. // this.posterData.qrCodeImage = ''
  117. switch (this.type) {
  118. case 'product':
  119. await this.createProductPoster()
  120. break
  121. case 'activity':
  122. await this.createActivityPoster()
  123. break
  124. default:
  125. await this.createNormalPoster()
  126. }
  127. // const {tempFilePath} = await this.canvasToTempFilePath()
  128. // this.posterUrl = tempFilePath
  129. }
  130. uni.hideLoading()
  131. // 下载完成后转发
  132. // wx.showShareImageMenu({ path: this.posterUrl })
  133. this.onShare()
  134. // console.log(this.posterUrl)
  135. } catch (e) {
  136. console.log(e)
  137. } finally {
  138. uni.hideLoading()
  139. }
  140. },
  141. // 画布转图片临时链接
  142. canvasToTempFilePath() {
  143. return new Promise((resolve, reject) => {
  144. uni.canvasToTempFilePath(
  145. {
  146. canvasId: 'poster',
  147. success: res => {
  148. resolve(res)
  149. },
  150. fail() {
  151. reject(false)
  152. }
  153. },
  154. this
  155. )
  156. })
  157. },
  158. // 生成绘制文本数组
  159. generateTextArray() {
  160. const textArray = []
  161. const { productPrice, productOriginPrice, productName, activityName } = this.posterData
  162. // 处理价格
  163. let priceText = ''
  164. if (this.type === 'product') {
  165. if (productPrice) {
  166. priceText += productPrice
  167. }
  168. if (productOriginPrice) {
  169. priceText += '¥' + productOriginPrice
  170. }
  171. }
  172. textArray.push(priceText)
  173. console.log(this.posterData)
  174. // 处理产品名称
  175. if (productName) {
  176. const nameStr = productName || activityName
  177. textArray.push(nameStr.substring(0, 12))
  178. if (nameStr.length > 24) {
  179. textArray.push(nameStr.substring(12, 23) + '...')
  180. } else {
  181. textArray.push(nameStr.substring(12))
  182. }
  183. }
  184. return textArray
  185. },
  186. // 商品海报
  187. async createProductPoster() {
  188. try {
  189. const ctx = uni.createCanvasContext('poster', this)
  190. const drawPoster = new DrawPoster(ctx, {
  191. avatarUrl: this.posterData.avatar,
  192. userName: this.posterData.username,
  193. subTitle: '强烈为你推荐该商品',
  194. coverUrl: this.posterData.productImage,
  195. // ewmUrl: this.posterData.qrCodeImage,
  196. textArray: this.generateTextArray()
  197. })
  198. return await drawPoster.draw()
  199. } catch (e) {
  200. throw e
  201. }
  202. },
  203. // 活动页面
  204. async createActivityPoster() {
  205. try {
  206. const ctx = uni.createCanvasContext('poster', this)
  207. const drawPoster = new DrawPoster(ctx, {
  208. avatarUrl: this.posterData.avatar,
  209. userName: this.posterData.username,
  210. subTitle: '强烈为你推荐该活动',
  211. coverUrl: this.posterData.activityImage,
  212. ewmUrl: this.posterData.qrCodeImage,
  213. textArray: this.generateTextArray()
  214. })
  215. return await drawPoster.draw()
  216. } catch (e) {
  217. throw e
  218. }
  219. },
  220. // 普通海报
  221. async createNormalPoster() {
  222. try {
  223. const ctx = uni.createCanvasContext('poster', this)
  224. const drawPoster = new DrawPoster(ctx, {
  225. avatarUrl: this.posterData.avatar,
  226. userName: this.posterData.username,
  227. subTitle: '强烈为你推荐该商城',
  228. textArray: ['', '护肤上颜选,正品', '有好货~~']
  229. })
  230. return await drawPoster.draw()
  231. } catch (e) {
  232. throw e
  233. }
  234. }
  235. }
  236. }
  237. </script>
  238. <style lang="scss" scoped>
  239. .poster-canvas {
  240. position: fixed;
  241. top: 0;
  242. left: 0;
  243. width: 375px;
  244. height: 610px;
  245. border: 1px solid;
  246. }
  247. </style>