index.vue 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <template>
  2. <transition name="msgbox-fade">
  3. <div class="popup-wrap mod-lottery">
  4. <div class="popup-modal"></div>
  5. <div class="popup-box">
  6. <div class="popup-hd">
  7. <div class="popup-hd-title"><em>{{$t('lottery.title')}}</em></div>
  8. <span class="popup-close" @click="$emit('visible:lottery')"></span>
  9. </div>
  10. <div class="popup-bd">
  11. <div class="lottery-wrap">
  12. <p class="left-time">{{$t('lottery.text1')}}:{{leftTimes}}</p>
  13. <div class="lottery-wheel" v-if="rewardList.length">
  14. <div class="wheel" :style="{transform: `rotate(${rotateDeg}deg)`}">
  15. <div class="rotate-box" v-for="(item, key) in rewardList" :key="key">
  16. <div class="wheel-item">
  17. <span class="amount">{{item}}</span>
  18. <i class="gold-eos-icon"></i>
  19. </div>
  20. </div>
  21. </div>
  22. <div class="lottery-btn" :class="{'lottery-btn-small': isRotating}" v-if="ttl == 0" @click="runLottery">
  23. {{isRotating ? $t('lottery.text2') : $t('lottery.text3')}}
  24. </div>
  25. <div class="lottery-btn disabled" v-else-if="ttl == -1">{{$t('lottery.text3')}}</div>
  26. <div class="lottery-btn disabled time-count-down" v-else>{{timeStr}}</div>
  27. </div>
  28. <transition name="msgbox-fade">
  29. <div class="lottery-result" v-if="luckResult">
  30. <div class="num">{{$t('lottery.text5')}}:{{luckResult.luckdraw_num}}</div>
  31. <div class="lottery-fair">
  32. <span class="title">{{$t('lottery.text5')}}</span>
  33. <a target="_blank" :href="`https://eospark.com/block/${luckResult.next_block_num}`" class="fair-num">{{luckResult.next_block_num}}</a>
  34. <a target="_blank" :href="`https://eospark.com/block/${luckResult.next_block_num}`" class="hash" v-html="luckHash"></a>
  35. </div>
  36. <div class="lottery-fair">
  37. <span class="title">{{$t('lottery.text3')}}</span>
  38. <a target="_blank" :href="`https://eospark.com/tx/${luckResult.trx_id}`" class="fair-num">{{luckResult.draw_block_num}}</a>
  39. <a target="_blank" :href="`https://eospark.com/tx/${luckResult.trx_id}`" class="hash">...{{luckResult.trx_id.substring(luckResult.trx_id.length - 30,luckResult.trx_id.length)}}</a>
  40. </div>
  41. </div>
  42. </transition>
  43. <p class="lottery-tips">{{$t('lottery.text4')}}</p>
  44. </div>
  45. </div>
  46. </div>
  47. </div>
  48. </transition>
  49. </template>
  50. <script>
  51. import API from '@/api'
  52. import { mapState } from 'vuex'
  53. import { showError } from '@/util/util'
  54. export default {
  55. name: 'lottery',
  56. data () {
  57. return {
  58. rewardList: [],
  59. rotateDeg: 60,
  60. isRotating: false,
  61. leftTimes: 0, // 抽奖剩余次数
  62. ttl: 0, // 剩余秒数
  63. luckResult: null, // 抽奖结果
  64. timeStr: ''
  65. }
  66. },
  67. computed: {
  68. identity () {
  69. return { authorization: [`${this.account.name}@${this.account.authority}`] }
  70. },
  71. luckHash () {
  72. if (this.luckResult) {
  73. let hash = this.luckResult.next_block_id
  74. let luckNum = this.luckResult.luckdraw_num.toString()
  75. let subHash = hash.substring(hash.length - 30, hash.length)
  76. let hashArr = subHash.split('')
  77. let luckLen = luckNum.length
  78. let k = 0
  79. for (let i = hashArr.length - 1; i >= 0; i--) {
  80. let char = hashArr[i]
  81. if (luckNum.indexOf(char) > -1 && k < luckLen) {
  82. let newChar = `<span class="yellow">${char}</span>`
  83. hashArr.splice(i, 1, newChar)
  84. k++
  85. }
  86. }
  87. return '...' + hashArr.join('')
  88. } else {
  89. return ''
  90. }
  91. },
  92. ...mapState({
  93. eos: state => state.eos,
  94. account: state => state.account
  95. })
  96. },
  97. methods: {
  98. async runLottery () {
  99. this.$showLoading()
  100. var doAction = (param) => {
  101. API.eos.sendLuckTrx(param)
  102. .then(({ data }) => {
  103. this.$hideLoading()
  104. if (data.code === 0) {
  105. // 计算角度
  106. let rewardAmount = data.data.luckdraw_amount_int / 10000
  107. let ind = this.rewardList.indexOf(rewardAmount.toString())
  108. this.rotateDeg = 1800 + ind * 60
  109. this.isRotating = true
  110. // 结束抽奖
  111. setTimeout(() => {
  112. this.isRotating = false
  113. this.luckResult = data.data
  114. this.$store.commit('updateBalance', data.data.luckdraw_amount_int)
  115. this.leftTimes--
  116. this.ttl = 3600
  117. this.timer = setInterval(() => {
  118. this.updateTime()
  119. }, 1000)
  120. }, 3500)
  121. }
  122. }).catch(() => {
  123. this.$hideLoading()
  124. })
  125. }
  126. var memo
  127. if (this.$isLogin()) {
  128. memo = 'luckdraw'
  129. } else {
  130. memo = 'luckdraw|' + await this.$getRandom()
  131. }
  132. window.EOS.contract('eosgetadmin1').then(contract => {
  133. contract.luckdraw(this.account.name, memo, this.identity)
  134. .then(trx => {
  135. doAction({
  136. transaction_id: trx.transaction_id,
  137. block_num: trx.processed.block_num ? trx.processed.block_num : ''
  138. })
  139. })
  140. .catch(msg => {
  141. this.$hideLoading()
  142. if (msg.type === 'signature_rejected') {
  143. return
  144. }
  145. let json = JSON.parse(msg)
  146. let details = json.error.details
  147. showError(details[0].message)
  148. })
  149. })
  150. },
  151. updateTime () {
  152. if (this.ttl > 0) {
  153. let ttl = this.ttl
  154. let M = Math.floor(ttl % 3600 / 60)
  155. M = M < 10 ? '0' + M : M
  156. let S = Math.floor(ttl % 3600 % 60)
  157. S = S < 10 ? '0' + S : S
  158. this.timeStr = `${M}:${S}`
  159. this.ttl -= 1
  160. if (this.ttl === 0) {
  161. clearInterval(this.timer)
  162. }
  163. }
  164. },
  165. getLuckInfo () {
  166. API.eos.getLuckInfo({
  167. player: this.account.name
  168. }).then(({ data }) => {
  169. this.leftTimes = data.data.times
  170. this.ttl = data.data.limit // -1不能抽,0可以抽, 大于0是倒计时秒数
  171. let rewardData = data.data.reward_conf
  172. rewardData.forEach(e => {
  173. this.rewardList.push(e.formatAmount.toFixed(4))
  174. })
  175. if (this.ttl > 0) {
  176. this.timer = setInterval(() => {
  177. this.updateTime()
  178. }, 1000)
  179. }
  180. })
  181. },
  182. beforeDestroy () {
  183. if (this.timer) {
  184. clearInterval(this.timer)
  185. }
  186. }
  187. },
  188. async created () {
  189. await this.$store.dispatch('doScatterLogin')
  190. this.getLuckInfo()
  191. }
  192. }
  193. </script>
  194. <style lang="scss">
  195. .popup-wrap {
  196. &.mod-lottery{
  197. .popup-box{
  198. width: px2rem(730);
  199. }
  200. }
  201. }
  202. .lottery-wrap{
  203. color: #ffffff;
  204. .left-time{
  205. font-size: px2rem(16);
  206. text-align: center;
  207. }
  208. }
  209. .lottery-result{
  210. .num{
  211. width: px2rem(230);
  212. height: px2rem(70);
  213. font-size: px2rem(18);
  214. line-height: px2rem(70);
  215. margin: 0 auto;
  216. background-color: #394d80;
  217. font-weight: bold;
  218. margin: px2rem(20) auto px2rem(30);
  219. }
  220. }
  221. .lottery-fair{
  222. text-align: center;
  223. font-size: px2rem(14);
  224. margin-bottom: px2rem(8);
  225. font-weight: bold;
  226. .fair-num{
  227. display: inline-block;
  228. margin: 0 px2rem(6);
  229. width: px2rem(80);
  230. text-align: left;
  231. text-decoration: none;
  232. color: #ffffff;
  233. }
  234. .hash{
  235. display: inline-block;
  236. width: px2rem(320);
  237. text-align: left;
  238. text-decoration: none;
  239. color: #ffffff;
  240. .yellow{
  241. color: #ffeb00;
  242. font-weight: bold;
  243. }
  244. }
  245. .title{
  246. display: inline-block;
  247. width: px2rem(60);
  248. text-align: left;
  249. }
  250. }
  251. .lottery-tips{
  252. font-size: px2rem(14);
  253. line-height: 1.4;
  254. font-weight: bold;
  255. margin: px2rem(30) 0 px2rem(20);
  256. }
  257. .lottery-wheel{
  258. width: px2rem(504);
  259. height: px2rem(504);
  260. margin: px2rem(12) auto;
  261. position: relative;
  262. .rotate-box{
  263. position: absolute;
  264. top: 0;
  265. left: 0;
  266. width: 100%;
  267. height: 100%;
  268. &:nth-child(2) {
  269. .wheel-item{
  270. transform: rotate(60deg);
  271. }
  272. }
  273. &:nth-child(3) {
  274. .wheel-item{
  275. transform: rotate(120deg);
  276. }
  277. }
  278. &:nth-child(4) {
  279. .wheel-item{
  280. transform: rotate(180deg);
  281. }
  282. }
  283. &:nth-child(5) {
  284. .wheel-item{
  285. transform: rotate(240deg);
  286. }
  287. }
  288. &:nth-child(6) {
  289. .wheel-item{
  290. transform: rotate(300deg);
  291. }
  292. }
  293. }
  294. .wheel{
  295. position: absolute;
  296. background: url('./img/wheel.png') no-repeat;
  297. width: px2rem(504);
  298. height: px2rem(504);
  299. background-size: 100%;
  300. transition: transform 3s ease;
  301. }
  302. .lottery-btn{
  303. position: absolute;
  304. top: 50%;
  305. left: 50%;
  306. width: px2rem(135);
  307. height: px2rem(154);
  308. box-sizing: border-box;
  309. padding-top: px2rem(70);
  310. margin-top: -px2rem(77);
  311. margin-left: -px2rem(135 / 2);
  312. background: url('./img/lottery-btn.png') no-repeat;
  313. background-size: 100%;
  314. text-align: center;
  315. color: #ffffff;
  316. font-size: px2rem(36);
  317. cursor: pointer;
  318. transition: all .3s ease-in-out;
  319. &:hover{
  320. background: url('./img/lottery-btn-hover.png') no-repeat;
  321. background-size: 100%;
  322. }
  323. &.disabled{
  324. background: url('./img/lottery-btn-disabled.png') no-repeat;
  325. background-size: 100%;
  326. cursor: default;
  327. }
  328. &.time-count-down{
  329. font-size: px2rem(28);
  330. padding-top: px2rem(74);
  331. }
  332. }
  333. .lottery-btn-small{
  334. font-size: px2rem(24);
  335. }
  336. .wheel-item{
  337. text-align: center;
  338. width: px2rem(100);
  339. margin: 0 auto;
  340. text-align: center;
  341. padding-top: px2rem(86);
  342. transform-origin: 50% px2rem(504/2);
  343. .amount{
  344. display: block;
  345. font-weight: bold;
  346. font-size: px2rem(24);
  347. color: #df951f;
  348. }
  349. }
  350. }
  351. .gold-eos-icon{
  352. background: url('./img/gold-eos-icon.png') no-repeat;
  353. background-size: 100%;
  354. display: block;
  355. width: px2rem(22);
  356. margin: px2rem(6) auto;
  357. height: px2rem(32);
  358. }
  359. </style>