Files
li 6b02df55ab feat: contract account tab, full i18n, male avatar, PC home stretch
- Asset page: add Contract account row + tab, show num_lh balance
- Total Assets = Spot + Contract + Fiat
- All Chinese text eliminated (z-paging, loadmore, colorui, pages)
- Password/payword pages use image captcha instead of OTP
- Home page PC: full-width stretch layout
- Register captcha input type fix, invite code lock
2026-04-05 13:05:27 +08:00

600 lines
20 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view :style="'background-color: '+theme.bg+';color: '+theme.text" style="height: 100vh;">
<!-- 头部 -->
<myNav :title="i18n.withdraw.title1" isRight righturl="/static/imgs/index/tbjl.png"
@Jump="router.push('/pages/index/withdrawalRecord')"></myNav>
<!-- 身体 -->
<view class="width-750 padding-t-10 padding-b-40 padding-w-30">
<!-- 币种 -->
<!-- <view @click="show=true"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text"
class="width-100b height-96 radiu-20 padding-w-32 flex align-center justify-between">
<text class="font-28 weight-bold">{{i18n.withdraw.text1}}</text>
<view class="flex align-center">
<text class="font-28 numbold-font color-0165EE">{{curr}}</text>
<u-icon name="arrow-right" color="#0165EE" size="28"></u-icon>
</view>
</view> -->
<view style="background-color: rgba(255,255,255,0);"
class="width-100b height-96 radiu-20 padding-w-32 flex align-center justify-center">
<view @click="current=1" class="width-150 height-78 radiu-20 text-center line-height-78"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<text :class="current==1?'color-0165EE':''" class="font-28">{{i18n.fastRecord.tos2}}</text>
</view>
<!-- <view @click="current=2" class="width-150 height-78 radiu-20 text-center line-height-78"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<text :class="current==2?'color-0165EE':''" class="font-28">{{i18n.fastRecord.text9}}</text>
</view> -->
</view>
<view v-if="current==2" :style="'background-color: '+theme.fu_bg+';color: '+theme.text"
class="width-100b radiu-20 padding-w-32 margin-t-20">
<view class="height-80 flex align-center justify-between">
<text v-if="bank" @click="bankshow=true" class="flex-1 font-28 weight-bold">{{bank.bank_name}}({{bank.username}})</text>
<text v-else @click="router.push('/pages/my/safety/payment')" class="flex-1 font-28 weight-bold">{{i18n.mine.safety.add}}</text>
<i class="cuIcon-right font-28"></i>
</view>
<view v-if="bank" class="height-70 flex align-center justify-between">
<text class="font-28 weight-bold">{{bank.card_num}}</text>
<!-- <i @click="copy(bank.card_num)" class='cuIcon-copy font-30 color-0165EE'></i> -->
</view>
</view>
<!-- 币种选择 -->
<view v-if="current==1" class="width-100b radiu-20 padding-w-32 padding-b-20 margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="height-116 padding-t-27 font-28 weight-bold">{{i18n.withdraw.text1}}</view>
<view class="flex align-center flex-wrap">
<view @click="changeCoinType(item)" v-for="(item,index) in coinTypes" :key="item.id"
:class="currid==item.id?'onbox':'offbox'" class="numbold-font margin-r-14">{{item.name}}</view>
</view>
</view>
<!-- 链类型 -->
<view v-if="current==1" class="width-100b radiu-20 padding-w-32 padding-b-20 margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="height-116 padding-t-27 font-28 weight-bold">{{i18n.withdraw.text2}}</view>
<view class="flex align-center flex-wrap">
<view @click="changelian(item,index)" v-for="(item,index) in detail"
:class="index==lian?'onbox':'offbox'" class="numbold-font margin-r-14">{{item}}</view>
</view>
</view>
<!-- 地址 -->
<view v-if="current==1"
class="width-100b height-192 radiu-20 padding-w-32 padding-c-27 flex direction-column justify-between margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.withdraw.text3}}</text>
<image @click="show1=true" class="width-32 height-32" src="/static/imgs/index/shaixuan@2x.png"
mode=""></image>
</view>
<input class="font-28" :placeholder="i18n.withdraw.tos5" type="text" v-model="address" />
</view>
<!-- 数量 -->
<view class="width-100b height-249 padding-w-32 radiu-20 margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="height-96 flex align-center font-28 weight-bold">{{i18n.withdraw.text4}}
</view>
<view class="height-153 padding-t-27 padding-b-23 flex direction-column justify-between">
<view class="flex align-center justify-between">
<input class="flex-1 padding-r-50 font-28" type="number" v-model="number"
:placeholder="i18n.withdraw.tos2" />
<view class="flex align-center">
<text class="font-28 weight-bold">{{curr}}</text>
<view class="width-2 height-23 bj-8B99A2 margin-w-10"></view>
<text @click="number=data.num"
class="font-28 color-0165EE weight-bold">{{i18n.withdraw.text5}}</text>
</view>
</view>
<text class="font-24 numbold-font">{{i18n.withdraw.text6}}{{data.num}} {{curr}}</text>
</view>
</view>
<!-- 手续费 -->
<view class="width-100b height-96 radiu-20 padding-w-32 flex align-center justify-between margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<text class="font-28 weight-bold">{{i18n.withdraw.text7}}</text>
<view v-if="current==1" class="flex align-center">
<text class="font-28 color-0165EE weight-bold">{{data.process}}</text>
<text class="font-28 numbold-font margin-l-10">{{curr}}</text>
</view>
<view v-if="current==2" class="flex align-center">
<text class="font-28 color-0165EE weight-bold">{{data.yhk_process}}</text>
<text class="font-28 numbold-font margin-l-10">{{curr}}</text>
</view>
</view>
<!-- 折合 -->
<!-- <view class="margin-t-20 padding-w-32 flex align-center font-28 color-333333">
<text>折合</text>
<text class="color-0165EE nummedium-font margin-w-5">{{data.apt_process}}</text>
<text class="nummedium-font">APT</text>
</view> -->
<!-- 提示 -->
<view class="padding-w-32 margin-t-31" v-html="data.withdraw_text"></view>
<!-- 提币按钮 -->
<view class="width-600 margin-0-auto margin-t-65">
<u-button v-if="current==1" @click="openshow1" class="custom-style" type="primary">
{{i18n.withdraw.text10}}</u-button>
<u-button v-if="current==2" @click="openshow2" class="custom-style" type="primary">
{{i18n.withdraw.text10}}</u-button>
</view>
</view>
<!-- 币种弹窗 -->
<u-popup v-model="show" mode="bottom" border-radius="20">
<view class="height-437 padding-w-30 padding-b-36"
:style="'background-color: '+theme.bg+';color: '+theme.text">
<view class="flex align-center justify-between padding-c-32">
<text class="font-28">{{i18n.withdraw.text11}}</text>
<text @click.stop="show=false" class="font-26 color-C3C3C3">{{i18n.withdraw.text12}}</text>
</view>
<view class="height-278">
<scroll-view scroll-y="true" class="height-250">
<view @click.stop="changecurr(item)" v-for="(item,index) in list"
class="height-72 padding-w-30 flex align-center margin-b-17 font-28">
{{item.name}}
</view>
</scroll-view>
</view>
</view>
</u-popup>
<!-- 银行弹窗 -->
<u-popup v-model="bankshow" mode="bottom" border-radius="20">
<view class="height-517 padding-w-30 padding-b-36"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="flex align-center justify-between padding-c-32">
<text class="font-28">{{i18n.fastRecord.text9}}</text>
<text @click.stop="bankshow=false" class="font-26 color-C3C3C3">{{i18n.recharge.text8}}</text>
</view>
<view class="height-358">
<scroll-view scroll-y="true" class="height-300">
<view @click.stop="changebank(item)" v-for="(item,index) in bankList"
class="height-72 flex align-center margin-b-17">
<text class="font-28">{{item.bank_name}}({{item.username}})</text>
</view>
</scroll-view>
</view>
</view>
</u-popup>
<!-- 地址弹窗 -->
<u-popup v-model="show1" mode="bottom" border-radius="20">
<view class="height-437 padding-w-30 padding-b-36"
:style="'background-color: '+theme.bg+';color: '+theme.text">
<view class="flex align-center justify-between padding-c-32">
<text class="font-28">{{i18n.withdraw.text3}}</text>
<text @click.stop="show1=false" class="font-26 color-C3C3C3">{{i18n.withdraw.text12}}</text>
</view>
<view class="height-278">
<scroll-view scroll-y="true" class="height-278">
<view @click="address=item.address,show1=false" v-for="(item,index) in list1" class="addressbox"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="height-70 flex align-center font-28" style="word-break: break-all;">
{{item.address}}</view>
<view class="height-30 line-height-30 font-24 color-C3C3C3">{{item.notice}}</view>
</view>
</scroll-view>
</view>
</view>
</u-popup>
<!-- 确认提币弹窗 -->
<u-popup :mask-close-able="false" v-model="show2" mode="bottom" border-radius="20">
<view class="padding-b-50 padding-w-30" :style="'background-color: '+theme.bg+';color: '+theme.text">
<!-- 标题 -->
<view class="flex align-center justify-between padding-c-32">
<text class="font-28">{{i18n.withdraw.text16}}</text>
<text @click.stop="show2=false" class="font-26 color-C3C3C3">{{i18n.withdraw.text12}}</text>
</view>
<!-- 交易密码 -->
<view
class="width-100b height-192 radiu-20 padding-w-32 padding-c-27 flex direction-column justify-between"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="font-28 weight-bold">{{i18n.withdraw.text8}}</view>
<input class="font-28" :placeholder="i18n.withdraw.tos3" type="text" v-model="paypwd" password />
</view>
<!-- 邮箱验证 -->
<!-- <view v-if="email!=''"
class="width-100b height-192 radiu-20 padding-w-32 padding-c-27 flex direction-column justify-between margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.withdraw.text17}}</text>
<text>{{email}}</text>
</view>
<view class="flex align-center justify-between">
<input class="font-28 flex-1 padding-r-24" :placeholder="i18n.withdraw.tos9" type="text"
v-model="code" />
<text @click="cutTime()" class="font-28 color-0165EE weight-bold">{{codeText}}</text>
</view>
</view> -->
<!-- 手机验证 -->
<!-- <view v-if="mobile!=''"
class="width-100b height-192 radiu-20 padding-w-32 padding-c-27 flex direction-column justify-between margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.withdraw.text18}}</text>
<text>{{mobile}}</text>
</view>
<view class="flex align-center justify-between">
<input class="font-28 flex-1 padding-r-24" :placeholder="i18n.withdraw.tos10" type="text"
v-model="code_m" />
<text @click="cutTime2()" class="font-28 color-0165EE weight-bold">{{codeText2}}</text>
</view>
</view> -->
<!-- 谷歌验证 -->
<!-- <view v-if="google" class="width-100b height-192 radiu-20 padding-w-32 padding-c-27 flex direction-column justify-between margin-t-24"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.withdraw.text19}}</text>
</view>
<view class="flex align-center justify-between">
<input class="font-28 flex-1 padding-r-24" :placeholder="i18n.withdraw.tos11" type="text"
v-model="code_g" />
</view>
</view> -->
<view class="width-600 margin-0-auto margin-t-65">
<u-button @click="getwithdraw" class="custom-style" type="primary">{{i18n.withdraw.text10}}
</u-button>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import clipboard from "@/components/clipboard.js"
export default {
data() {
return {
statusBar: uni.getSystemInfoSync().statusBarHeight,
current: 1,
list: [],
list1: [],
coinTypes: [],
lian: 0,
curr: '',
currid: '',
detail: [],
data: '',
show: false,
show1: false,
show2: false,
address: '',
number: '',
paypwd: '',
code: '',
code_m: '',
code_g: '',
flag: true,
time: 0,
timeFlag: true,
time2: 0,
timeFlag2: true,
email: '',
mobile: '',
google: false,
theme: '',
bankList: [],
bank: {},
bankshow: false
}
},
computed: {
i18n() {
return this.$t('message');
},
codeText() {
if (this.time > 0) {
return this.time + " S"
} else {
return this.i18n.withdraw.text13
}
},
codeText2() {
if (this.time2 > 0) {
return this.time2 + " S"
} else {
return this.i18n.withdraw.text13
}
}
},
onLoad(e) {
this.time = this.i18n.withdraw.text13
if (e.type == 'saoma') {
this.address = e.result
}
},
onShow() {
this.getbank()
if (uni.getStorageSync("theme") == "dark") {
this.theme = this.$store.state.darkTheme
} else {
this.theme = this.$store.state.lightTheme
}
this.getcurrlist()
this.getaddresslist()
// this.getEmail()
},
methods: {
openshow1() {
if (this.address == '') return this.tos(this.i18n.withdraw.tos1)
if (this.number == '') return this.tos(this.i18n.withdraw.tos2)
this.show2 = true
},
openshow2() {
if (this.number == '') return this.tos(this.i18n.withdraw.tos2)
this.show2 = true
},
// 提交
getwithdraw() {
if (this.paypwd == '') return this.tos(this.i18n.withdraw.tos3)
// if (this.email != '') {
// if (this.code == '') return this.tos(this.i18n.withdraw.tos9)
// }
// if (this.mobile != '') {
// if (this.code_m == '') return this.tos(this.i18n.withdraw.tos10)
// }
// if (this.google) {
// if (this.code_g == '') return this.tos(this.i18n.withdraw.tos11)
// }
if (!this.flag) {
return
} else {
this.flag = false
let obj = {}
if (this.current == 1) {
obj = {
type: 1,
address: this.address,
lian: this.detail[this.lian],
num: this.number,
pay_pwd: this.paypwd,
code: this.code,
code_m: this.code_m,
code_g: this.code_g
}
}
if (this.current == 2) {
obj = {
type: 2,
coll_id: this.bank.id,
num: this.number,
pay_pwd: this.paypwd,
code: this.code,
code_m: this.code_m,
code_g: this.code_g
}
}
console.log(obj)
this.post('/wallet/withdraw', obj, true).then(res => {
console.log(res)
this.flag = true
if (res.code == 1) {
this.tos(res.msg)
this.paypwd = ''
this.show2 = false
setTimeout(() => {
uni.navigateTo({
url: '/pages/index/withdrawalRecord'
})
}, 500)
}
})
}
},
// 获取提币内容
getdetails(id) {
this.post('/wallet/get_withdraw', {
id: id
}).then(res => {
console.log(res)
if (res.code == 1) {
this.detail = res.data.lian
this.data = res.data
this.lian = 0
this.email = res.data.email
this.mobile = res.data.mobile
this.google = res.data.is_google
}
})
},
// 获取币种
getcurrlist() {
this.post('/wallet/wid_curr').then(res => {
console.log(res)
if (res.code == 1) {
this.list = res.data
// 构建币种选择列表,确保包含 BTC 和 ETH
// BTC curr_id=3, ETH curr_id=4(与后端 app_currency 表对应)
let types = [...res.data]
let names = types.map(t => t.name.toUpperCase())
if (!names.includes('BTC')) {
types.push({ id: 3, name: 'BTC' })
}
if (!names.includes('ETH')) {
types.push({ id: 4, name: 'ETH' })
}
this.coinTypes = types
this.curr = res.data[0].name
this.currid = res.data[0].id
this.getdetails(this.currid)
}
})
},
changeCoinType(item) {
if (this.currid == item.id) return
this.curr = item.name
this.currid = item.id
this.address = ''
this.number = ''
this.getdetails(this.currid)
},
// 获取地址
getaddresslist() {
this.post('/my/address_list').then(res => {
console.log(res)
if (res.code == 1) {
this.list1 = res.data
}
})
},
getbank() {
this.post('/my/collection_list').then(res => {
console.log('银行卡', res)
if (res.code == 1) {
this.bankList = res.data
this.bank = res.data[0]
}
})
},
changebank(item) {
this.bank = item
this.bankshow = false
},
changecurr(item) {
this.curr = item.name
this.currid = item.id
this.getdetails(this.currid)
this.show = false
},
changelian(item, index) {
if (this.lian != index) {
this.lian = index
console.log(this.detail[this.lian])
}
},
getEmail() {
this.post('/my/get_userinfo').then(res => {
console.log(res)
if (res.code == 1) {
this.email = res.data.email
}
})
},
cutTime() {
if (!this.timeFlag) return
uni.showLoading({
title: '',
})
this.timeFlag = false
this.post('/ems/send', {
email: this.email,
event: "withdraw",
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
this.tos(this.i18n.withdraw.tos7)
this.time = 120
var that = this
let timeName = setInterval(() => {
if (that.time > 0) {
that.time--
} else {
that.time = that.i18n.withdraw.text13
that.timeFlag = true
clearInterval(timeName)
}
}, 1000)
} else {
this.timeFlag = true
}
})
},
cutTime2() {
if (!this.timeFlag2) return
uni.showLoading({
title: '',
})
this.timeFlag2 = false
this.post('/sms/send', {
mobile: this.mobile,
event: "withdraw",
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
this.tos(this.i18n.withdraw.tos7)
this.time2 = 120
var that = this
let timeName2 = setInterval(() => {
if (that.time2 > 0) {
that.time2--
} else {
that.time2 = that.i18n.withdraw.text13
that.timeFlag2 = true
clearInterval(timeName2)
}
}, 1000)
} else {
this.timeFlag2 = true
}
})
},
copy(data) {
// #ifndef H5
clipboard.setText(data);
// #endif
// #ifdef H5
let result
let textarea = document.createElement("textarea")
textarea.value = data
textarea.readOnly = "readOnly"
document.body.appendChild(textarea)
textarea.select() // 选中文本内容
textarea.setSelectionRange(0, data.length)
result = document.execCommand("copy")
textarea.remove()
// #endif
this.tos(this.i18n.mine.share.copySuceed)
},
}
}
</script>
<style lang="scss">
.onbox {
height: 56rpx;
padding: 0 24rpx;
background: linear-gradient(180deg, #52F3C9 0%, #3ECEB2 100%);
border-radius: 28rpx;
text-align: center;
line-height: 56rpx;
font-size: 30rpx;
color: #FFFFFF;
white-space: nowrap;
}
.offbox {
height: 56rpx;
padding: 0 24rpx;
background: rgba(139, 153, 162, 0.2);
border-radius: 28rpx;
text-align: center;
line-height: 56rpx;
font-size: 30rpx;
color: #8B99A2;
white-space: nowrap;
}
.custom-style {
width: 600rpx;
height: 86rpx;
background: linear-gradient(180deg, #52F3C9 0%, #3ECEB2 100%);
border-radius: 20rpx;
font-size: 32rpx;
color: #FFFFFF;
}
.addressbox {
width: 690rpx;
height: 120rpx;
border-radius: 20rpx;
// background-color: rgba(0, 0, 0, 0.1);
margin-bottom: 10rpx;
padding: 10rpx 30rpx;
}
</style>