Compare commits

...

3 Commits
main ... dev_yk

3 changed files with 857 additions and 628 deletions

View File

@ -0,0 +1,270 @@
<template>
<view v-if="visible" class="popup-mask" @touchmove.stop.prevent="noop">
<view class="popup-mask__backdrop" @click="handleMaskClick"></view>
<view class="popup-panel" :class="['popup-panel--' + status, panelClass]">
<view class="popup-panel__head">
<text class="popup-panel__title">{{ title }}</text>
<view v-if="showClose" class="popup-panel__close" @click="$emit('cancel')">
<image class="popup-panel__close-image" src="https://imgs.agrimedia.cn/bm-bmt/bmt-close.png" mode="aspectFit">
</image>
</view>
</view>
<view v-if="showStatusBlock" class="popup-panel__status">
<image class="popup-panel__status-image" :src="statusIcon" mode="aspectFit"></image>
<text v-if="message" class="popup-panel__status-text asset-number-font">{{
message
}}</text>
</view>
<text v-else-if="message" class="popup-panel__message asset-number-font">{{
message
}}</text>
<text v-if="description" class="popup-panel__description asset-number-font">{{
description
}}</text>
<view v-if="$slots.default" class="popup-panel__body">
<slot />
</view>
<view class="popup-panel__footer" :class="{ 'popup-panel__footer--single': !showCancel }">
<view v-if="showCancel" class="popup-panel__btn popup-panel__btn--ghost" style="height: 64rpx"
@click="$emit('cancel')">
{{ cancelText }}
</view>
<view class="popup-panel__btn popup-panel__btn--primary" style="height: 64rpx" @click="$emit('confirm')">
{{ confirmText }}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "提示",
},
message: {
type: String,
default: "",
},
description: {
type: String,
default: "",
},
confirmText: {
type: String,
default: "确认",
},
cancelText: {
type: String,
default: "取消",
},
showCancel: {
type: Boolean,
default: true,
},
showClose: {
type: Boolean,
default: true,
},
closeOnMask: {
type: Boolean,
default: true,
},
status: {
type: String,
default: "default",
},
panelClass: {
type: String,
default: "",
},
},
computed: {
showStatusBlock() {
return this.status === "success" || this.status === "error";
},
statusIcon() {
if (this.status === "success") {
return "https://imgs.agrimedia.cn/bm-bmt/success.png";
}
if (this.status === "error") {
return "https://imgs.agrimedia.cn/bm-bmt/fail.png";
}
return "";
},
},
methods: {
noop() { },
handleMaskClick() {
if (this.closeOnMask) {
this.$emit("cancel");
}
},
},
};
</script>
<style lang="scss" scoped>
@import "../../styles/tokens.scss";
.popup-mask {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
inset: 0;
z-index: 80;
display: flex;
align-items: center;
justify-content: center;
padding: 24rpx;
}
.popup-mask__backdrop {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
inset: 0;
background: rgba(5, 10, 22, 0.72);
}
.popup-panel {
position: relative;
width: 100%;
max-width: 600rpx;
padding: 30rpx 28rpx 32rpx;
border-radius: 28rpx;
border: 1px solid rgba(142, 157, 206, 0.14);
background: #2a2f4d;
box-shadow: 0 30rpx 70rpx rgba(0, 0, 0, 0.28);
}
.popup-panel__head {
position: relative;
display: flex;
align-items: center;
justify-content: center;
min-height: 44rpx;
}
.popup-panel__title {
display: block;
width: 100%;
padding: 0 56rpx;
font-size: 32rpx;
font-weight: 500;
text-align: center;
color: #ffffff;
}
.popup-panel__close {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
width: 44rpx;
height: 44rpx;
}
.popup-panel__close-image {
width: 28rpx;
height: 28rpx;
}
.popup-panel__message {
display: block;
margin-top: 34rpx;
font-size: 30rpx;
line-height: 1.8;
color: #edf2ff;
}
.popup-panel__status {
display: flex;
align-items: center;
justify-content: center;
margin-top: 46rpx;
}
.popup-panel__status-image {
width: 54rpx;
height: 54rpx;
flex-shrink: 0;
}
.popup-panel__status-text {
margin-left: 18rpx;
font-size: 24rpx;
font-weight: 600;
color: #edf2ff;
}
.popup-panel__description {
display: block;
margin-top: 34rpx;
font-size: 26rpx;
line-height: 1.7;
text-align: center;
color: rgba(201, 209, 233, 0.86);
}
.popup-panel__body {
margin-top: 22rpx;
font-size: 28rpx;
}
.popup-panel__footer {
display: flex;
align-items: center;
gap: 18rpx;
margin-top: 40rpx;
}
.popup-panel__footer--single {
justify-content: center;
}
.popup-panel__btn {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
height: 64rpx;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 700;
}
.popup-panel__footer--single .popup-panel__btn {
flex: 0 0 232rpx;
}
.popup-panel__btn--ghost {
border: 1px solid rgba(157, 173, 221, 0.44);
background: rgba(77, 89, 129, 0.28);
color: #ffffff;
}
.popup-panel__btn--primary {
background: #02ABF1;
color: #ffffff;
}
</style>

