Files
li 5f40e4e1b5 feat: 前端全量更新 - 含所有本次需求
- 移除秒合约页面及UI
- 合约页Tab改为Position Held/Transaction Record
- 存款/提款/转账页增加BTC/ETH
- 资产页重构(用户信息+盈亏+多语言)
- 注册页改版(匹配新设计稿)
- 日文全面翻译+首页菜单多语言
- 代理专属注册链接支持(?code=)
- 10个locale文件同步更新
2026-03-30 20:14:20 +08:00

620 lines
19 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: #080A17;color: #FFFFFF;'">
<!-- <myNav :title="titleName" ></myNav> -->
<u-navbar :title="titleName" z-index="10100" back-icon-color="#FFFFFF" title-color="#fff"
:background="{ background: '#080A17' }" height="55" :border-bottom="false"></u-navbar>
<view style="height: 60px;" class="flex align-center justify-between padding-w-30">
<view class="flex-1 height-100 padding-c-8 flex direction-column align-start justify-between">
<view :class="lastData.close>lastData.open?'color-00C481':'color-FF4040'" class="font-44 numbold-font">
{{Number(lastData.close).toFixed(price_jd)||0}}
</view>
<view :class="lastData.close>lastData.open?'color-00C481':'color-FF4040'"
class="font-28 nummedium-font">
{{(Number(lastData.close)*exchange_rate).toFixed(price_jd)||0}} {{name_sx}}
</view>
</view>
<view class="flex-1 height-60 flex direction-column align-end justify-between">
<view class="font-20 nummedium-font color-C3C3C3">
{{i18n.line.highprice}}{{Number(dayData.high).toFixed(price_jd)||0}}
</view>
<view class="font-20 nummedium-font color-C3C3C3">
{{i18n.line.lowprice}}{{Number(dayData.low).toFixed(price_jd)||0}}
</view>
<!-- <view class="font-20 nummedium-font color-C3C3C3">24h交易额{{(lastData.close*6.25*lastData.amount/100000000).toFixed(2)}}亿</view> -->
</view>
</view>
<!-- #ifdef H5 -->
<!-- <view class="width-100b text-center" style="border: 1rpx solid #EDEDED;" :style="{ 'height': h5Height + 'px' }">
<text class="font-26 color-C3C3C3">请在app上查看</text>
</view> -->
<!-- #endif -->
<view :style="{ 'height': h5Height + 'px' }"></view>
<view class="list">
<view class="height-72 padding-w-40 flex align-center justify-between">
<view @click="tabsChange(index)"
class="flex-1 height-46 flex direction-column align-center justify-between"
v-for="(item,index) in tablist" :key="index">
<text :class="current==index?'color-0165EE':'color-C3C3C3'"
class="bold-font font-26">{{item}}</text>
<view :style="current==index?'':'visibility: hidden;'" class="heng"></view>
</view>
</view>
<!-- 委托列表 -->
<view v-if="current==0" class="">
<view class="height-72 padding-w-30 flex align-center justify-between">
<text class="font-24 nummedium-font color-00C481">{{i18n.line.buyP}}</text>
<text class="font-24 nummedium-font color-C3C3C3">{{i18n.line.num}}</text>
<text class="width-300 text-center font-24 nummedium-font color-C3C3C3">{{i18n.line.price}}</text>
<text class="font-24 nummedium-font color-C3C3C3">{{i18n.line.num}}</text>
<text class="font-24 nummedium-font color-FF4040">{{i18n.line.sellP}}</text>
</view>
<view class="padding-w-30 width-100b flex align-start justify-between">
<view class="width-330 flex direction-column justify-start">
<view v-if="index<10" class="height-72 flex align-center justify-between relative"
v-for="(item,index) in tick.bids" :key="index">
<text class="font-24 nummedium-font color-C3C3C3">{{index+1}}</text>
<text class="font-24 nummedium-font color-C3C3C3">{{item[1] | numFilter}}</text>
<text
class="font-24 nummedium-font color-00C481">{{Number(item[0]).toFixed(price_jd)}}</text>
<view class="right progress bj-E5F9F2"
:style="'width:'+ dethWidth(index,item[1],tick.bids) +'%;'">
</view>
</view>
</view>
<view class="width-330 flex direction-column justify-start">
<view v-if="index<10" class="height-72 flex align-center justify-between relative"
v-for="(item,index) in tick.asks" :key="index">
<text
class="font-24 nummedium-font color-FF4040">{{Number(item[0]).toFixed(price_jd)}}</text>
<text class="font-24 nummedium-font color-C3C3C3">{{item[1] | numFilter}}</text>
<text class="font-24 nummedium-font color-C3C3C3">{{index+1}}</text>
<view class="left progress bj-FFEBEB"
:style="'width:'+ dethWidth(index,item[1],tick.asks) +'%;'">
</view>
</view>
</view>
</view>
</view>
<!-- 信息 -->
<view v-if="current==1" class="">
<view class="listBox">
<view class="flex align-center">
<image class="width-42 height-42 radiu-50b" :src="coinInfo.logo_image" mode=""></image>
<text class="font-26 numbold-font margin-l-10">{{coinInfo.name}}</text>
</view>
<!-- <text class="font-26 color-0165EE numbold-font">{{coinInfo.jys}}</text> -->
</view>
<!-- <view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.ranking}}</text>
<text class="font-26 nummedium-font">{{'NO.'}}{{coinInfo.level}}</text>
</view> -->
<!-- <view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.value}}</text>
<text class="font-26 nummedium-font">{{coinInfo.count_price}}</text>
</view> -->
<view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.number}}</text>
<text class="font-26 nummedium-font">{{coinInfo.liutong_num}}</text>
</view>
<view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.supply}}</text>
<text class="font-26 nummedium-font">{{coinInfo.gongji_num}}</text>
</view>
<view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.allNum}}</text>
<text class="font-26 nummedium-font">{{coinInfo.count_num}}</text>
</view>
<view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.issuingDate}}</text>
<text class="font-26 nummedium-font">{{coinInfo.faxin_time}}</text>
</view>
<view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.issuePrice}}</text>
<text class="font-26 nummedium-font">{{coinInfo.faxin_price}}</text>
</view>
<view @click="goURL(coinInfo.qukuai)" class="listBox1">
<view class="width-180 height-66 line-height-66">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.qukuai}}</text>
</view>
<view class="" style="width:480rpx;word-wrap:break-word;padding: 8rpx 0px;text-align: right;">
<text class="font-26 color-0165EE nummedium-font">{{coinInfo.qukuai}}</text>
</view>
</view>
<view class="listBox">
<text class="font-26 color-C3C3C3 numbold-font">{{i18n.line.jieshao}}</text>
</view>
<view class="padding-w-30 padding-c-10 font-26">
{{coinInfo.desc}}
</view>
</view>
</view>
<view class="height-140"></view>
<view class="bottomBox">
<button @click="goTabBar('buy')" class="cu-btn loginBtn"
style="background-color: #04DC9B;">{{i18n.line.buyIn}}</button>
<button @click="goTabBar('sell')" class="cu-btn loginBtn"
style="background-color: #FF2B41;">{{i18n.line.sellout}}</button>
</view>
</view>
</template>
<script>
var wv; //计划创建的webview
export default {
components: {
},
data() {
return {
Language: uni.getStorageSync('Language'),
name_sx: '',
src: '',
titleName: "",
symbol: '',
exchange_rate: 6, //usdt汇率
tablist: ['委托订单', '信息'],
current: 0,
coinInfo: {},
lastData: {
amount: 0.000000,
close: 0.000000,
count: 0.000000,
high: 0.000000,
id: 1637307480,
low: 0.000000,
open: 0.000000,
vol: 0.000000,
},
dayData: "",
tick: "",
market_jd: 6,
price_jd: 4,
timer: null
}
},
filters: {
//过滤数字位数
numFilter(item) {
if (item == undefined || item == null) {
return 0;
} else {
if (Number(item) < 10) {
return Number(item).toFixed(6);
} else if (Number(item) >= 10 && Number(item) < 1000) {
return Number(item).toFixed(4);
} else if (Number(item) >= 1000 && Number(item) < 1000000) {
return (Number(item) / 1000).toFixed(4) + ' K';
} else if (Number(item) >= 1000000 && Number(item) < 10000000000) {
return (Number(item) / 1000000).toFixed(2) + ' M';
} else {
return (Number(item) / 10000000000).toFixed(2) + ' B';
}
}
},
},
computed: {
i18n() {
return this.$t('message');
},
h5Height() {
return uni.getSystemInfoSync().windowWidth * 1.14 + 30;
},
topHeight() {
return uni.getSystemInfoSync().statusBarHeight + 60 + 55;
}
},
onLoad(option) {
this.tablist = this.i18n.line.tablist
this.titleName = option.title
console.log('传入参数', option)
if (option.symbol) {
this.lastData.close = option.close
this.symbol = option.symbol
this.getCionInfo(option.symbol)
this.getDay()
getApp().globalData.symbol = this.symbol
}
let that = this;
uni.getSystemInfo({
success: function(res) { // console.log(res)
// console.log(res.system.split(' ')[0])
let system = res.system.split(' ')[0]
if (system == 'iOS') {
// K线网页
that.src = "https://exchange.v5ico-kline.coddex.xyz/index.html?symbol=" + option.symbol +
'&bb_type=' + option.bb_type + "&title=" + option.title + '&lang=' + uni
.getStorageSync('Language')
} else {
that.src = "/hybrid/html/index.html?symbol=" + option.symbol + '&bb_type=' + option
.bb_type + "&title=" + option.title + '&lang=' + uni.getStorageSync('Language')
}
}
})
// #ifdef APP-PLUS
wv = plus.webview.create(this.src, 'custom-webview', {
'kernel': 'WKWebview', //UIWebview或者'WKWebview'
position: 'static',
top: that.topHeight,
left: '0px',
width: '100%',
height: that.h5Height,
zindex: 900,
});
var currentWebview = this.$scope
.$getAppWebview(); //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效,非v3编译模式使用this.$mp.page.$getAppWebview()
currentWebview.append(wv); //一定要append到当前的页面里!!!才能跟随当前页面一起做动画,一起关闭
// #endif
},
onShow() {
this.onSocketMessage()
this.linkSocket() //链接socket订阅
uni.$on('reConnect', (res) => {
console.log("重连WebSocket")
this.onSocketMessage()
})
// this.getexchange()
this.exchange_rate = uni.getStorageSync('ratenum')
this.name_sx = uni.getStorageSync('ratename')
// #ifdef APP-PLUS
// 确保WebView已经加载
if (wv) {
setTimeout(() => {
// 向WebView发送最新数据
if (this.dayData) {
wv.evalJS(`
if (typeof Event !== 'undefined') {
Event.emit('newDay', ${JSON.stringify(this.dayData)});
}
`);
}
if (this.lastData) {
wv.evalJS(`
if (typeof Event !== 'undefined') {
Event.emit('realTime', ${JSON.stringify(this.lastData)});
Event.emit('newData', ${JSON.stringify(this.lastData)});
}
`);
}
}, 1000);
}
// #endif
},
onUnload: function() {
clearTimeout(this.timer)
uni.$off('reConnect')
this.cancelSocket() //取消socket订阅
},
methods: {
onSocketMessage() {
uni.$on('market', (res) => {
// 解析并处理WebSocket消息
try {
if (res.ch && res.ch.includes(this.symbol) && res.tick) {
// 更新最新交易数据
this.lastData = res.tick;
// 如果是WebView显示K线,向WebView发送消息
// #ifdef APP-PLUS
if (wv) {
// 向WebView发送处理好的K线数据
wv.evalJS(`
if (typeof Event !== 'undefined') {
Event.emit('realTime', ${JSON.stringify(res.tick)});
Event.emit('newData', ${JSON.stringify(res.tick)});
}
`);
}
// #endif
}
} catch (e) {
console.error("处理WebSocket消息时出错:", e);
}
})
},
getDay() {
this.post('/market/get_day_kline', {
symbol: this.symbol
}).then(res => {
console.log('获取一天最高最低', res)
if (res.code == 1) {
this.dayData = res.data
// #ifdef APP-PLUS
// 向WebView发送日K线数据
if (wv) {
wv.evalJS(`
if (typeof Event !== 'undefined') {
Event.emit('newDay', ${JSON.stringify(res.data)});
}
`);
}
// #endif
this.timer = setTimeout(() => {
this.getDay()
}, 10000)
}
})
},
getexchange() {
let that = this
this.post('/publics/exchange_list').then(res => {
if (res.code == 1) {
let data = res.data
let cha = data.find(item => item.id == 2)
if (that.Language == 'zh-cn') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 2)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
}
}
if (that.Language == 'en-us') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 4)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'mn') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 11)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'ms') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 5)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'kr') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 7)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'fre') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 9)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'ger') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 3)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'ily') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 10)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
if (that.Language == 'jp') {
// that.exchange_rate=res.data
let obj = data.find(item => item.id == 8)
if (obj) {
that.exchange_rate = obj.exchange
that.name_sx = obj.name_sx
} else {
that.exchange_rate = cha.exchange
that.name_sx = cha.name_sx
}
}
}
})
},
goURL(url) {
plus.runtime.openURL(url)
},
dethWidth(index, item, list) {
var temp = 0
let num = list.length
if (num == 0) return
if (num > 10) {
num = 10
}
for (var i = 0; i < num; i++) {
temp += Number(list[i][1])
}
return Number(item / temp).toFixed(2) * 100
},
tabsChange(index) {
this.current = index;
},
goTabBar(buyType) {
getApp().globalData.buyType = buyType
getApp().globalData.symbol = this.symbol
uni.switchTab({
url: '/pages/transaction/index'
})
},
getCionInfo(symbol) {
this.post('/Contract/get_curr_con', {
symbol: symbol
}).then(res => {
console.log('币种信息', res)
if (res.code == 1) {
this.coinInfo = res.data
// this.exchange_rate = res.data.exchange_rate
this.market_jd = res.data.market_jd
this.price_jd = res.data.price_jd
}
})
},
// 取消socket订阅
cancelSocket() {
this.sendSocketMessage({
'subs': 'depth',
"user_id": uni.getStorageSync("user_id"),
"unsub": "market." + this.symbol + ".depth.step0",
"id": "BTC",
})
this.sendSocketMessage({
'subs': 'tradenow',
"user_id": uni.getStorageSync("user_id"),
"unsub": "market." + this.symbol + ".kline.1min",
"id": "BTC",
})
// this.sendSocketMessage({
// 'subs': 'tradenow',
// "user_id": uni.getStorageSync("user_id"),
// "unsub": "market." + this.symbol + ".kline.1day",
// "id": "BTC",
// })
},
// 链接socket订阅
linkSocket() {
this.sendSocketMessage({
'subs': 'depth',
"user_id": uni.getStorageSync("user_id"),
"sub": "market." + this.symbol + ".depth.step0",
"id": "BTC",
})
this.sendSocketMessage({
'subs': 'tradenow',
"user_id": uni.getStorageSync("user_id"),
"sub": "market." + this.symbol + ".kline.1min",
"id": "BTC",
})
// this.sendSocketMessage({
// 'subs': 'tradenow',
// "user_id": uni.getStorageSync("user_id"),
// "sub": "market." + this.symbol + ".kline.1day",
// "id": "BTC",
// })
},
},
}
</script>
<style lang="scss">
.list {
width: 100%;
padding: 10rpx;
padding-bottom: calc(100rpx + env(safe-area-inset-bottom));
border-top-left-radius: 10rpx;
border-top-right-radius: 10rpx;
// background-color: #fff;
box-shadow: 2rpx 2rpx 4rpx #181b2a;
}
.progress {
height: 100%;
max-width: 330rpx;
position: absolute;
top: 0rpx;
transition: all 0.3s;
}
.right {
right: 0rpx;
border-top-left-radius: 10rpx;
border-bottom-left-radius: 10rpx;
}
.left {
left: 0rpx;
border-top-right-radius: 10rpx;
border-bottom-right-radius: 10rpx;
}
.heng {
width: 48rpx;
height: 4rpx;
margin: 10 auto;
background: #0165EE;
}
.bottomBox {
width: 100%;
height: 140rpx;
padding: 0 30rpx 20rpx;
display: flex;
align-items: center;
justify-content: center;
// background: #FFFFFF;
position: fixed;
bottom: 0rpx;
box-shadow: 0rpx 0rpx 10rpx rgba(0, 0, 0, 0.16);
}
.loginBtn {
// width: 320rpx;
flex: 1;
height: 74rpx;
margin: 0 20rpx;
box-shadow: 0rpx 6rpx 10rpx rgba(16, 194, 168, 0.18);
border-radius: 4rpx;
color: #FFFFFF;
}
.listBox {
width: 100%;
height: 66rpx;
border-bottom: 1rpx solid #313135;
padding: 0 30rpx;
color: #8B99A2;
display: flex;
align-items: center;
justify-content: space-between;
}
.listBox1 {
width: 100%;
min-height: 66rpx;
border-bottom: 1rpx solid #313135;
padding: 0 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
</style>