967 lines
23 KiB
Vue
967 lines
23 KiB
Vue
<template>
|
||
<view class="asset-page asset-theme bmt-page">
|
||
<asset-page-shell title="BMT兑换" />
|
||
|
||
<view class="asset-scroll bmt-scroll">
|
||
<view class="hero-card">
|
||
<view class="hero-card__content">
|
||
<view class="hero-card__coin-row">
|
||
<view class="hero-card__coin">
|
||
<image
|
||
class="hero-card__coin-image"
|
||
:src="pageIcon('bmt')"
|
||
mode="aspectFit"
|
||
></image>
|
||
</view>
|
||
<text class="hero-card__coin-text">BMT</text>
|
||
</view>
|
||
<text class="hero-card__label">可用BMT:</text>
|
||
<text class="hero-card__value asset-number-font">{{ displayBmt }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="panel-card info-card">
|
||
<view class="info-row">
|
||
<view class="info-row__left">
|
||
<image
|
||
class="info-row__icon"
|
||
:src="pageIcon('voucher')"
|
||
mode="aspectFit"
|
||
></image>
|
||
<text class="info-row__label">我的算力</text>
|
||
</view>
|
||
<text class="info-row__value asset-number-font">{{ displayVoucher }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<view class="info-row__left">
|
||
<image
|
||
class="info-row__icon"
|
||
:src="pageIcon('coupon')"
|
||
mode="aspectFit"
|
||
></image>
|
||
<text class="info-row__label">可用积分</text>
|
||
</view>
|
||
<text class="info-row__value asset-number-font">{{ displayCoupon }}</text>
|
||
</view>
|
||
|
||
<view class="info-row">
|
||
<view class="info-row__left">
|
||
<image
|
||
class="info-row__icon"
|
||
:src="pageIcon('bmtr')"
|
||
mode="aspectFit"
|
||
></image>
|
||
<text class="info-row__label">BMTR数量</text>
|
||
</view>
|
||
<text class="info-row__value asset-number-font">{{ displayBmtr }}</text>
|
||
</view>
|
||
|
||
<view class="info-row info-row--last">
|
||
<view class="info-row__left">
|
||
<image
|
||
class="info-row__icon"
|
||
src="https://imgs.agrimedia.cn/bm-bmt/b.png"
|
||
mode="aspectFit"
|
||
></image>
|
||
<text class="info-row__label">BMT实时价格</text>
|
||
</view>
|
||
<view class="info-row__price">
|
||
<text class="info-row__value asset-number-font">{{ displayPrice }}</text>
|
||
<text class="info-row__unit">BMT/CNY</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="info-card__estimate">
|
||
<text>全部兑换预估可得</text>
|
||
<text class="info-card__estimate-value asset-number-font">{{ allEstimateBmt }}</text>
|
||
<text>BMT</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="panel-card form-card">
|
||
<view class="form-card__title">
|
||
<image
|
||
class="form-card__title-icon"
|
||
src="https://imgs.agrimedia.cn/bm-bmt/b.png"
|
||
mode="aspectFit"
|
||
></image>
|
||
<text class="form-card__title-text">BMT兑换</text>
|
||
</view>
|
||
|
||
<view class="scheme-tabs">
|
||
<view
|
||
class="scheme-tab"
|
||
:class="{ 'scheme-tab--active': redeemType === 0 }"
|
||
@click="selectRedeemType(0)"
|
||
>
|
||
<text>{{ loadingRedeemType === 0 ? "加载中..." : "方案1" }}</text>
|
||
</view>
|
||
<view
|
||
class="scheme-tab"
|
||
:class="{ 'scheme-tab--active': redeemType === 1 }"
|
||
@click="selectRedeemType(1)"
|
||
>
|
||
<text>{{ loadingRedeemType === 1 ? "加载中..." : "方案2" }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-input">
|
||
<decimal-input
|
||
v-model="form.points"
|
||
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>
|
||
</view>
|
||
|
||
<view class="preview-card">
|
||
<view class="preview-card__row">
|
||
<view class="preview-card__left">
|
||
<text class="preview-card__label">预估兑换BMT</text>
|
||
</view>
|
||
<text class="preview-card__value asset-number-font">{{ estimateBmt }}</text>
|
||
</view>
|
||
<view class="preview-card__row">
|
||
<view class="preview-card__left">
|
||
<text class="preview-card__label" style="color: #fff"
|
||
>消耗算力</text
|
||
>
|
||
</view>
|
||
<text class="preview-card__value preview-card__value--light asset-number-font">{{
|
||
powerCost
|
||
}}</text>
|
||
</view>
|
||
<view class="preview-card__row">
|
||
<view class="preview-card__left">
|
||
<text class="preview-card__label preview-card__label--light"
|
||
>消耗BMTR</text
|
||
>
|
||
</view>
|
||
<text class="preview-card__value preview-card__value--light asset-number-font">{{
|
||
bmtrCost
|
||
}}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="tips-block">
|
||
<text class="tips-block__title">兑换说明:</text>
|
||
<view
|
||
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__text asset-number-font">{{ tip }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="action-wrap">
|
||
<view
|
||
class="action-button"
|
||
@touchend.stop.prevent="openConfirm"
|
||
@tap.stop="openConfirm"
|
||
@click.stop="openConfirm"
|
||
>确认兑换</view
|
||
>
|
||
<view class="action-link" @click="openLedger">兑换记录</view>
|
||
</view>
|
||
</view>
|
||
|
||
<asset-confirm-popup
|
||
:visible="confirmVisible"
|
||
title="兑换提示"
|
||
:message="
|
||
'确认使用 ' + formatAmount(pointsValue, 0) + ' 积分兑换 BMT 吗?'
|
||
"
|
||
@cancel="confirmVisible = false"
|
||
@confirm="submit"
|
||
>
|
||
<view class="popup-line">
|
||
<text class="meta-pair__label">预估兑换BMT:</text>
|
||
<text class="meta-pair__value asset-number-font">{{ estimateBmt }}</text>
|
||
</view>
|
||
<view class="popup-line">
|
||
<text class="meta-pair__label">消耗可用积分:</text>
|
||
<text class="meta-pair__value asset-number-font">{{ formatAmount(pointsValue, 0) }}</text>
|
||
</view>
|
||
<view class="popup-line">
|
||
<text class="meta-pair__label">消耗算力:</text>
|
||
<text class="meta-pair__value asset-number-font">{{ powerCost }}</text>
|
||
</view>
|
||
<view class="popup-line">
|
||
<text class="meta-pair__label">消耗BMTR:</text>
|
||
<text class="meta-pair__value asset-number-font">{{ bmtrCost }}</text>
|
||
</view>
|
||
</asset-confirm-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import AssetConfirmPopup from "../../components/asset-confirm-popup.vue";
|
||
import AssetPageShell from "../../components/asset-page-shell.vue";
|
||
import DecimalInput from "../../components/DecimalInput/DecimalInput.vue";
|
||
import {
|
||
fetchBmtExchangeDetail,
|
||
fetchBmtRedeemConfig,
|
||
fetchBmtRedeemPowerRateNew,
|
||
submitAssetBmtExchange,
|
||
} from "../../api/assets";
|
||
|
||
const REDEEM_POINT_STEP = 100;
|
||
|
||
export default {
|
||
components: {
|
||
AssetConfirmPopup,
|
||
AssetPageShell,
|
||
DecimalInput,
|
||
},
|
||
data() {
|
||
return {
|
||
detail: {
|
||
ticker: {},
|
||
balances: {},
|
||
exchangeConfig: {},
|
||
schemeOneConfig: {},
|
||
tips: [],
|
||
},
|
||
hasShown: false,
|
||
form: {
|
||
points: "",
|
||
},
|
||
confirmVisible: false,
|
||
submitting: false,
|
||
redeemType: 0,
|
||
schemeOneConfigLoaded: false,
|
||
loadingRedeemType: null,
|
||
};
|
||
},
|
||
onLoad() {
|
||
this.loadPage(true);
|
||
},
|
||
onShow() {
|
||
if (this.hasShown) {
|
||
this.loadPage();
|
||
return;
|
||
}
|
||
|
||
this.hasShown = true;
|
||
},
|
||
computed: {
|
||
pointsValue() {
|
||
return Number(this.form.points || 0);
|
||
},
|
||
configPointNumber() {
|
||
return Number(this.detail.exchangeConfig.point || 0);
|
||
},
|
||
configPowerNumber() {
|
||
return Number(this.detail.exchangeConfig.cPower || 0);
|
||
},
|
||
configBmtrNumber() {
|
||
return Number(this.detail.exchangeConfig.bmtr || 0);
|
||
},
|
||
redeemNumNumber() {
|
||
return Number(this.detail.exchangeConfig.redeemNum || 0);
|
||
},
|
||
schemeOnePowerNumber() {
|
||
return Number(this.detail.schemeOneConfig.power || 0);
|
||
},
|
||
schemeOneBmtrNumber() {
|
||
return Number(this.detail.schemeOneConfig.bmtr || 0);
|
||
},
|
||
activePowerCostPerPoint() {
|
||
if (this.redeemType === 0) {
|
||
return this.schemeOnePowerNumber;
|
||
}
|
||
|
||
if (!this.configPointNumber) {
|
||
return 0;
|
||
}
|
||
|
||
return this.configPowerNumber / this.configPointNumber;
|
||
},
|
||
activeBmtrCostPerPoint() {
|
||
if (this.redeemType === 0) {
|
||
return this.schemeOneBmtrNumber;
|
||
}
|
||
|
||
if (!this.configPointNumber) {
|
||
return 0;
|
||
}
|
||
|
||
return this.configBmtrNumber / this.configPointNumber;
|
||
},
|
||
canCalculateBmt() {
|
||
return this.redeemType === 0
|
||
? this.priceNumber > 0
|
||
: this.configPointNumber > 0 && this.redeemNumNumber > 0;
|
||
},
|
||
estimateBmt() {
|
||
if (!this.pointsValue || !this.canCalculateBmt) {
|
||
return "0";
|
||
}
|
||
|
||
return this.formatAmount(this.calculateBmt(this.pointsValue), 2);
|
||
},
|
||
powerCostNumber() {
|
||
if (!this.pointsValue || !this.activePowerCostPerPoint) {
|
||
return 0;
|
||
}
|
||
|
||
return this.pointsValue * this.activePowerCostPerPoint;
|
||
},
|
||
powerCost() {
|
||
return this.formatTruncatedAmount(this.powerCostNumber, 2);
|
||
},
|
||
bmtrCostNumber() {
|
||
if (!this.pointsValue || !this.activeBmtrCostPerPoint) {
|
||
return 0;
|
||
}
|
||
|
||
return this.pointsValue * this.activeBmtrCostPerPoint;
|
||
},
|
||
bmtrCost() {
|
||
return this.formatTruncatedAmount(this.bmtrCostNumber, 2);
|
||
},
|
||
allEstimateBmt() {
|
||
const points = Number(this.detail.balances.points || 0);
|
||
|
||
if (!this.canCalculateBmt) {
|
||
return "0.00";
|
||
}
|
||
|
||
let exchangeablePoints = points;
|
||
const power = Number(this.detail.balances.power || 0);
|
||
const bmtr = Number(this.detail.balances.bmtr || 0);
|
||
|
||
if (this.activePowerCostPerPoint > 0) {
|
||
exchangeablePoints = Math.min(
|
||
exchangeablePoints,
|
||
power / this.activePowerCostPerPoint,
|
||
);
|
||
}
|
||
|
||
if (this.activeBmtrCostPerPoint > 0) {
|
||
exchangeablePoints = Math.min(
|
||
exchangeablePoints,
|
||
bmtr / this.activeBmtrCostPerPoint,
|
||
);
|
||
}
|
||
|
||
const truncatedBmt =
|
||
Math.floor(this.calculateBmt(Math.max(0, exchangeablePoints)) * 100) /
|
||
100;
|
||
return this.formatAmount(truncatedBmt, 2);
|
||
},
|
||
priceNumber() {
|
||
return Number(
|
||
this.detail.ticker.close || 0,
|
||
);
|
||
},
|
||
displayBmt() {
|
||
return this.detail.balances.bmt;
|
||
},
|
||
displayVoucher() {
|
||
return this.detail.balances.power;
|
||
},
|
||
displayCoupon() {
|
||
return this.detail.balances.points;
|
||
},
|
||
displayBmtr() {
|
||
return this.formatAmount(this.detail.balances.bmtr, 2);
|
||
},
|
||
displayPrice() {
|
||
return this.priceNumber ? this.priceNumber : "0.00";
|
||
},
|
||
normalizedTips() {
|
||
const tips =
|
||
this.detail.tips && this.detail.tips.length
|
||
? this.detail.tips.slice()
|
||
: [
|
||
`预估BMT数=输入可用积分数÷${this.configPointNumber}×${this.redeemNumNumber}。`,
|
||
"",
|
||
`只能兑换${REDEEM_POINT_STEP}的整数倍,小于${REDEEM_POINT_STEP}积分不可兑换;`,
|
||
"凌晨0点-凌晨1点积分系统维护不可兑换;",
|
||
];
|
||
|
||
tips[1] =
|
||
this.redeemType === 0
|
||
? `方案1消耗算力=输入可用积分数×${this.schemeOnePowerNumber},消耗BMTR=输入可用积分数×${this.schemeOneBmtrNumber};`
|
||
: `方案2消耗算力=输入可用积分数÷${this.configPointNumber}×${this.configPowerNumber},消耗BMTR=输入可用积分数÷${this.configPointNumber}×${this.configBmtrNumber};`;
|
||
tips[0] =
|
||
this.redeemType === 0
|
||
? "方案1预估BMT数=输入可用积分数÷BMT实时价格。"
|
||
: `方案2预估BMT数=(输入可用积分数÷${this.configPointNumber},保留4位小数)×${this.redeemNumNumber},结果保留2位小数。`;
|
||
|
||
return tips;
|
||
},
|
||
},
|
||
methods: {
|
||
calculateBmt(points) {
|
||
const pointAmount = Number(points || 0);
|
||
|
||
if (!pointAmount) {
|
||
return 0;
|
||
}
|
||
|
||
if (this.redeemType === 0) {
|
||
return this.priceNumber ? pointAmount / this.priceNumber : 0;
|
||
}
|
||
|
||
if (!this.configPointNumber || !this.redeemNumNumber) {
|
||
return 0;
|
||
}
|
||
|
||
const convertedPoints = Number(
|
||
(pointAmount / this.configPointNumber).toFixed(4),
|
||
);
|
||
return convertedPoints * this.redeemNumNumber;
|
||
},
|
||
pageIcon(type) {
|
||
const iconMap = {
|
||
power: "https://imgs.agrimedia.cn/bm-bmt/s.png",
|
||
bmt: "https://imgs.agrimedia.cn/bm-bmt/b-w.png",
|
||
transfer: "https://imgs.agrimedia.cn/bm-bmt/z.png",
|
||
withdraw: "https://imgs.agrimedia.cn/bm-bmt/t.png",
|
||
voucher: "https://imgs.agrimedia.cn/bm-bmt/quan-icon-g%20%281%29.png",
|
||
points: "https://imgs.agrimedia.cn/bm-bmt/j.png",
|
||
coupon: "https://imgs.agrimedia.cn/bm-bmt/xiaofei-icon-o.png",
|
||
bmtr: "https://imgs.agrimedia.cn/webimg/202607171808386371853.svg",
|
||
};
|
||
return iconMap[type] || "";
|
||
},
|
||
formatAmount(value, digits) {
|
||
const number = Number(value || 0);
|
||
if (!Number.isFinite(number)) {
|
||
return digits > 0 ? Number(0).toFixed(digits) : "0";
|
||
}
|
||
|
||
if (digits > 0) {
|
||
const fixed = number.toFixed(digits);
|
||
const parts = fixed.split(".");
|
||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||
return parts.join(".");
|
||
}
|
||
|
||
return Math.floor(number)
|
||
.toString()
|
||
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||
},
|
||
formatTruncatedAmount(value, digits) {
|
||
const number = Number(value || 0);
|
||
const precision = Number(digits || 0);
|
||
|
||
if (!Number.isFinite(number)) {
|
||
return precision > 0 ? Number(0).toFixed(precision) : "0";
|
||
}
|
||
|
||
const factor = Math.pow(10, precision);
|
||
const truncated = Math.floor(Math.max(0, number) * factor) / factor;
|
||
return this.formatAmount(truncated, precision);
|
||
},
|
||
async loadPage(showLoading) {
|
||
try {
|
||
this.detail = await fetchBmtExchangeDetail(
|
||
showLoading
|
||
? {
|
||
showLoading: true,
|
||
loadingText: "加载中",
|
||
}
|
||
: null,
|
||
);
|
||
this.schemeOneConfigLoaded = Boolean(
|
||
this.detail.schemeOneConfigLoaded,
|
||
);
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: error.message || "页面加载失败",
|
||
icon: "none",
|
||
});
|
||
}
|
||
},
|
||
async selectRedeemType(type) {
|
||
const nextType = Number(type) === 0 ? 0 : 1;
|
||
|
||
if (nextType === this.redeemType || this.loadingRedeemType !== null) {
|
||
return;
|
||
}
|
||
|
||
this.loadingRedeemType = nextType;
|
||
try {
|
||
const configResult = await Promise.all([
|
||
fetchBmtRedeemConfig({
|
||
showLoading: true,
|
||
loadingText: "刷新兑换配置",
|
||
}),
|
||
fetchBmtRedeemPowerRateNew({
|
||
showLoading: true,
|
||
loadingText: "刷新兑换配置",
|
||
}),
|
||
]);
|
||
|
||
this.detail.exchangeConfig = configResult[0];
|
||
this.detail.schemeOneConfig = configResult[1];
|
||
this.schemeOneConfigLoaded = true;
|
||
|
||
this.redeemType = nextType;
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: error.message || "兑换方案配置加载失败",
|
||
icon: "none",
|
||
});
|
||
} finally {
|
||
this.loadingRedeemType = null;
|
||
}
|
||
},
|
||
openConfirm() {
|
||
if (this.submitting || this.confirmVisible) {
|
||
return;
|
||
}
|
||
|
||
this.confirmVisible = true;
|
||
},
|
||
async submit() {
|
||
if (this.submitting) {
|
||
return;
|
||
}
|
||
|
||
if (!this.pointsValue) {
|
||
uni.showToast({
|
||
title: "请输入积分数量",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (!this.configPointNumber) {
|
||
uni.showToast({
|
||
title: "兑换配置加载失败,请稍后重试",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (this.pointsValue < REDEEM_POINT_STEP) {
|
||
uni.showToast({
|
||
title: `小于${REDEEM_POINT_STEP}积分不可兑换`,
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (this.pointsValue % REDEEM_POINT_STEP !== 0) {
|
||
uni.showToast({
|
||
title: `只能兑换${REDEEM_POINT_STEP}的整数倍`,
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (this.pointsValue > Number(this.detail.balances.points || 0)) {
|
||
uni.showToast({
|
||
title: "可用积分不足",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (this.powerCostNumber > Number(this.detail.balances.power || 0)) {
|
||
uni.showToast({
|
||
title: "可用算力不足",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (this.bmtrCostNumber > Number(this.detail.balances.bmtr || 0)) {
|
||
uni.showToast({
|
||
title: "BMTR数量不足",
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
|
||
this.submitting = true;
|
||
|
||
try {
|
||
await submitAssetBmtExchange({
|
||
amount: this.pointsValue,
|
||
type: this.redeemType,
|
||
}, {
|
||
showLoading: true,
|
||
loadingText: "兑换中",
|
||
});
|
||
this.confirmVisible = false;
|
||
this.form.points = "";
|
||
uni.showToast({
|
||
title: "兑换成功",
|
||
icon: "none",
|
||
});
|
||
this.loadPage();
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: error.message || "兑换失败",
|
||
icon: "none",
|
||
});
|
||
} finally {
|
||
this.submitting = false;
|
||
}
|
||
},
|
||
openLedger() {
|
||
uni.navigateTo({
|
||
url: "/pages/assets/ledger?type=bmt",
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "../../styles/tokens.scss";
|
||
@import "../../styles/common.scss";
|
||
|
||
.bmt-page {
|
||
min-height: 100vh;
|
||
background: #191e32;
|
||
}
|
||
|
||
.bmt-scroll {
|
||
padding: 8rpx 20rpx calc(env(safe-area-inset-bottom) + 36rpx);
|
||
}
|
||
|
||
.panel-card,
|
||
.hero-card {
|
||
border-radius: 12rpx;
|
||
background: #20263e;
|
||
}
|
||
|
||
.hero-card {
|
||
position: relative;
|
||
min-height: 240rpx;
|
||
padding: 24rpx 28rpx;
|
||
overflow: hidden;
|
||
background: #20263e url("https://imgs.agrimedia.cn/bm-bmt/bmt2-header.png")
|
||
no-repeat center top / 100% 240rpx;
|
||
}
|
||
|
||
.hero-card__content {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.hero-card__coin-row {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.hero-card__coin {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, #18c5ff 0%, #1496ff 100%);
|
||
}
|
||
|
||
.hero-card__coin-image {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
}
|
||
|
||
.hero-card__coin-text {
|
||
margin-left: 16rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.hero-card__label {
|
||
margin-top: 34rpx;
|
||
font-size: 28rpx;
|
||
color: #9ba7ce;
|
||
}
|
||
|
||
.hero-card__value {
|
||
margin-top: 8rpx;
|
||
font-size: 48rpx;
|
||
font-weight: 800;
|
||
color: #ffffff;
|
||
line-height: 1.1;
|
||
}
|
||
|
||
.panel-card {
|
||
margin-top: 18rpx;
|
||
padding: 0 26rpx;
|
||
}
|
||
|
||
.info-card {
|
||
padding-top: 2rpx;
|
||
padding-bottom: 14rpx;
|
||
}
|
||
|
||
.info-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
min-height: 96rpx;
|
||
border-bottom: 1rpx solid #4e5a82;
|
||
}
|
||
|
||
.info-row--last {
|
||
border-bottom: 1rpx solid #4e5a82;
|
||
}
|
||
|
||
.info-row__left {
|
||
display: flex;
|
||
align-items: center;
|
||
min-width: 0;
|
||
}
|
||
|
||
.info-row__icon {
|
||
width: 34rpx;
|
||
height: 34rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.info-row__label {
|
||
margin-left: 20rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 400;
|
||
color: #eef2ff;
|
||
}
|
||
|
||
.info-row__value {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.info-row__price {
|
||
display: flex;
|
||
align-items: baseline;
|
||
}
|
||
|
||
.info-row__unit {
|
||
margin-left: 10rpx;
|
||
font-size: 22rpx;
|
||
color: rgba(184, 193, 218, 0.88);
|
||
}
|
||
|
||
.info-card__estimate {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: baseline;
|
||
padding-top: 18rpx;
|
||
font-size: 28rpx;
|
||
color: #1ad296;
|
||
}
|
||
|
||
.info-card__estimate-value {
|
||
margin: 0 10rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 800;
|
||
color: #2fe2a4;
|
||
}
|
||
|
||
.form-card {
|
||
padding-top: 18rpx;
|
||
padding-bottom: 20rpx;
|
||
}
|
||
|
||
.form-card__title {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.form-card__title-icon {
|
||
width: 34rpx;
|
||
height: 34rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.form-card__title-text {
|
||
margin-left: 14rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.scheme-tabs {
|
||
display: flex;
|
||
margin-top: 20rpx;
|
||
padding: 6rpx;
|
||
border-radius: 10rpx;
|
||
background: #191e32;
|
||
}
|
||
|
||
.scheme-tab {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex: 1;
|
||
min-width: 0;
|
||
height: 64rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 26rpx;
|
||
color: rgba(177, 187, 214, 0.76);
|
||
}
|
||
|
||
.scheme-tab--active {
|
||
background: #20b6f5;
|
||
font-weight: 700;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.form-input {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 20rpx;
|
||
padding: 0 20rpx;
|
||
border-radius: 10rpx;
|
||
background: #191e32;
|
||
}
|
||
|
||
.form-input__icon {
|
||
width: 34rpx;
|
||
height: 34rpx;
|
||
margin-right: 18rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.form-input__field {
|
||
flex: 1;
|
||
height: 98rpx;
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.form-input__suffix {
|
||
margin-left: 16rpx;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.preview-card {
|
||
margin-top: 18rpx;
|
||
padding: 12rpx 26rpx;
|
||
border-radius: 8rpx;
|
||
background: rgba(26, 210, 150, 0.1);
|
||
}
|
||
|
||
.preview-card__row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.preview-card__row + .preview-card__row {
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.preview-card__left {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.preview-card__icon {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
margin-right: 10rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.preview-card__label {
|
||
font-size: 26rpx;
|
||
color: rgba(26, 210, 150, 1);
|
||
}
|
||
|
||
.preview-card__label--light {
|
||
color: #ffffff;
|
||
}
|
||
|
||
.preview-card__value {
|
||
font-size: 26rpx;
|
||
font-weight: 800;
|
||
color: #1ad296;
|
||
}
|
||
|
||
.preview-card__value--light {
|
||
color: #ffffff;
|
||
}
|
||
|
||
.tips-block {
|
||
margin-top: 24rpx;
|
||
}
|
||
|
||
.tips-block__title {
|
||
display: block;
|
||
font-size: 24rpx;
|
||
color: rgba(190, 197, 219, 0.92);
|
||
}
|
||
|
||
.tips-block__item {
|
||
display: flex;
|
||
margin-top: 10rpx;
|
||
}
|
||
|
||
.tips-block__index,
|
||
.tips-block__text {
|
||
font-size: 24rpx;
|
||
color: #929dbf;
|
||
line-height: 44rpx;
|
||
color: rgba(166, 175, 204, 0.92);
|
||
}
|
||
|
||
.tips-block__index {
|
||
margin-right: 6rpx;
|
||
}
|
||
|
||
.tips-block__text {
|
||
flex: 1;
|
||
}
|
||
|
||
.action-wrap {
|
||
position: relative;
|
||
z-index: 30;
|
||
padding: 36rpx 22rpx 0;
|
||
}
|
||
|
||
.action-button {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
height: 88rpx;
|
||
border-radius: 999rpx;
|
||
background: linear-gradient(135deg, #20b6f5 0%, #1ca5e3 100%);
|
||
box-shadow: 0 16rpx 30rpx rgba(20, 119, 214, 0.16);
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #ffffff;
|
||
cursor: pointer;
|
||
touch-action: manipulation;
|
||
}
|
||
|
||
.action-link {
|
||
margin-top: 26rpx;
|
||
text-align: center;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #1fb4ff;
|
||
}
|
||
|
||
.popup-line {
|
||
margin-top: 14rpx;
|
||
}
|
||
</style>
|