OSDN Git Service

d7877ee7a10e07d051b086f7938a6116842f5282
[bytom/Byone.git] / src / views / sendTransaction / crossChainTransaction.vue
1 <style lang="" scoped>
2 .header {
3   display: flex;
4 }
5 .header p{
6   text-align: center;
7   width: 270px;
8   padding-top: 17px;
9 }
10 .transferType {
11   /*width: 280px;*/
12   /*height: 40px;*/
13     margin: 20px;
14   display: flex;
15 }
16
17 .transferType input[type=radio] {
18   position: absolute;
19   visibility: hidden;
20 }
21
22 .transferType input[type="radio"]:checked+label{
23   color:white;
24   background: linear-gradient(90deg, #227AF1 100%, #035BD4 0%);;
25 }
26 .transferType input[type="radio"]:checked+label .cross-icon{
27   background-image: url('../../assets/img/icon/crosschain-toV.svg');
28 }
29
30 .transferType div:last-child input[type="radio"]:checked+label{
31   color:white;
32   background: linear-gradient(91deg, #4B4B4B 0.27%, #1C1C1C 99.68%);
33 }
34
35 .transferType div:last-child input[type="radio"]:checked+label .cross-icon{
36   background-image: url('../../assets/img/icon/crosschain-toB.svg');
37 }
38
39 .transferType div:last-child .choice{
40   border-radius: 0px 40px 40px 0px;
41
42 }
43 .choice {
44   cursor: pointer;
45   padding: 10px;
46   font-size: 12px;
47   white-space: pre-wrap;
48   display: flex;
49   width: 140px;
50   background: rgba(0, 0, 0, 0.04);
51   border-radius: 40px 0px 0px 40px;
52 }
53
54 .choice:hover {
55      background-color: #f7f7f7;
56    }
57
58 .form-container{
59   margin: 20px;
60 }
61 .form {
62     margin-bottom: 20px;
63     padding: 10px 15px;
64     border-radius:4px;
65 }
66 .form-container .btn{
67     height: 48px;
68     bottom: 20px;
69     position: absolute;
70     width: 320px;
71 }
72   .small{
73     font-size: 12px;
74   }
75 .wallet{
76   width: 40px;
77   height: 40px;
78   background: rgba(255,255,255,0.1);
79   border-radius: 50%;
80   color: white;
81   margin-right: 20px;
82   line-height: 40px;
83   text-align: center;
84 }
85
86 .asset-option{
87   font-size: 15px;
88   text-transform: uppercase;
89 }
90
91 .asset-option  .asset-id{
92   font-size: 13px;
93 }
94
95 .v-select{
96   height: 50px;
97   width: 100%;
98   background: rgba(247,247,247,1);
99   font-size: 14px;
100   margin: auto;
101   border-bottom: 1px solid #E0E0E0;
102 }
103
104   .cross-icon{
105     background-image: url('../../assets/img/icon/crosschain-default.svg');
106     height:40px;
107     width:40px;
108     margin:auto 12px;
109   }
110   .separator{
111     height: 12px;
112   }
113 </style>
114
115 <template>
116     <div class="warp-chlid bg-white">
117         <section class="header bg-header">
118             <i class="iconfont icon-back" @click="close"></i>
119             <p>{{ $t('crossChain.title') }}</p>
120         </section>
121
122         <section class="transferType">
123           <div>
124             <input type="radio" id="typeChoice1"
125                    value="toVapor" v-model="transaction.type">
126             <label class="choice" for="typeChoice1"> <div class="cross-icon"></div><div>{{$t('crossChain.toVapor')}}</div></label>
127
128           </div>
129           <div>
130             <input type="radio" id="typeChoice2"
131                    value="toBytom" v-model="transaction.type">
132             <label class="choice" for="typeChoice2"><div class="cross-icon"></div><div>{{$t('crossChain.toBytom')}}</div></label>
133
134           </div>
135         </section>
136
137         <section class="form-container">
138               <div class="form-item">
139                 <label class="form-item-label">{{ $t('crossChain.asset') }}</label>
140                 <div class="form-item-content" >
141                   <v-select :options="assets" v-bind:colorBlack="true" :clearable="false" :value="selectAsset" :onChange="assetChange" label="asset">
142                     <template slot="selected-option" slot-scope="asset">
143                       <div class="asset-option">
144                         <div>{{asset.symbol || 'Asset'}}</div>
145                         <div  class="color-grey asset-id">{{shortAddress(asset.asset)}}</div>
146                       </div>
147                     </template>
148                     <template slot="option" slot-scope="asset">
149                       <div class="asset-option">
150                         <div>{{asset.symbol || 'Asset'}}</div>
151                         <div class="color-grey  asset-id">{{shortAddress(asset.asset)}}</div>
152                       </div>
153                     </template>
154                   </v-select>
155                 </div>
156               </div>
157         </section>
158
159         <div class="separator bg-gray"></div>
160         <section class="form-container">
161           <div class="">
162               <div class="form-item">
163                   <label class="form-item-label">
164                     {{ $t('transfer.quantity') }}
165
166                     <small class="float-right" style="margin-right: 8px;">{{formatCurrency(transaction.cost||0) }}</small>
167                   </label>
168                   <div class="form-item-content" style=" display: flex;">
169                       <input type="number" v-model="transaction.amount" :placeholder="bytomBalance">
170                       <span class="color-grey" style="width: 40px; font-size: 15px;position: absolute;right: 0;">{{unit}}</span>
171                   </div>
172                   <p class="small color-grey">{{$t('crossChain.amountHint')}}</p>
173               </div>
174           </div>
175           <a class="btn btn-primary" @click="send">{{ $t('transfer.send') }}</a>
176         </section>
177     </div>
178 </template>
179
180 <script>
181   import address from "@/utils/address";
182   import account from "@/models/account";
183 import transaction from "@/models/transaction";
184 import getLang from "@/assets/language/sdk";
185 import Confirm from "./transferConfirm";
186 import { BTM } from "@/utils/constants";
187 import { mapActions, mapGetters, mapState } from 'vuex'
188 import { Number as Num } from "@/utils/Number"
189   import _ from 'lodash';
190
191   const currencyInPrice = {
192   inCny: 'cny_price',
193   inUsd: 'usd_price',
194   inBtc:'btc_price'
195 }
196
197 export default {
198     components: {
199         Confirm
200     },
201     data() {
202         return {
203           selectAsset: {
204             asset: BTM,
205             symbol: "BTM",
206             decimals:8
207           },
208             show: false,
209             guid: null,
210             account: {},
211             accountBalance: 0.00,
212             fee: this.$t("transfer.feeType"),
213             feeTypeOptions: [this.$t("transfer.feeType")],
214             transaction: {
215                 type:'toVapor',
216                 asset: BTM,
217                 fee: 0,
218                 amount: "",
219                 to:'',
220                 confirmations: 1
221             }
222         };
223     },
224     computed: {
225       assets(){
226         if(this.transaction.type === 'toVapor'){
227           return this.currentAccount.balances
228         }else{
229           return this.currentAccount.vpBalances
230         }
231       },
232         unit() {
233           return this.selectAsset.symbol;
234         },
235       bytomBalance: function () {
236         let balance, balances
237         if(this.transaction.type === 'toVapor'){
238           balances = this.currentAccount.balances
239         }else if(this.transaction.type === 'toBytom') {
240           balances = this.currentAccount.vpBalances
241         }
242
243         if(balances && balances.length >0 ){
244           if( this.selectAsset.asset === BTM && this.transaction.type === 'toBytom' ){
245             const balanceObject = balances.filter(b => b.asset === BTM)[0]
246             balance = balanceObject.balance
247
248             let vote = 0, lock = 0
249
250             const votes = this.currentAccount.votes
251
252             if (votes && votes.length > 0) {
253               vote = _.sumBy(votes, 'total')
254               lock = _.sumBy(votes, 'locked')
255             }
256
257             balance = Num.formatNue((balance - vote - lock), balanceObject.decimals)
258           }else{
259
260             const balanceObject = balances.filter(b => b.asset === this.selectAsset.asset)[0]
261             balance = Num.formatNue(balanceObject.balance, balanceObject.decimals)
262           }
263
264         }
265
266         if(this.transaction.type === 'toVapor'){
267           return `Bytom${this.$t("crossChain.amountPlaceHolder")}${(balance != null && balance != 0) ? balance : '0.00'}`
268         }else{
269           return `Vapor${this.$t("crossChain.amountPlaceHolder")}${(balance != null && balance != 0) ? balance : '0.00'}`
270         }
271       },
272       ...mapState([
273         'bytom'
274       ]),
275       ...mapGetters([
276         'currentAccount',
277         'accountList',
278         'net',
279         'netType',
280         'currency'
281       ])
282     },
283     watch: {
284         "transaction.amount": function (newAmount) {
285           this.transaction.cost = Number(this.selectAsset[currencyInPrice[this.currency]] * newAmount).toFixed(2);
286         },
287         account: function (newAccount) {
288             this.guid = newAccount.guid;
289         },
290         guid: function (newGuid) {
291             this.accountList.forEach(account => {
292                 if (account.guid == newGuid.guid) {
293                     this.account = account;
294                     return;
295                 }
296             });
297
298             account.balance(newGuid).then(balances => {
299               let balance = 0.00
300               if(balances.length >0 ) {
301                 const balanceObject = balances.filter(b => b.asset === BTM)[0]
302                 balance = balanceObject.balance / Math.pow(10, balanceObject.decimals)
303               }
304                 this.accountBalance = balance;
305             }).catch(error => {
306                 console.log(error);
307             });
308         }
309     },
310     methods: {
311         shortAddress: function (add) {
312           return address.short(add)
313         },
314         close: function () {
315             this.$router.go(-1)
316             this.transaction.to = "";
317             this.transaction.amount = "";
318             account.setupNet(`${this.net}${this.netType}`);
319             if(this.$route.query.type == 'popup'){
320                window.close();
321             }
322         },
323         formatCurrency: function (num) {
324           return Num.formatCurrency(num, this.currency)
325         },
326         assetChange: function (val) {
327           if(val.asset !== this.selectAsset.asset){
328             this.transaction.asset = val.asset;
329             const balances = this.currentAccount.balances
330             let balance = 0.00
331             if(balances.length >0 ) {
332               const balanceObject = balances.filter(b => b.asset === val.asset)[0]
333               balance = Num.formatNue(balanceObject.balance, balanceObject.decimals)
334             }
335             this.accountBalance = balance;
336             transaction.asset(val.asset).then(ret => {
337               this.selectAsset = Object.assign(ret,val)
338               this.transaction.cost = Number(ret[currencyInPrice[this.currency]] * this.transaction.amount).toFixed(2);
339             });
340           }
341         },
342         send: function () {
343             if (this.transaction.amount <= 0) {
344                 this.$dialog.show({
345                     body: this.$t("transfer.noneBTM")
346                 });
347                 return;
348             }
349
350             let loader = this.$loading.show({
351                 // Optional parameters
352                 container: null,
353                 canCancel: true,
354                 onCancel: this.onCancel
355             });
356
357             // Bytom => Vapor
358             if(this.transaction.type === 'toVapor'){
359               transaction.chainStatus().then((resp)=>{
360                 const address = resp.federation_address
361                 account.setupNet(`${this.net}`)
362                 this.transaction.to = address
363                 transaction.build(this.account.guid, address, this.transaction.asset, Num.convertToNue(this.transaction.amount,this.selectAsset.decimals), this.transaction.confirmations).then(result => {
364                   loader.hide();
365                   if(!this.transaction.fee){
366                     this.transaction.fee = Number( _.sumBy(result, 'fee'));
367                   }
368                   this.$router.push({ name: 'transfer-confirm', params: { account: this.account, transaction: this.transaction, rawData: result,assetAlias: this.selectAsset.symbol, type: this.$route.query.type } })
369                 }).catch(error => {
370                   loader.hide();
371                   this.$dialog.show({
372                     body: getLang(error.message)
373                   });
374                 });
375               })
376             }
377
378             // Vapor => Bytom
379             else{
380               const address = this.account.address
381               account.setupNet(`${this.net}vapor`)
382               this.transaction.to = address
383               transaction.buildCrossChain(this.account.guid, address, this.transaction.asset,  Num.convertToNue(this.transaction.amount,this.selectAsset.decimals), this.transaction.confirmations).then(result => {
384                   loader.hide();
385                 if(!this.transaction.fee){
386                   this.transaction.fee = Number( _.sumBy(result, 'fee') / 100000000);
387                 }
388                 this.$router.push({ name: 'transfer-confirm', params: { account: this.account, transaction: this.transaction, rawData: result, assetAlias: this.selectAsset.symbol, type: this.$route.query.type } })
389               }).catch(error => {
390                   loader.hide();
391                   this.$dialog.show({
392                       body: getLang(error.message)
393                   });
394               });
395             }
396
397         }
398     }, mounted() {
399         //detect injection
400         if(this.$route.query.type === 'popup'){
401           if (this.$route.query.from != undefined) {
402               this.guid = this.$route.query.from
403               this.account = this.accountList.filter(e => e.guid === this.guid)[0]
404           }
405
406           if (this.$route.query.asset != undefined) {
407               this.transaction.asset= this.$route.query.asset
408           }
409           if (this.$route.query.to != undefined) {
410               this.transaction.to = this.$route.query.to
411           }
412           if (this.$route.query.amount != undefined) {
413               this.transaction.amount = this.$route.query.amount
414           }
415           if (this.$route.query.gas != undefined) {
416               this.transaction.fee = this.$route.query.gas
417           }
418           if(this.$route.query.confirmations != undefined) {
419               this.transaction.confirmations = this.$route.query.confirmations
420           }
421         }else{
422           this.account = this.currentAccount
423         }
424
425       const currentAsset = this.currentAccount.balances[0]
426
427       if(currentAsset){
428         transaction.asset(currentAsset.asset).then(ret => {
429           this.selectAsset = Object.assign(ret,currentAsset)
430         });
431       }
432     }
433 };
434 </script>