luckDraw.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <template>
  2. <view class="content">
  3. <view class="luckwheel">
  4. <almost-lottery
  5. :prize-list="prizeList"
  6. :prize-index="prizeIndex"
  7. @reset-index="prizeIndex = -1"
  8. @draw-start="handleDrawStart"
  9. @draw-end="handleDrawEnd"
  10. @finish="handleDrawFinish"
  11. v-if="prizeList.length"
  12. :canvasWidth="canvasData.width"
  13. :canvasHeight="canvasData.height"
  14. :canvasMargin="canvasData.margin"
  15. />
  16. <view class="synums">
  17. 抽奖剩余次数:
  18. <text>2</text>
  19. </view>
  20. </view>
  21. <!-- 获奖人员滚动列表 -->
  22. <vueSeamlessScroll :data="hjList" :class-option="hjListOptions" class="hjList">
  23. <view class="hjList_item" v-for="(item, index) in hjList" :key="index">
  24. 恭喜
  25. <text>{{ item.phone }}</text>
  26. 获得
  27. <text>{{ item.prize }}</text>
  28. </view>
  29. </vueSeamlessScroll>
  30. <!-- 抽奖规则 -->
  31. <view class="guize">
  32. <view>抽奖规则</view>
  33. <view>
  34. <text>1.活动时间:</text>
  35. <text>2020.12.10 至 2020.12.31</text>
  36. </view>
  37. <view>
  38. <text>2.奖品:</text>
  39. <view>
  40. <view>一等奖 华为P40</view>
  41. <view>二等奖 小米电动牙刷</view>
  42. <view>三等奖 瑞士军刀</view>
  43. <view>四等奖 20乐豆</view>
  44. <view>五等奖 7乐豆</view>
  45. </view>
  46. </view>
  47. <view><text>3.抽奖条件:</text></view>
  48. <view>①首次注册乐色管家小程序即可获得一次抽奖机会;</view>
  49. <view>②分享给好友或发送到朋友圈可获得1次抽奖机会;</view>
  50. <view><text>4.抽奖说明:</text></view>
  51. <view>本活动最终解释权归XXXXXX所有。</view>
  52. </view>
  53. </view>
  54. </template>
  55. <script>
  56. import vueSeamlessScroll from 'vue-seamless-scroll'
  57. import AlmostLottery from '@/components/almost-lottery/almost-lottery.vue';
  58. import { clearCacheFile } from '@/almost-utils/almost-utils.js';
  59. export default {
  60. name: 'Home',
  61. components: {
  62. AlmostLottery,
  63. vueSeamlessScroll
  64. },
  65. data() {
  66. return {
  67. hjList: [
  68. {
  69. time: '2019年1月',
  70. phone: '1855****7766',
  71. prize: 'iphone1164G一部'
  72. },
  73. {
  74. time: '2019年2月',
  75. phone: '1855****7766',
  76. prize: 'iphone1164G一部'
  77. },
  78. {
  79. time: '2019年3月',
  80. phone: '1855****7766',
  81. prize: 'iphone1164G一部'
  82. },
  83. {
  84. time: '2019年4月',
  85. phone: '1855****7766',
  86. prize: 'iphone1164G一部'
  87. },
  88. {
  89. time: '2019年5月',
  90. phone: '1855****7766',
  91. prize: 'iphone1164G一部'
  92. },
  93. {
  94. time: '2019年6月',
  95. phone: '1855****7766',
  96. prize: 'iphone1164G一部'
  97. }
  98. ], // 已获奖人员
  99. // canvas 属性配置
  100. canvasData: {
  101. width: 220,
  102. height: 220,
  103. margin: -1
  104. },
  105. // 奖品数据
  106. prizeList: [],
  107. // 中奖下标
  108. prizeIndex: -1,
  109. // 中奖类目名称
  110. targetName: '',
  111. // 奖品是否设有库存
  112. onStock: true,
  113. // 权重随机数的最大值
  114. weightTotal: 0,
  115. // 权重数组
  116. weightArr: []
  117. };
  118. },
  119. computed: {
  120. hjListOptions () {
  121. return {
  122. step: 1,
  123. limitMoveNum: 5,
  124. singleHeight: 30,
  125. waitTime: 1000,
  126. }
  127. }
  128. },
  129. methods: {
  130. // 重新生成
  131. handleInitCanvas() {
  132. clearCacheFile();
  133. this.targetName = '';
  134. this.prizeList = [];
  135. this.getPrizeList();
  136. },
  137. // 获取奖品列表
  138. async getPrizeList() {
  139. uni.showLoading({
  140. title: '奖品准备中...'
  141. });
  142. let res = await this.requestPrizeList();
  143. console.log('获取奖品列表', res);
  144. if (res.ok) {
  145. let data = res.data;
  146. if (data.length) {
  147. // stock 奖品库存
  148. // weight 中奖概率,数值越大中奖概率越高
  149. this.prizeList = data;
  150. }
  151. } else {
  152. uni.hideLoading();
  153. uni.showToast({
  154. title: '获取奖品失败'
  155. });
  156. }
  157. },
  158. // 模拟请求奖品列表接口
  159. requestPrizeList() {
  160. return new Promise((resolve, reject) => {
  161. let requestTimer = setTimeout(() => {
  162. clearTimeout(requestTimer);
  163. requestTimer = null;
  164. resolve({
  165. ok: true,
  166. data: [
  167. {
  168. prizeId: 1,
  169. name: '0.1元现金',
  170. stock: 10,
  171. weight: 0,
  172. prizeImage: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/56f085e0-bcfe-11ea-b244-a9f5e5565f30.png'
  173. },
  174. {
  175. prizeId: 2,
  176. name: '10元现金',
  177. stock: 0,
  178. weight: 0,
  179. prizeImage: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/56f085e0-bcfe-11ea-b244-a9f5e5565f30.png'
  180. },
  181. { prizeId: 3, name: '5元话费', stock: 1, weight: 0 },
  182. { prizeId: 4, name: '50元现金', stock: 0, weight: 0 },
  183. { prizeId: 5, name: '1卷抽纸', stock: 3, weight: 0 },
  184. { prizeId: 6, name: '0.2元现金', stock: 8, weight: 0 },
  185. { prizeId: 7, name: '谢谢参与', stock: 100, weight: 0 },
  186. { prizeId: 8, name: '100金币', stock: 100, weight: 0 }
  187. ]
  188. });
  189. }, 2000);
  190. });
  191. },
  192. // 本次抽奖开始
  193. handleDrawStart() {
  194. this.targetName = '';
  195. let list = [...this.prizeList];
  196. // 模拟请求
  197. let stoTimer = setTimeout(() => {
  198. clearTimeout(stoTimer);
  199. stoTimer = null;
  200. // 这里随机产生的 prizeId 是模拟后端返回的 prizeId
  201. let prizeId = Math.floor(Math.random() * list.length + 1);
  202. list.forEach((item, index) => {
  203. if (item.prizeId === prizeId) {
  204. // 中奖下标
  205. this.prizeIndex = index;
  206. }
  207. });
  208. console.log('本次抽中奖品 =>', this.prizeList[this.prizeIndex].name);
  209. if (this.onStock) {
  210. console.log('本次奖品库存 =>', this.prizeList[this.prizeIndex].stock);
  211. }
  212. }, 200);
  213. },
  214. // 本次抽奖结束
  215. handleDrawEnd() {
  216. // 旋转结束后,可以执行拿到结果后的逻辑
  217. let prizeName = this.prizeList[this.prizeIndex].name;
  218. if (this.onStock) {
  219. let prizeStock = this.prizeList[this.prizeIndex].stock;
  220. this.targetName = prizeName === '谢谢参与' ? prizeName : prizeStock ? `恭喜您,获得 ${prizeName}` : '很抱歉,您来晚了,当前奖品已无库存';
  221. } else {
  222. this.targetName = prizeName === '谢谢参与' ? prizeName : `恭喜您,获得 ${prizeName}`;
  223. }
  224. console.log(this.targetName);
  225. },
  226. // 抽奖转盘绘制完成
  227. handleDrawFinish(res) {
  228. console.log('抽奖转盘绘制完成', res);
  229. uni.showToast({
  230. title: res.msg,
  231. duration: 2000,
  232. mask: true,
  233. icon: 'none'
  234. });
  235. }
  236. },
  237. onLoad() {
  238. // 模拟请求奖品数据
  239. this.getPrizeList();
  240. },
  241. onUnload() {
  242. uni.hideLoading();
  243. }
  244. };
  245. </script>
  246. <style lang="less">
  247. .content {
  248. width: 100%;
  249. background: linear-gradient(#00287a, #002268);
  250. .luckwheel {
  251. padding: 30rpx 0;
  252. .synums {
  253. font-size: 28rpx;
  254. color: #fff;
  255. padding-top: 20rpx;
  256. text-align: center;
  257. text {
  258. color: #ffff00;
  259. margin-left: 6rpx;
  260. }
  261. }
  262. }
  263. .hjList{
  264. .hjList_item{
  265. }
  266. }
  267. .guize {
  268. color: #ffffff;
  269. padding: 30rpx 0;
  270. width: 70%;
  271. margin: 0 auto;
  272. align-items: left;
  273. font-size: 24rpx;
  274. > view {
  275. display: flex;
  276. align-items: center;
  277. padding: 10rpx 0;
  278. width: 100%;
  279. }
  280. }
  281. }
  282. </style>