coupons.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <template>
  2. <view class="coupon_box">
  3. <view v-if="type === 'user'" class="other_type">
  4. <view class="text"><span>已领取优惠券</span></view>
  5. </view>
  6. <coupon v-for="(item, index) in couponList" :key="index" v-bind:item="item" :index="index" @shareCoupon="shareCoupon" @useCoupon="useCoupon"
  7. @obtainCoupon="obtainCoupon" theme="#ff0000"></coupon>
  8. <view v-if="type === 'list' || obatinableCouponList.length > 0" class="other_type">
  9. <view class="text"><span>可领取</span></view>
  10. </view>
  11. <coupon v-for="(item, index) in obatinableCouponList" v-if="item.remainCount > 0" :key="index" v-bind:item="item" :index="index" @shareCoupon="shareCoupon" @useCoupon="useCoupon"
  12. @obtainCoupon="obtainCoupon" theme="#ff0000"></coupon>
  13. <view class="hideCanvasView">
  14. <canvas class="hideCanvas" canvas-id="default_PosterCanvasId" :style="{width: (poster.width||0) + 'px', height: (poster.height||0) + 'px'}"></canvas>
  15. </view>
  16. <!-- 以下是浮层 -->
  17. <view class="flex_row_c_c modalView" :class="qrShow?'show':''" @tap="hideQr()">
  18. <view class="flex_column">
  19. <view class="backgroundColor-white padding1vh border_radius_10px">
  20. <image :src="poster.finalPath" mode="widthFix" class="posterImage"></image>
  21. </view>
  22. <view class="flex_row marginTop2vh">
  23. <button class="posterBtn" type="primary" size="mini" @tap.prevent.stop="saveImage()">保存图片</button>
  24. <button class="posterBtn" type="primary" open-type="share" size="mini">分享好友</button>
  25. </view>
  26. </view>
  27. </view>
  28. <view v-if="type === 'list'" class="other_type">
  29. <view class="text"><span>可领取优惠券</span></view>
  30. </view>
  31. </view>
  32. </template>
  33. <script>
  34. import coupon from '@/components/coolc-coupon/coolc-coupon'
  35. import { getSharePoster } from '@/components/QS-SharePoster/QS-SharePoster.js'
  36. import _app from '@/components/QS-SharePoster/app.js'
  37. export default {
  38. components: {
  39. coupon
  40. },
  41. data() {
  42. return {
  43. title: '可领取优惠券',
  44. couponList: [],
  45. obatinableCouponList: [],
  46. type: 'list',
  47. poster: {},
  48. qrShow: false,
  49. canvasId: 'default_PosterCanvasId',
  50. couponId: undefined
  51. }
  52. },
  53. /**
  54. * @param {Object} options .type 取值为 list(默认) | user
  55. * list: 表示从Advert等地方进去的,只显示可领取优惠券
  56. * user: 表示从我的进去的,显示已领取优惠券
  57. */
  58. onLoad(options) {
  59. if (options.type) {
  60. this.type = options.type
  61. } else {
  62. this.type = 'list'
  63. }
  64. this.loadData()
  65. },
  66. onShareAppMessage() {
  67. const that = this
  68. if (that.couponId) {
  69. return {
  70. title: '',
  71. imageUrl: '',
  72. path: '/pages/index/index?couponid=' + that.couponId
  73. }
  74. } else {
  75. return {
  76. title: '',
  77. imageUrl: '',
  78. path: '/pages/coupon/list'
  79. }
  80. }
  81. },
  82. methods: {
  83. async loadData() {
  84. const that = this
  85. if (that.type === 'user') {
  86. that.$api.request('get', 'coupon/app/getUserCoupons').then(res => {
  87. that.couponList = res.data
  88. })
  89. }
  90. that.$api.request('get', 'coupon/app/getObtainableCoupon').then(res => {
  91. that.obatinableCouponList = res.data
  92. })
  93. },
  94. obtainCoupon(item, index) {
  95. const that = this
  96. that.$api.request('get', 'coupon/app/obtainCoupon', {
  97. couponId: item.id
  98. }).then(res => {
  99. that.$api.msg('领取成功')
  100. if (that.type === 'list') {
  101. that.couponList[index].nowCount++
  102. } else {
  103. that.loadData()
  104. }
  105. })
  106. },
  107. shareCoupon(item, index) {
  108. const that = this
  109. uni.showLoading({
  110. title: '正在获取.'
  111. })
  112. if (!item.couponId) {
  113. that.$api.msg('这个优惠券不能分享')
  114. return
  115. }
  116. that.$api.request('get', 'coupon/app/getCouponQRCodeUrl', {
  117. couponId: item.couponId
  118. }, failres => {
  119. uni.hideLoading()
  120. that.$api.msg(failres.errmsg)
  121. }).then(res => {
  122. that.shareFc(res.data)
  123. })
  124. },
  125. useCoupon(item, index) {
  126. uni.switchTab({
  127. url:`../category/category`
  128. })
  129. },
  130. async shareFc(qrcodeText) {
  131. try {
  132. console.log('准备生成:' + new Date())
  133. const d = await getSharePoster({
  134. _this: this, //若在组件中使用 必传
  135. type: 'testShareType',
  136. formData: {
  137. //访问接口获取背景图携带自定义数据
  138. },
  139. posterCanvasId: this.canvasId, //canvasId
  140. delayTimeScale: 20, //延时系数
  141. /* background: {
  142. width: 1080,
  143. height: 1920,
  144. backgroundColor: '#666'
  145. }, */
  146. drawArray: ({
  147. bgObj,
  148. type,
  149. bgScale
  150. }) => {
  151. const dx = bgObj.width * 0.3;
  152. const fontSize = bgObj.width * 0.045;
  153. const lineHeight = bgObj.height * 0.04;
  154. //可直接return数组,也可以return一个promise对象, 但最终resolve一个数组, 这样就可以方便实现后台可控绘制海报
  155. return new Promise((rs, rj) => {
  156. rs([{
  157. type: 'custom',
  158. setDraw(Context) {
  159. Context.setFillStyle('black');
  160. Context.setGlobalAlpha(0.3);
  161. Context.fillRect(0, bgObj.height - bgObj.height * 0.2, bgObj.width, bgObj.height * 0.2);
  162. Context.setGlobalAlpha(1);
  163. }
  164. },
  165. {
  166. type: 'image',
  167. url: '/static/logo.jpg',
  168. alpha: .3,
  169. dx,
  170. dy: bgObj.height - bgObj.width * 0.25,
  171. infoCallBack(imageInfo) {
  172. let scale = bgObj.width * 0.2 / imageInfo.height;
  173. return {
  174. circleSet: {
  175. x: imageInfo.width * scale / 2,
  176. y: bgObj.width * 0.2 / 2,
  177. r: bgObj.width * 0.2 / 2
  178. }, // 圆形图片 , 若circleSet与roundRectSet一同设置 优先circleSet设置
  179. dWidth: imageInfo.width * scale, // 因为设置了圆形图片 所以要乘以2
  180. dHeight: bgObj.width * 0.2,
  181. /* roundRectSet: { // 圆角矩形
  182. r: imageInfo.width * .1
  183. } */
  184. }
  185. }
  186. },
  187. {
  188. type: 'text',
  189. fontStyle: 'italic',
  190. text: '优惠券',
  191. size: fontSize,
  192. color: 'white',
  193. alpha: .5,
  194. textAlign: 'left',
  195. textBaseline: 'middle',
  196. infoCallBack(textLength) {
  197. _app.log('index页面的text的infocallback ,textlength:' + textLength);
  198. return {
  199. dx: bgObj.width - textLength - fontSize,
  200. dy: bgObj.height - lineHeight * 3
  201. }
  202. },
  203. serialNum: 0,
  204. id: 'tag1' //自定义标识
  205. },
  206. {
  207. type: 'text',
  208. text: '优惠券',
  209. fontWeight: 'bold',
  210. size: fontSize,
  211. color: 'white',
  212. alpha: .75,
  213. textAlign: 'left',
  214. textBaseline: 'middle',
  215. serialNum: 1,
  216. allInfoCallback({ //v3.0.1 更新 可以获取drawArray中全部数据
  217. drawArray
  218. } = {}) {
  219. const obj = drawArray.find(item => item.id === 'tag1');
  220. /* return {
  221. dx: obj.dx,
  222. dy: obj.dy + lineHeight
  223. } */
  224. //也可以return promise对象
  225. return new Promise((rs, rj) => {
  226. setTimeout(() => {
  227. rs({
  228. dx: obj.dx,
  229. dy: obj.dy + lineHeight
  230. });
  231. }, 1);
  232. });
  233. }
  234. },
  235. {
  236. type: 'text',
  237. text: '优惠券',
  238. size: fontSize,
  239. color: 'white',
  240. alpha: 1,
  241. textAlign: 'left',
  242. textBaseline: 'middle',
  243. infoCallBack(textLength) {
  244. return {
  245. dx: bgObj.width - textLength - fontSize,
  246. dy: bgObj.height - lineHeight
  247. }
  248. }
  249. },
  250. {
  251. type: 'qrcode',
  252. text: qrcodeText,
  253. size: bgObj.width * 0.2,
  254. dx: bgObj.width * 0.05,
  255. dy: bgObj.height - bgObj.width * 0.25
  256. }
  257. ]);
  258. })
  259. },
  260. setCanvasWH: ({
  261. bgObj,
  262. type,
  263. bgScale
  264. }) => { // 为动态设置画布宽高的方法,
  265. this.poster = bgObj;
  266. }
  267. });
  268. console.log('海报生成成功, 时间:' + new Date() + ', 临时路径: ' + d.poster.tempFilePath)
  269. this.poster.finalPath = d.poster.tempFilePath;
  270. this.qrShow = true;
  271. } catch (e) {
  272. _app.hideLoading();
  273. _app.showToast(JSON.stringify(e));
  274. console.log(JSON.stringify(e));
  275. }
  276. },
  277. saveImage() {
  278. // #ifndef H5
  279. uni.saveImageToPhotosAlbum({
  280. filePath: this.poster.finalPath,
  281. success(res) {
  282. _app.showToast('保存成功');
  283. }
  284. })
  285. // #endif
  286. // #ifdef H5
  287. _app.showToast('保存了');
  288. // #endif
  289. },
  290. share() {
  291. // #ifdef APP-PLUS
  292. _app.getShare(false, false, 2, '', '', '', this.poster.finalPath, false, false);
  293. // #endif
  294. // #ifndef APP-PLUS
  295. _app.showToast('分享了');
  296. // #endif
  297. },
  298. hideQr() {
  299. this.qrShow = false;
  300. }
  301. }
  302. }
  303. </script>
  304. <style lang='scss'>
  305. page {
  306. background: #FFFFFF;
  307. }
  308. .coupon_box {
  309. width: 100%;
  310. height: auto;
  311. display: table;
  312. padding: 6upx 26upx 26upx 26upx;
  313. }
  314. .other_type {
  315. width: 100%;
  316. height: 90upx;
  317. padding-top: 50upx;
  318. .text {
  319. width: 100%;
  320. border-top: 1px solid #eeeeee;
  321. display: block;
  322. text-align: center;
  323. position: relative;
  324. }
  325. .text span {
  326. width: 180upx;
  327. height: 40upx;
  328. line-height: 40upx;
  329. color: #999999;
  330. display: block;
  331. background: #ffffff;
  332. position: absolute;
  333. left: 50%;
  334. top: 50%;
  335. margin-left: -90upx;
  336. margin-top: -20upx;
  337. font-size: $font-base;
  338. }
  339. }
  340. .hideCanvasView {
  341. position: relative;
  342. }
  343. .hideCanvas {
  344. position: fixed;
  345. top: -99999upx;
  346. left: -99999upx;
  347. z-index: -99999;
  348. }
  349. .flex_row_c_c {
  350. display: flex;
  351. flex-direction: row;
  352. justify-content: center;
  353. align-items: center;
  354. }
  355. .modalView {
  356. width: 100%;
  357. height: 100%;
  358. position: fixed;
  359. top: 0;
  360. left: 0;
  361. right: 0;
  362. bottom: 0;
  363. opacity: 0;
  364. outline: 0;
  365. transform: scale(1.2);
  366. perspective: 2500upx;
  367. background: rgba(0, 0, 0, 0.6);
  368. transition: all .3s ease-in-out;
  369. pointer-events: none;
  370. backface-visibility: hidden;
  371. z-index: 999;
  372. }
  373. .modalView.show {
  374. opacity: 1;
  375. transform: scale(1);
  376. pointer-events: auto;
  377. }
  378. .flex_column {
  379. display: flex;
  380. flex-direction: column;
  381. }
  382. .backgroundColor-white {
  383. background-color: white;
  384. }
  385. .border_radius_10px {
  386. border-radius: 10px;
  387. }
  388. .padding1vh {
  389. padding: 1vh;
  390. }
  391. .posterImage {
  392. width: 60vw;
  393. }
  394. .flex_row {
  395. display: flex;
  396. flex-direction: row;
  397. }
  398. .marginTop2vh {
  399. margin-top: 2vh;
  400. }
  401. .posterBtn {
  402. background: $uni-color-primary;
  403. color: #fff;
  404. font-size: $font-lg;
  405. }
  406. </style>