更新购买流程
This commit is contained in:
parent
d918e9d580
commit
058c5e8703
@ -1,4 +1,4 @@
|
||||
VUE_APP_WALLET_INFURAID='e7743d46923911fa8850619b7a7f6d9d'
|
||||
VUE_APP_CHAIN_ID=97
|
||||
VUE_APP_CHAIN_RPC='https://data-seed-prebsc-1-s1.binance.org:8545/'
|
||||
VUE_APP_BASE_API='https://game2006api-test.kingsome.cn'
|
||||
VUE_APP_CHAIN_ID=1338
|
||||
VUE_APP_CHAIN_RPC='http://192.168.100.22:8545'
|
||||
VUE_APP_BASE_API='http://game2006api-test.kingsome.cn'
|
||||
|
@ -1,4 +1,4 @@
|
||||
VUE_APP_WALLET_INFURAID='e7743d46923911fa8850619b7a7f6d9d'
|
||||
VUE_APP_CHAIN_ID=97
|
||||
VUE_APP_CHAIN_RPC='https://data-seed-prebsc-1-s1.binance.org:8545/'
|
||||
VUE_APP_CHAIN_RPC='https://data-seed-prebsc-1-s1.binance.org:8545'
|
||||
VUE_APP_BASE_API='https://game2006api.kingsome.cn'
|
||||
|
@ -23,6 +23,13 @@ export const searchBox = (data: any) =>
|
||||
params: data
|
||||
})
|
||||
|
||||
export const queryPresaleStatus = (data: any) =>
|
||||
request({
|
||||
url: '/webapp/index.php?c=Market&a=getPreSaleInfo',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
|
||||
export const getNftList = (data: any) =>
|
||||
request({
|
||||
url: '/webapp/index.php?c=Market&a=getNftList',
|
||||
@ -43,3 +50,10 @@ export const buyBox = (data: any) =>
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
|
||||
export const queryOrder = (data: any) =>
|
||||
request({
|
||||
url: '/webapp/index.php?c=Market&a=queryOrder',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
|
@ -24,11 +24,11 @@
|
||||
<li data-menuanchor="chip" @click="changeSection" :class="{'active': currentSection === 'chip'}">
|
||||
<a href="#chip_section">Chip</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="mynft" v-if="accountId">Mine</a>
|
||||
<li v-if="accountId">
|
||||
<a href="mynft" >Mine</a>
|
||||
</li>
|
||||
<li data-menuanchor="market" @click.stop="comingSoon">
|
||||
<a href="javascipt:void(0)">MARKETPLACE</a>
|
||||
<a href="javascript:void(0)">MARKETPLACE</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -49,11 +49,17 @@
|
||||
<li data-menuanchor="chip" @click="changeSection" :class="{'active': currentSection === 'chip'}">
|
||||
<a href="#chip_section">CHIP</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="mynft" v-if="accountId">Mine</a>
|
||||
<li v-if="accountId">
|
||||
<a href="mynft" >Mine</a>
|
||||
</li>
|
||||
<li data-menuanchor="market" @click.stop="comingSoon">
|
||||
<a href="javascipt:void(0)">MARKETPLACE</a>
|
||||
<a href="javascript:void(0)">MARKETPLACE</a>
|
||||
</li>
|
||||
<li v-if="accountId" @click.stop="disconnectWallet">
|
||||
<a href="javascript:void(0)" >Logout</a>
|
||||
</li>
|
||||
<li v-if="!accountId">
|
||||
<a href="javascript:void(0)" >Connect Wallet</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -64,6 +70,7 @@
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import { Message } from 'element-ui'
|
||||
import { AppModule } from '@/store/modules/app'
|
||||
import { BlockChain } from '@/utils/blockchain'
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
@ -79,6 +86,8 @@ declare module 'vue/types/vue' {
|
||||
})
|
||||
export default class extends Vue {
|
||||
private dropShow = false
|
||||
bc = new BlockChain();
|
||||
|
||||
changeSection(e: PointerEvent) {
|
||||
this.dropShow = false
|
||||
const target = e.currentTarget as HTMLElement
|
||||
@ -87,6 +96,10 @@ export default class extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
async disconnectWallet() {
|
||||
return this.bc.disconnect()
|
||||
}
|
||||
|
||||
toggleDrop() {
|
||||
this.dropShow = !this.dropShow
|
||||
}
|
||||
@ -198,6 +211,9 @@ export default class extends Vue {
|
||||
.menu_fullpage{
|
||||
display: none;
|
||||
}
|
||||
.menu-list {
|
||||
padding-right: 10px;
|
||||
}
|
||||
.menu_drop {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
|
@ -14,11 +14,15 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import { Component, Vue, Watch } from 'vue-property-decorator'
|
||||
import CardScroller from '@/components/main/CardScroller.vue'
|
||||
import { searchBox } from '@/api/Mall'
|
||||
import { queryOrder, queryPresaleStatus, searchBox } from '@/api/Mall'
|
||||
import { ISpineData } from '@/utils/SpineRender'
|
||||
import { AppModule } from '@/store/modules/app'
|
||||
import { secs2str } from '@/utils/time.util'
|
||||
import { EventBus, PRESALE_BEGIN, PRESALE_ERROR, PRESALE_ORDER_GET, PRESALE_SUCCESS } from '@/utils/event-bus'
|
||||
import { Loading } from 'element-ui'
|
||||
import { ElLoadingComponent } from 'element-ui/types/loading'
|
||||
|
||||
@Component({
|
||||
name: 'NftSection',
|
||||
@ -34,55 +38,178 @@ export default class extends Vue {
|
||||
presaleStatus = 0
|
||||
numberTotal = 0
|
||||
numberRest = 0
|
||||
buyed = false
|
||||
timeStr = '20:59:59'
|
||||
buyed = true
|
||||
timeStr = ''
|
||||
countdown = 0
|
||||
timer: any = null
|
||||
orderTimer: any = null
|
||||
loadingInstance: ElLoadingComponent
|
||||
created() {
|
||||
this.fetchData()
|
||||
this.subscribeToEvents()
|
||||
}
|
||||
|
||||
unmounted() {
|
||||
this.removeEvents()
|
||||
}
|
||||
|
||||
@Watch('accountId')
|
||||
private accountChange() {
|
||||
if (this.accountId) {
|
||||
this.getPresaleInfo()
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('countdown')
|
||||
private countDownChange() {
|
||||
this.timeStr = secs2str(this.countdown)
|
||||
}
|
||||
|
||||
get accountId() {
|
||||
return AppModule.accountId
|
||||
}
|
||||
|
||||
async fetchData() {
|
||||
await this.queryPresale()
|
||||
await this.queryPresaleList()
|
||||
}
|
||||
|
||||
async queryPresale() {
|
||||
const res: any = await searchBox({ account: '', page: 0 })
|
||||
console.log(res)
|
||||
if (!res.errcode) {
|
||||
this.heroDatas.length = 0
|
||||
if (res.presale_info) {
|
||||
this.numberTotal = res.presale_info.total_num || 0
|
||||
this.numberRest = this.numberTotal - (res.presale_info.sold_num || 0)
|
||||
this.numberRest = this.numberRest < 0 ? 0 : this.numberRest
|
||||
this.hint = res.presale_info.hint.replace(/\\n/g, '<br/>')
|
||||
this.buyed = !!res.presale_info.buyed
|
||||
this.presaleStatus = res.presale_info.state || 0
|
||||
this.presaleTitle = res.presale_info.title
|
||||
AppModule.updateCanBuy(this.presaleStatus === 2 &&
|
||||
this.numberRest > 0 &&
|
||||
!this.buyed
|
||||
)
|
||||
subscribeToEvents() {
|
||||
EventBus.$on(PRESALE_BEGIN, this.onPresaleBegin.bind(this))
|
||||
EventBus.$on(PRESALE_SUCCESS, this.onPresaleSuccess.bind(this))
|
||||
EventBus.$on(PRESALE_ERROR, this.onPresaleError.bind(this))
|
||||
EventBus.$on(PRESALE_ORDER_GET, this.onOrderIDGeted.bind(this))
|
||||
}
|
||||
|
||||
removeEvents() {
|
||||
EventBus.$off(PRESALE_BEGIN, this.onPresaleBegin.bind(this))
|
||||
EventBus.$off(PRESALE_SUCCESS, this.onPresaleSuccess)
|
||||
EventBus.$off(PRESALE_ERROR, this.onPresaleError)
|
||||
EventBus.$off(PRESALE_ORDER_GET, this.onOrderIDGeted.bind(this))
|
||||
}
|
||||
|
||||
onPresaleBegin() {
|
||||
this.loadingInstance = Loading.service({})
|
||||
console.log('presale begin')
|
||||
}
|
||||
|
||||
onOrderIDGeted(orderId: string) {
|
||||
console.log('order id:', orderId)
|
||||
this.beginTraceOrderStatus(orderId)
|
||||
}
|
||||
|
||||
onPresaleError(res: any) {
|
||||
console.log('presale error: ', res)
|
||||
this.loadingInstance.close()
|
||||
this.$alert('Some error when process presale', 'Buy Failed', { type: 'error', confirmButtonText: 'OK' })
|
||||
}
|
||||
|
||||
async onPresaleSuccess(res: any) {
|
||||
console.log('presale success', res)
|
||||
this.resetTmpOrderId()
|
||||
this.$alert('Congratulations', 'Buy Success', { type: 'success', confirmButtonText: 'OK' })
|
||||
await this.getPresaleInfo()
|
||||
}
|
||||
|
||||
beginTraceOrderStatus(orderId: string) {
|
||||
this.orderTimer = setInterval(() => {
|
||||
this.getOrderStatus(orderId)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
resetTmpOrderId() {
|
||||
if (this.orderTimer !== null) {
|
||||
clearInterval(this.orderTimer)
|
||||
this.orderTimer = null
|
||||
}
|
||||
localStorage.removeItem('tmp_presale_order_id')
|
||||
this.loadingInstance.close()
|
||||
}
|
||||
|
||||
async getOrderStatus(orderId: string) {
|
||||
try {
|
||||
const res: any = await queryOrder({ account: this.accountId, order_id: orderId })
|
||||
if (res.status === 1) {
|
||||
EventBus.$emit(PRESALE_SUCCESS, {})
|
||||
} else if (res.status === 3) {
|
||||
EventBus.$emit(PRESALE_ERROR, {})
|
||||
this.resetTmpOrderId()
|
||||
} else if (res.status === 0) {
|
||||
EventBus.$emit(PRESALE_ERROR, {})
|
||||
this.resetTmpOrderId()
|
||||
}
|
||||
for (const data of res.rows) {
|
||||
const heroData: any = {
|
||||
name: data.name,
|
||||
class: (data.job + '').toLowerCase(),
|
||||
recordId: data.box_id,
|
||||
id: data.box_id,
|
||||
skelName: `n_${data.name.toLowerCase()}`,
|
||||
directBuy: true,
|
||||
stopBuy: this.buyed,
|
||||
showBuy: true
|
||||
}
|
||||
if (data.currency_list && data.currency_list.length > 0) {
|
||||
const priceData: any = data.currency_list[0]
|
||||
heroData.discount = priceData.discount_rate
|
||||
heroData.price = priceData.original_price
|
||||
heroData.priceDiscount = priceData.discount_price
|
||||
heroData.currency = priceData.name
|
||||
heroData.coinAddress = priceData.contract_address
|
||||
}
|
||||
this.heroDatas.push(heroData)
|
||||
} catch (err) {
|
||||
console.log('query order status error', err)
|
||||
}
|
||||
}
|
||||
|
||||
beginCountdown() {
|
||||
this.clearTimer()
|
||||
this.timer = setInterval(() => {
|
||||
if (this.countdown <= 0) {
|
||||
this.clearTimer()
|
||||
} else {
|
||||
this.countdown--
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
clearTimer() {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
|
||||
async getPresaleInfo() {
|
||||
const res: any = await queryPresaleStatus({ account: this.accountId })
|
||||
if (res.presale_info) {
|
||||
this.numberTotal = res.presale_info.total_num || 0
|
||||
this.numberRest = this.numberTotal - (res.presale_info.sold_num || 0)
|
||||
this.numberRest = this.numberRest < 0 ? 0 : this.numberRest
|
||||
this.hint = res.presale_info.hint.replace(/\\n/g, '<br/>')
|
||||
this.buyed = !!res.presale_info.buyed
|
||||
this.presaleStatus = res.presale_info.state || 0
|
||||
this.presaleTitle = res.presale_info.title
|
||||
this.countdown = res.presale_info.countdown
|
||||
if (this.presaleStatus === 2 && this.countdown > 0) {
|
||||
this.beginCountdown()
|
||||
}
|
||||
AppModule.updateCanBuy(this.presaleStatus === 2 &&
|
||||
this.numberRest > 0 &&
|
||||
!this.buyed
|
||||
)
|
||||
for (const data of this.heroDatas) {
|
||||
Vue.set(data, 'stopBuy', this.buyed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async queryPresaleList() {
|
||||
const reqData = {
|
||||
account: '',
|
||||
page: 0
|
||||
}
|
||||
const res: any = await searchBox(reqData)
|
||||
this.heroDatas.length = 0
|
||||
|
||||
for (const data of res.rows) {
|
||||
const heroData: any = {
|
||||
name: data.name,
|
||||
class: (data.job + '').toLowerCase(),
|
||||
recordId: data.box_id,
|
||||
id: data.box_id,
|
||||
skelName: `n_${data.name.toLowerCase()}`,
|
||||
directBuy: true,
|
||||
stopBuy: this.buyed,
|
||||
showBuy: true
|
||||
}
|
||||
if (data.currency_list && data.currency_list.length > 0) {
|
||||
const priceData: any = data.currency_list[0]
|
||||
heroData.discount = priceData.discount_rate
|
||||
heroData.price = priceData.original_price
|
||||
heroData.priceDiscount = priceData.discount_price
|
||||
heroData.currency = priceData.name
|
||||
heroData.coinAddress = priceData.contract_address
|
||||
}
|
||||
this.heroDatas.push(heroData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import { BlockChain } from '@/utils/blockchain'
|
||||
import { AppModule } from '@/store/modules/app'
|
||||
import { buyBox } from '@/api/Mall'
|
||||
import { Message } from 'element-ui'
|
||||
import { EventBus, PRESALE_BEGIN, PRESALE_ERROR, PRESALE_ORDER_GET, PRESALE_SUCCESS } from '@/utils/event-bus'
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
@ -60,26 +61,34 @@ export default class extends Vue {
|
||||
if (this.data.stopBuy) {
|
||||
return
|
||||
}
|
||||
EventBus.$emit(PRESALE_BEGIN)
|
||||
if (!this.walletCollected) {
|
||||
await this.bc.connect()
|
||||
}
|
||||
const account = AppModule.accountId
|
||||
const { nonce, signature } = await this.bc.signPresale({
|
||||
type: this.data.recordId!,
|
||||
paymentTokenAddress: this.data.coinAddress!,
|
||||
price: this.data.priceDiscount!,
|
||||
buyerAddress: account
|
||||
})
|
||||
const buyData = {
|
||||
buyer_address: AppModule.accountId,
|
||||
type: this.data.recordId,
|
||||
price: this.data.priceDiscount,
|
||||
payment_token_address: this.data.coinAddress,
|
||||
nonce,
|
||||
signature
|
||||
try {
|
||||
const { nonce, signature } = await this.bc.signPresale({
|
||||
type: this.data.recordId!,
|
||||
paymentTokenAddress: this.data.coinAddress!,
|
||||
price: this.data.priceDiscount!,
|
||||
buyerAddress: account
|
||||
})
|
||||
const buyData = {
|
||||
buyer_address: AppModule.accountId,
|
||||
type: this.data.recordId,
|
||||
price: this.data.priceDiscount,
|
||||
payment_token_address: this.data.coinAddress,
|
||||
nonce,
|
||||
signature
|
||||
}
|
||||
const res: any = await buyBox(buyData)
|
||||
const orderId = res.order_id
|
||||
localStorage.setItem('tmp_presale_order_id', orderId)
|
||||
EventBus.$emit(PRESALE_ORDER_GET, orderId)
|
||||
} catch (err) {
|
||||
console.log('buy error: ', err)
|
||||
EventBus.$emit(PRESALE_ERROR, err)
|
||||
}
|
||||
const res = await buyBox(buyData)
|
||||
console.log('buy nft: ', res)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -237,6 +237,7 @@ export default class extends Vue {
|
||||
background-image: url('../../assets/main/p1/btn_bg.png');
|
||||
background-repeat: repeat-x;
|
||||
background-position: 0 17px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
|
||||
|
@ -98,9 +98,12 @@ export class BlockChain {
|
||||
price: number
|
||||
buyerAddress: string
|
||||
}) {
|
||||
const nonce = Math.random() * 1000 | 0
|
||||
const nonce = Math.random() * 100000 | 0
|
||||
const signStr: string = this.web3.utils.soliditySha3(type, paymentTokenAddress, price, nonce)!
|
||||
let signature = await this.web3.eth.sign(signStr, buyerAddress)
|
||||
const signStr2 = this.web3.eth.accounts.hashMessage(signStr)
|
||||
let signature = await this.web3.eth.sign(signStr2, buyerAddress)
|
||||
// console.log(paymentTokenAddress, type, nonce, price, signature)
|
||||
// const whoSigned1 = await this.web3.eth.accounts.recover(signStr2, signature, true)
|
||||
signature = signature.replace(/00$/, '1b').replace(/01$/, '1c')
|
||||
return { nonce, signature }
|
||||
}
|
||||
|
10
src/utils/event-bus.ts
Normal file
10
src/utils/event-bus.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import Vue from 'vue'
|
||||
export const EventBus = new Vue()
|
||||
|
||||
export const PRESALE_BEGIN = 'presale_begin'
|
||||
|
||||
export const PRESALE_ORDER_GET = 'presale_order_get'
|
||||
|
||||
export const PRESALE_SUCCESS = 'presale_success'
|
||||
|
||||
export const PRESALE_ERROR = 'presale_error'
|
@ -54,7 +54,7 @@ service.interceptors.response.use(
|
||||
location.reload() // To prevent bugs from vue-router
|
||||
})
|
||||
}
|
||||
return Promise.reject(new Error(res.msg || 'Error'))
|
||||
return Promise.reject(new Error(res.errmsg || 'Error'))
|
||||
} else {
|
||||
return response.data
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user