View File

@ -1,6 +1,6 @@
{ {
"name" : "白马交易所", "name" : "白马交易所",
"appid" : "__UNI__3EC3CC8", "appid" : "__UNI__B250220",
"description" : "", "description" : "",
"versionName" : "1.0.0", "versionName" : "1.0.0",
"versionCode" : "100", "versionCode" : "100",

View File

@ -7,11 +7,7 @@
<view class="hero-card__content"> <view class="hero-card__content">
<view class="hero-card__coin-row"> <view class="hero-card__coin-row">
<view class="hero-card__coin"> <view class="hero-card__coin">
<image <image class="hero-card__coin-image" :src="pageIcon('bmt')" mode="aspectFit"></image>
class="hero-card__coin-image"
:src="pageIcon('bmt')"
mode="aspectFit"
></image>
</view> </view>
<text class="hero-card__coin-text">BMT</text> <text class="hero-card__coin-text">BMT</text>
</view> </view>
@ -23,11 +19,7 @@
<view class="panel-card info-card"> <view class="panel-card info-card">
<view class="info-row"> <view class="info-row">
<view class="info-row__left"> <view class="info-row__left">
<image <image class="info-row__icon" :src="pageIcon('voucher')" mode="aspectFit"></image>
class="info-row__icon"
:src="pageIcon('voucher')"
mode="aspectFit"
></image>
<text class="info-row__label">我的算力</text> <text class="info-row__label">我的算力</text>
</view> </view>
<text class="info-row__value asset-number-font">{{ displayVoucher }}</text> <text class="info-row__value asset-number-font">{{ displayVoucher }}</text>
@ -35,11 +27,7 @@
<view class="info-row"> <view class="info-row">
<view class="info-row__left"> <view class="info-row__left">
<image <image class="info-row__icon" :src="pageIcon('coupon')" mode="aspectFit"></image>
class="info-row__icon"
:src="pageIcon('coupon')"
mode="aspectFit"
></image>
<text class="info-row__label">可用积分</text> <text class="info-row__label">可用积分</text>
</view> </view>
<text class="info-row__value asset-number-font">{{ displayCoupon }}</text> <text class="info-row__value asset-number-font">{{ displayCoupon }}</text>
@ -47,11 +35,8 @@
<view class="info-row info-row--last"> <view class="info-row info-row--last">
<view class="info-row__left"> <view class="info-row__left">
<image <image class="info-row__icon" src="https://imgs.agrimedia.cn/bm-bmt/b.png" mode="aspectFit">
class="info-row__icon" </image>
src="https://imgs.agrimedia.cn/bm-bmt/b.png"
mode="aspectFit"
></image>
<text class="info-row__label">BMT实时价格</text> <text class="info-row__label">BMT实时价格</text>
</view> </view>
<view class="info-row__price"> <view class="info-row__price">
@ -69,22 +54,14 @@
<view class="panel-card form-card"> <view class="panel-card form-card">
<view class="form-card__title"> <view class="form-card__title">
<image <image class="form-card__title-icon" src="https://imgs.agrimedia.cn/bm-bmt/b.png" mode="aspectFit">
class="form-card__title-icon" </image>
src="https://imgs.agrimedia.cn/bm-bmt/b.png"
mode="aspectFit"
></image>
<text class="form-card__title-text">BMT兑换</text> <text class="form-card__title-text">BMT兑换</text>
</view> </view>
<view class="form-input"> <view class="form-input">
<decimal-input <decimal-input v-model="form.points" class="form-input__field asset-number-font" :digit="0"
v-model="form.points" placeholder="请输入积分数量" placeholder-style="color: rgba(177, 187, 214, 0.42);" />
class="form-input__field asset-number-font"
:digit="0"
placeholder="请输入积分数量"
placeholder-style="color: rgba(177, 187, 214, 0.42);"
/>
<text class="form-input__suffix">可用积分</text> <text class="form-input__suffix">可用积分</text>
</view> </view>
@ -97,9 +74,7 @@
</view> </view>
<view class="preview-card__row"> <view class="preview-card__row">
<view class="preview-card__left"> <view class="preview-card__left">
<text class="preview-card__label" style="color: #fff" <text class="preview-card__label" style="color: #fff">消耗算力</text>
>消耗算力</text
>
</view> </view>
<text class="preview-card__value preview-card__value--light asset-number-font">{{ <text class="preview-card__value preview-card__value--light asset-number-font">{{
powerCost powerCost
@ -109,11 +84,7 @@
<view class="tips-block"> <view class="tips-block">
<text class="tips-block__title">兑换说明</text> <text class="tips-block__title">兑换说明</text>
<view <view v-for="(tip, index) in normalizedTips" :key="tip" class="tips-block__item">
v-for="(tip, index) in normalizedTips"
:key="tip"
class="tips-block__item"
>
<text class="tips-block__index asset-number-font">{{ index + 1 }}.</text> <text class="tips-block__index asset-number-font">{{ index + 1 }}.</text>
<text class="tips-block__text asset-number-font">{{ tip }}</text> <text class="tips-block__text asset-number-font">{{ tip }}</text>
</view> </view>
@ -121,26 +92,15 @@
</view> </view>
<view class="action-wrap"> <view class="action-wrap">
<view <view class="action-button" @touchend.stop.prevent="openConfirm" @tap.stop="openConfirm"
class="action-button" @click.stop="openConfirm">确认兑换</view>
@touchend.stop.prevent="openConfirm"
@tap.stop="openConfirm"
@click.stop="openConfirm"
>确认兑换</view
>
<view class="action-link" @click="openLedger">兑换记录</view> <view class="action-link" @click="openLedger">兑换记录</view>
</view> </view>
</view> </view>
<asset-confirm-popup <confirm-popup :visible="confirmVisible" title="兑换提示" :message="
:visible="confirmVisible"
title="兑换提示"
:message="
'确认使用 ' + formatAmount(pointsValue, 0) + ' 积分兑换 BMT 吗?' '确认使用 ' + formatAmount(pointsValue, 0) + ' 积分兑换 BMT 吗?'
" " @cancel="confirmVisible = false" @confirm="submit">
@cancel="confirmVisible = false"
@confirm="submit"
>
<view class="popup-line"> <view class="popup-line">
<text class="meta-pair__label">预估兑换BMT</text> <text class="meta-pair__label">预估兑换BMT</text>
<text class="meta-pair__value asset-number-font">{{ estimateBmt }}</text> <text class="meta-pair__value asset-number-font">{{ estimateBmt }}</text>
@ -153,22 +113,22 @@
<text class="meta-pair__label">消耗算力</text> <text class="meta-pair__label">消耗算力</text>
<text class="meta-pair__value asset-number-font">{{ powerCost }}</text> <text class="meta-pair__value asset-number-font">{{ powerCost }}</text>
</view> </view>
</asset-confirm-popup> </confirm-popup>
</view> </view>
</template> </template>
<script> <script>
import AssetConfirmPopup from "../../components/asset-confirm-popup.vue"; import ConfirmPopup from "../../components/confirm-popup/confirm-popup.vue";
import AssetPageShell from "../../components/asset-page-shell.vue"; import AssetPageShell from "../../components/asset-page-shell.vue";
import DecimalInput from "../../components/DecimalInput/DecimalInput.vue"; import DecimalInput from "../../components/DecimalInput/DecimalInput.vue";
import { import {
fetchBmtExchangeDetail, fetchBmtExchangeDetail,
submitAssetBmtExchange, submitAssetBmtExchange,
} from "../../api/assets"; } from "../../api/assets";
export default { export default {
components: { components: {
AssetConfirmPopup, ConfirmPopup,
AssetPageShell, AssetPageShell,
DecimalInput, DecimalInput,
}, },
@ -297,12 +257,12 @@ export default {
async loadPage(showLoading) { async loadPage(showLoading) {
try { try {
this.detail = await fetchBmtExchangeDetail( this.detail = await fetchBmtExchangeDetail(
showLoading showLoading ?
? { {
showLoading: true, showLoading: true,
loadingText: "加载中", loadingText: "加载中",
} } :
: null, null,
); );
} catch (error) { } catch (error) {
uni.showToast({ uni.showToast({
@ -394,50 +354,49 @@ export default {
}); });
}, },
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../../styles/tokens.scss"; @import "../../styles/tokens.scss";
@import "../../styles/common.scss"; @import "../../styles/common.scss";
.bmt-page { .bmt-page {
min-height: 100vh; min-height: 100vh;
background: #191e32; background: #191e32;
} }
.bmt-scroll { .bmt-scroll {
padding: 8rpx 20rpx calc(env(safe-area-inset-bottom) + 36rpx); padding: 8rpx 20rpx calc(env(safe-area-inset-bottom) + 36rpx);
} }
.panel-card, .panel-card,
.hero-card { .hero-card {
border-radius: 12rpx; border-radius: 12rpx;
background: #20263e; background: #20263e;
} }
.hero-card { .hero-card {
position: relative; position: relative;
min-height: 240rpx; min-height: 240rpx;
padding: 24rpx 28rpx; padding: 24rpx 28rpx;
overflow: hidden; overflow: hidden;
background: #20263e url("https://imgs.agrimedia.cn/bm-bmt/bmt2-header.png") background: #20263e url("https://imgs.agrimedia.cn/bm-bmt/bmt2-header.png") no-repeat center top / 100% 240rpx;
no-repeat center top / 100% 240rpx; }
}
.hero-card__content { .hero-card__content {
position: relative; position: relative;
z-index: 1; z-index: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.hero-card__coin-row { .hero-card__coin-row {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.hero-card__coin { .hero-card__coin {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -445,244 +404,244 @@ export default {
height: 56rpx; height: 56rpx;
border-radius: 50%; border-radius: 50%;
background: linear-gradient(135deg, #18c5ff 0%, #1496ff 100%); background: linear-gradient(135deg, #18c5ff 0%, #1496ff 100%);
} }
.hero-card__coin-image { .hero-card__coin-image {
width: 30rpx; width: 30rpx;
height: 30rpx; height: 30rpx;
} }
.hero-card__coin-text { .hero-card__coin-text {
margin-left: 16rpx; margin-left: 16rpx;
font-size: 32rpx; font-size: 32rpx;
font-weight: 500; font-weight: 500;
color: #ffffff; color: #ffffff;
} }
.hero-card__label { .hero-card__label {
margin-top: 34rpx; margin-top: 34rpx;
font-size: 28rpx; font-size: 28rpx;
color: #9ba7ce; color: #9ba7ce;
} }
.hero-card__value { .hero-card__value {
margin-top: 8rpx; margin-top: 8rpx;
font-size: 48rpx; font-size: 48rpx;
font-weight: 800; font-weight: 800;
color: #ffffff; color: #ffffff;
line-height: 1.1; line-height: 1.1;
} }
.panel-card { .panel-card {
margin-top: 18rpx; margin-top: 18rpx;
padding: 0 26rpx; padding: 0 26rpx;
} }
.info-card { .info-card {
padding-top: 2rpx; padding-top: 2rpx;
padding-bottom: 14rpx; padding-bottom: 14rpx;
} }
.info-row { .info-row {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
min-height: 96rpx; min-height: 96rpx;
border-bottom: 1rpx solid #4e5a82; border-bottom: 1rpx solid #4e5a82;
} }
.info-row--last { .info-row--last {
border-bottom: 1rpx solid #4e5a82; border-bottom: 1rpx solid #4e5a82;
} }
.info-row__left { .info-row__left {
display: flex; display: flex;
align-items: center; align-items: center;
min-width: 0; min-width: 0;
} }
.info-row__icon { .info-row__icon {
width: 34rpx; width: 34rpx;
height: 34rpx; height: 34rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.info-row__label { .info-row__label {
margin-left: 20rpx; margin-left: 20rpx;
font-size: 28rpx; font-size: 28rpx;
font-weight: 400; font-weight: 400;
color: #eef2ff; color: #eef2ff;
} }
.info-row__value { .info-row__value {
font-size: 32rpx; font-size: 32rpx;
font-weight: 700; font-weight: 700;
color: #ffffff; color: #ffffff;
} }
.info-row__price { .info-row__price {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
} }
.info-row__unit { .info-row__unit {
margin-left: 10rpx; margin-left: 10rpx;
font-size: 22rpx; font-size: 22rpx;
color: rgba(184, 193, 218, 0.88); color: rgba(184, 193, 218, 0.88);
} }
.info-card__estimate { .info-card__estimate {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
align-items: baseline; align-items: baseline;
padding-top: 18rpx; padding-top: 18rpx;
font-size: 28rpx; font-size: 28rpx;
color: #1ad296; color: #1ad296;
} }
.info-card__estimate-value { .info-card__estimate-value {
margin: 0 10rpx; margin: 0 10rpx;
font-size: 32rpx; font-size: 32rpx;
font-weight: 800; font-weight: 800;
color: #2fe2a4; color: #2fe2a4;
} }
.form-card { .form-card {
padding-top: 18rpx; padding-top: 18rpx;
padding-bottom: 20rpx; padding-bottom: 20rpx;
} }
.form-card__title { .form-card__title {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.form-card__title-icon { .form-card__title-icon {
width: 34rpx; width: 34rpx;
height: 34rpx; height: 34rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.form-card__title-text { .form-card__title-text {
margin-left: 14rpx; margin-left: 14rpx;
font-size: 28rpx; font-size: 28rpx;
font-weight: 700; font-weight: 700;
color: #ffffff; color: #ffffff;
} }
.form-input { .form-input {
display: flex; display: flex;
align-items: center; align-items: center;
margin-top: 20rpx; margin-top: 20rpx;
padding: 0 20rpx; padding: 0 20rpx;
border-radius: 10rpx; border-radius: 10rpx;
background: #191e32; background: #191e32;
} }
.form-input__icon { .form-input__icon {
width: 34rpx; width: 34rpx;
height: 34rpx; height: 34rpx;
margin-right: 18rpx; margin-right: 18rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.form-input__field { .form-input__field {
flex: 1; flex: 1;
height: 98rpx; height: 98rpx;
font-size: 30rpx; font-size: 30rpx;
font-weight: 700; font-weight: 700;
color: #ffffff; color: #ffffff;
} }
.form-input__suffix { .form-input__suffix {
margin-left: 16rpx; margin-left: 16rpx;
font-size: 22rpx; font-size: 22rpx;
font-weight: 600; font-weight: 600;
color: #ffffff; color: #ffffff;
} }
.preview-card { .preview-card {
margin-top: 18rpx; margin-top: 18rpx;
padding: 12rpx 26rpx; padding: 12rpx 26rpx;
border-radius: 8rpx; border-radius: 8rpx;
background: rgba(26, 210, 150, 0.1); background: rgba(26, 210, 150, 0.1);
} }
.preview-card__row { .preview-card__row {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
.preview-card__row + .preview-card__row { .preview-card__row+.preview-card__row {
margin-top: 8rpx; margin-top: 8rpx;
} }
.preview-card__left { .preview-card__left {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.preview-card__icon { .preview-card__icon {
width: 30rpx; width: 30rpx;
height: 30rpx; height: 30rpx;
margin-right: 10rpx; margin-right: 10rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.preview-card__label { .preview-card__label {
font-size: 26rpx; font-size: 26rpx;
color: rgba(26, 210, 150, 1); color: rgba(26, 210, 150, 1);
} }
.preview-card__value { .preview-card__value {
font-size: 26rpx; font-size: 26rpx;
font-weight: 800; font-weight: 800;
color: #1ad296; color: #1ad296;
} }
.preview-card__value--light { .preview-card__value--light {
color: #ffffff; color: #ffffff;
} }
.tips-block { .tips-block {
margin-top: 24rpx; margin-top: 24rpx;
} }
.tips-block__title { .tips-block__title {
display: block; display: block;
font-size: 24rpx; font-size: 24rpx;
color: rgba(190, 197, 219, 0.92); color: rgba(190, 197, 219, 0.92);
} }
.tips-block__item { .tips-block__item {
display: flex; display: flex;
margin-top: 10rpx; margin-top: 10rpx;
} }
.tips-block__index, .tips-block__index,
.tips-block__text { .tips-block__text {
font-size: 24rpx; font-size: 24rpx;
color: #929dbf; color: #929dbf;
line-height: 44rpx; line-height: 44rpx;
color: rgba(166, 175, 204, 0.92); color: rgba(166, 175, 204, 0.92);
} }
.tips-block__index { .tips-block__index {
margin-right: 6rpx; margin-right: 6rpx;
} }
.tips-block__text { .tips-block__text {
flex: 1; flex: 1;
} }
.action-wrap { .action-wrap {
position: relative; position: relative;
z-index: 30; z-index: 30;
padding: 36rpx 22rpx 0; padding: 36rpx 22rpx 0;
} }
.action-button { .action-button {
position: relative; position: relative;
z-index: 1; z-index: 1;
display: flex; display: flex;
@ -698,17 +657,17 @@ export default {
color: #ffffff; color: #ffffff;
cursor: pointer; cursor: pointer;
touch-action: manipulation; touch-action: manipulation;
} }
.action-link { .action-link {
margin-top: 26rpx; margin-top: 26rpx;
text-align: center; text-align: center;
font-weight: 500; font-weight: 500;
font-size: 28rpx; font-size: 28rpx;
color: #1fb4ff; color: #1fb4ff;
} }
.popup-line { .popup-line {
margin-top: 14rpx; margin-top: 14rpx;
} }
</style> </style>