index.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <template>
  2. <view style="height: 100%;">
  3. <view class='distribution-posters'>
  4. <swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :circular="circular" :interval="interval"
  5. :duration="duration" @change="bindchange" previous-margin="40px" next-margin="40px">
  6. <block v-for="(item,index) in posterUrls" :key="index">
  7. <swiper-item>
  8. <image :src="item.pic" class="slide-image" :class="swiperIndex == index ? 'active' : 'quiet'"
  9. mode='aspectFill' />
  10. </swiper-item>
  11. </block>
  12. </swiper>
  13. <!-- #ifdef MP -->
  14. <view class='keep bg-color' @click='savePosterPath'>保存海报</view>
  15. <!-- #endif -->
  16. <!-- #ifndef MP -->
  17. <div class="preserve acea-row row-center-wrapper">
  18. <div class="line"></div>
  19. <div class="tip">长按保存图片</div>
  20. <div class="line"></div>
  21. </div>
  22. <!-- #endif -->
  23. </view>
  24. <!-- #ifdef MP -->
  25. <!-- <authorize @onLoadFun="onLoadFun" :isAuto="isAuto" :isShowAuth="isShowAuth" @authColse="authColse"></authorize> -->
  26. <!-- #endif -->
  27. <view class="canvas" v-if="canvasStatus">
  28. <canvas style="width:750px;height:1190px;" canvas-id="canvasOne"></canvas>
  29. <canvas canvas-id="qrcode" :style="{width: `${qrcodeSize}px`, height: `${qrcodeSize}px`}" />
  30. </view>
  31. </view>
  32. </template>
  33. <script>
  34. // #ifdef H5
  35. import uQRCode from '@/js_sdk/Sansnn-uQRCode/uqrcode.js'
  36. // #endif
  37. import { toLogin } from '@/libs/login.js';
  38. import { mapGetters } from "vuex";
  39. // #ifdef MP
  40. import { base64src } from '@/utils/base64src.js'
  41. import { getQrcode } from '@/api/api.js';
  42. // #endif
  43. import home from '@/components/home';
  44. import * as TradeConfigApi from '@/api/trade/config.js';
  45. export default {
  46. components: {
  47. home
  48. },
  49. data() {
  50. return {
  51. imgUrls: [],
  52. indicatorDots: false,
  53. circular: false,
  54. autoplay: false,
  55. interval: 3000,
  56. duration: 500,
  57. swiperIndex: 0,
  58. posterUrls: [],
  59. poster: '',
  60. qrcodeSize: 1000,
  61. PromotionCode: '',
  62. base64List: [],
  63. canvasStatus: true //海报绘图标签
  64. };
  65. },
  66. computed: mapGetters(['isLogin', 'uid', 'userInfo']),
  67. watch: {
  68. isLogin: {
  69. handler: function(newV, oldV) {
  70. if (newV) {
  71. this.userSpreadBannerList();
  72. }
  73. },
  74. deep: true
  75. }
  76. },
  77. onLoad() {
  78. if (!this.isLogin) {
  79. toLogin();
  80. return;
  81. }
  82. this.userSpreadBannerList();
  83. },
  84. /**
  85. * 用户点击右上角分享
  86. */
  87. // #ifdef MP
  88. onShareAppMessage: function() {
  89. return {
  90. title: this.userInfo.nickname + '-分销海报',
  91. imageUrl: this.posterUrls[0].pic,
  92. path: '/pages/index/index?spid=' + this.uid,
  93. };
  94. },
  95. // #endif
  96. onReady() {},
  97. methods: {
  98. userSpreadBannerList: function() {
  99. let that = this;
  100. uni.showLoading({
  101. title: '获取中',
  102. mask: true,
  103. })
  104. TradeConfigApi.getTradeConfig().then(res => {
  105. uni.hideLoading();
  106. const posterUrls = [];
  107. // TODO @芋艿:这里后续可以优化下;直接使用 brokeragePosterUrls 数组,而不是要搞 pic 元素
  108. if (res.data.brokeragePosterUrls) {
  109. res.data.brokeragePosterUrls.forEach(item => {
  110. posterUrls.push({
  111. pic: item
  112. })
  113. })
  114. }
  115. that.$set(that, 'posterUrls', posterUrls);
  116. that.getImageBase64(posterUrls);
  117. }).catch(err => {
  118. uni.hideLoading();
  119. });
  120. },
  121. getImageBase64: function(images) {
  122. uni.showLoading({
  123. title: '海报生成中',
  124. mask: true
  125. });
  126. let that = this;
  127. // #ifdef H5
  128. let posterUrls = []
  129. // 生成一个Promise对象的数组
  130. images.forEach(item => {
  131. posterUrls.push(item.pic)
  132. })
  133. Promise.all(posterUrls).then(result => {
  134. that.$set(that, 'base64List', result);
  135. that.make();
  136. that.setShareInfoStatus();
  137. })
  138. // #endif
  139. // #ifdef MP
  140. that.base64List = images.map(item => {
  141. return item.pic
  142. });
  143. // #endif
  144. // #ifdef MP
  145. that.getQrcode();
  146. // #endif
  147. },
  148. // 小程序二维码
  149. getQrcode() {
  150. let that = this;
  151. let data = {
  152. pid: that.uid,
  153. path: 'pages/index/index'
  154. }
  155. let arrImagesUrl = "";
  156. uni.downloadFile({
  157. url: this.base64List[0],
  158. success: (res) => {
  159. arrImagesUrl = res.tempFilePath;
  160. }
  161. });
  162. getQrcode(data).then(res => {
  163. base64src(res.data.code, res => {
  164. that.PromotionCode = res;
  165. });
  166. setTimeout(() => {
  167. that.PosterCanvas(arrImagesUrl, that.PromotionCode, that.userInfo.nickname, 0);
  168. }, 300);
  169. }).catch(err => {
  170. uni.hideLoading();
  171. that.$util.Tips({
  172. title: err
  173. });
  174. that.$set(that, 'canvasStatus', false);
  175. });
  176. },
  177. // 生成二维码;
  178. make() {
  179. let that = this;
  180. let href = '';
  181. // #ifdef H5
  182. href = window.location.href.split('/pages')[0];
  183. // #endif
  184. uQRCode.make({
  185. canvasId: 'qrcode',
  186. text: href + '/pages/index/index?spread=' + that.uid,
  187. size: this.qrcodeSize,
  188. margin: 10,
  189. success: res => {
  190. that.PromotionCode = res;
  191. setTimeout(() => {
  192. that.PosterCanvas(this.base64List[0], that.PromotionCode, that.userInfo
  193. .nickname, 0);
  194. }, 300);
  195. },
  196. complete: (res) => {},
  197. fail: res => {
  198. uni.hideLoading();
  199. that.$util.Tips({
  200. title: '海报二维码生成失败!'
  201. });
  202. }
  203. })
  204. },
  205. PosterCanvas: function(arrImages, code, nickname, index) {
  206. let context = uni.createCanvasContext('canvasOne')
  207. context.clearRect(0, 0, 0, 0);
  208. let that = this;
  209. uni.getImageInfo({
  210. src: arrImages,
  211. success: function(res) {
  212. context.drawImage(arrImages, 0, 0, 750, 1190);
  213. context.save();
  214. context.drawImage(code, 110, 925, 140, 140);
  215. context.restore();
  216. context.setFontSize(28);
  217. context.fillText(nickname, 270, 980);
  218. context.fillText('邀请您加入', 270, 1020);
  219. setTimeout(() => {
  220. context.draw(true, function() {
  221. uni.canvasToTempFilePath({
  222. destWidth: 750,
  223. destHeight: 1190,
  224. canvasId: 'canvasOne',
  225. fileType: 'jpg',
  226. success: function(res) {
  227. // 在H5平台下,tempFilePath 为 base64
  228. uni.hideLoading();
  229. that.posterUrls[index].pic = res
  230. .tempFilePath;
  231. that.$set(that, 'poster', res
  232. .tempFilePath);
  233. that.$set(that, 'canvasStatus', false);
  234. }
  235. })
  236. })
  237. }, 100);
  238. },
  239. fail: function(err) {
  240. uni.hideLoading();
  241. that.$util.Tips({
  242. title: '无法获取图片信息'
  243. });
  244. }
  245. });
  246. },
  247. onLoadFun: function(e) {
  248. this.$set(this, 'userInfo', e);
  249. this.userSpreadBannerList();
  250. },
  251. // 授权关闭
  252. authColse: function(e) {
  253. this.isShowAuth = e
  254. },
  255. bindchange(e) {
  256. let base64List = this.base64List;
  257. let index = e.detail.current;
  258. this.swiperIndex = index;
  259. let arrImagesUrl = "";
  260. uni.downloadFile({
  261. url: base64List[index],
  262. success: (res) => {
  263. arrImagesUrl = res.tempFilePath;
  264. setTimeout(() => {
  265. this.$set(this, 'canvasStatus', true);
  266. this.PosterCanvas(arrImagesUrl, this.PromotionCode, this.userInfo.nickname,
  267. index);
  268. }, 300);
  269. }
  270. });
  271. },
  272. // 点击保存海报
  273. savePosterPath: function() {
  274. let that = this;
  275. uni.getSetting({
  276. success(res) {
  277. if (!res.authSetting['scope.writePhotosAlbum']) {
  278. uni.authorize({
  279. scope: 'scope.writePhotosAlbum',
  280. success() {
  281. uni.saveImageToPhotosAlbum({
  282. filePath: that.poster,
  283. success: function(res) {
  284. that.$util.Tips({
  285. title: '保存成功',
  286. icon: 'success'
  287. });
  288. },
  289. fail: function(res) {
  290. that.$util.Tips({
  291. title: '保存失败'
  292. });
  293. }
  294. });
  295. }
  296. });
  297. } else {
  298. uni.saveImageToPhotosAlbum({
  299. filePath: that.poster,
  300. success: function(res) {
  301. that.$util.Tips({
  302. title: '保存成功',
  303. icon: 'success'
  304. });
  305. },
  306. fail: function(res) {
  307. that.$util.Tips({
  308. title: '保存失败'
  309. });
  310. }
  311. });
  312. }
  313. }
  314. });
  315. },
  316. setShareInfoStatus: function() {
  317. if (this.$wechat.isWeixin()) {
  318. let configAppMessage = {
  319. desc: '分销海报',
  320. title: this.userInfo.nickname + '-分销海报',
  321. link: '/pages/index/index?spread=' + this.uid,
  322. imgUrl: this.posterUrls[0].pic
  323. };
  324. this.$wechat.wechatEvevt(["updateAppMessageShareData", "updateTimelineShareData"],
  325. configAppMessage)
  326. }
  327. }
  328. }
  329. }
  330. </script>
  331. <style lang="scss" scoped>
  332. page {
  333. background-color: #a3a3a3 !important;
  334. height: 100% !important;
  335. }
  336. .canvas {
  337. position: relative;
  338. }
  339. .distribution-posters {
  340. width: 100%;
  341. height: 100%;
  342. display: flex;
  343. flex-direction: column;
  344. justify-content: center;
  345. align-items: center;
  346. }
  347. .distribution-posters swiper {
  348. width: 100%;
  349. height: 1000rpx;
  350. position: relative;
  351. margin-top: 40rpx;
  352. }
  353. .distribution-posters .slide-image {
  354. width: 100%;
  355. height: 100%;
  356. margin: 0 auto;
  357. border-radius: 15rpx;
  358. }
  359. .distribution-posters .slide-image.active {
  360. transform: none;
  361. transition: all 0.2s ease-in 0s;
  362. }
  363. .distribution-posters .slide-image.quiet {
  364. transform: scale(0.8333333);
  365. transition: all 0.2s ease-in 0s;
  366. }
  367. .distribution-posters .keep {
  368. font-size: 30rpx;
  369. color: #fff;
  370. width: 600rpx;
  371. height: 80rpx;
  372. border-radius: 50rpx;
  373. text-align: center;
  374. line-height: 80rpx;
  375. margin: 38rpx auto;
  376. }
  377. .distribution-posters .preserve {
  378. color: #fff;
  379. text-align: center;
  380. margin-top: 38rpx;
  381. }
  382. .distribution-posters .preserve .line {
  383. width: 100rpx;
  384. height: 1px;
  385. background-color: #fff;
  386. }
  387. .distribution-posters .preserve .tip {
  388. margin: 0 30rpx;
  389. }
  390. </style>