feat: 前端全量更新 - 含所有本次需求

- 移除秒合约页面及UI
- 合约页Tab改为Position Held/Transaction Record
- 存款/提款/转账页增加BTC/ETH
- 资产页重构(用户信息+盈亏+多语言)
- 注册页改版(匹配新设计稿)
- 日文全面翻译+首页菜单多语言
- 代理专属注册链接支持(?code=)
- 10个locale文件同步更新
This commit is contained in:
li
2026-03-30 20:14:20 +08:00
commit 5f40e4e1b5
605 changed files with 154871 additions and 0 deletions
+598
View File
@@ -0,0 +1,598 @@
<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">Select Coin</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">{{lian==0?data.erc_process: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: '获取验证码',
timeFlag: true,
time2: '获取验证码',
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
let types = [...res.data]
let names = types.map(t => t.name.toUpperCase())
if (!names.includes('BTC')) {
types.push({ id: 'btc_static', name: 'BTC' })
}
if (!names.includes('ETH')) {
types.push({ id: 'eth_static', 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>