This commit is contained in:
whitechiina 2026-04-27 18:12:36 +08:00
parent 952d3be4a9
commit d593b51ff9
16 changed files with 592 additions and 153 deletions

20
App.vue
View File

@ -35,6 +35,26 @@ export default {
<style lang="scss"> <style lang="scss">
@import "./styles/tokens.scss"; @import "./styles/tokens.scss";
@font-face {
font-family: "DIN-Bold";
src:
url("/static/fonts/din-bold-2.ttf") format("truetype"),
url("https://imgs.agrimedia.cn/din-bold-2.ttf") format("truetype");
font-style: normal;
font-weight: 800;
font-display: swap;
}
.asset-number-font {
font-family:
"DIN-Bold",
"PingFang SC",
"Helvetica Neue",
Arial,
sans-serif !important;
font-variant-numeric: tabular-nums;
}
html, html,
body, body,
#app { #app {

View File

@ -243,11 +243,298 @@ function buildWalletPayload(address) {
}; };
} }
function pickFirstValue(source, keys) {
const target = source && typeof source === "object" ? source : {};
for (let index = 0; index < keys.length; index += 1) {
const key = keys[index];
const value = target[key];
if (
value !== undefined &&
value !== null &&
!(typeof value === "string" && value.trim() === "")
) {
return value;
}
}
return "";
}
function normalizeListData(data) {
if (Array.isArray(data)) {
return data;
}
if (data && Array.isArray(data.list)) {
return data.list;
}
return [];
}
function formatTransferRecordNumber(value) { function formatTransferRecordNumber(value) {
const number = toNumber(value); const number = toNumber(value);
return formatHomeNumber(number, Number.isInteger(number) ? 0 : 2); return formatHomeNumber(number, Number.isInteger(number) ? 0 : 2);
} }
function formatLedgerRecordNumber(value) {
return formatTransferRecordNumber(Math.abs(toNumber(value)));
}
function resolveRecordDirection(item, amountValue, positiveLabel, negativeLabel) {
const rawDirection = pickFirstValue(item, [
"io_type",
"in_out",
"direction",
"income_type",
"is_add",
"flow_type",
]);
if (rawDirection !== "") {
const directionText = String(rawDirection).toLowerCase();
if (
directionText === "1" ||
directionText === "in" ||
directionText === "income" ||
directionText === "add" ||
directionText === "+"
) {
return positiveLabel;
}
if (
directionText === "0" ||
directionText === "-1" ||
directionText === "out" ||
directionText === "expense" ||
directionText === "sub" ||
directionText === "-"
) {
return negativeLabel;
}
}
return toNumber(amountValue) >= 0 ? positiveLabel : negativeLabel;
}
function buildDirectionPresentation(direction) {
return {
income:
direction === "收入" ||
direction === "转入" ||
direction === "获得" ||
direction === "到账",
actionSymbol:
direction === "收入" ||
direction === "转入" ||
direction === "获得" ||
direction === "到账"
? "+"
: "-",
};
}
function buildRecordId(item, fallbackPrefix) {
return String(
pickFirstValue(item, [
"order_sn",
"trade_no",
"bill_no",
"sn",
"id",
"log_id",
"uid",
]) || fallbackPrefix + "-" + Math.random(),
);
}
function mapWalletFlowRecords(list, meta) {
return normalizeListData(list).map(function (item) {
const amountValue = pickFirstValue(item, [
"number",
"num",
"amount",
"change_num",
"value",
"money",
"bmt_num",
"power_num",
"point_num",
]);
const direction = resolveRecordDirection(item, amountValue, "收入", "支出");
const directionPresentation = buildDirectionPresentation(direction);
const orderSn = String(
pickFirstValue(item, ["order_sn", "trade_no", "bill_no", "sn"]) || "",
);
const noteText = String(
pickFirstValue(item, [
"remark",
"desc",
"memo",
"note",
"type_name",
"status_text",
]) || "",
);
const balanceValue = pickFirstValue(item, [
"balance",
"after_balance",
"surplus",
"remain",
"wallet_balance",
"usable_balance",
]);
const title =
pickFirstValue(item, ["title", "name", "type_name"]) ||
meta.title ||
meta.unit + "记录";
return {
id: buildRecordId(item, meta.key || "flow"),
title: title,
subtitle: orderSn ? "单号 " + orderSn : noteText || direction,
time: pickFirstValue(item, [
"add_time",
"create_time",
"created_at",
"time",
"update_time",
]),
amount:
directionPresentation.actionSymbol +
formatLedgerRecordNumber(amountValue),
balance:
balanceValue !== ""
? "结余 " + formatTransferRecordNumber(balanceValue) + " " + meta.unit
: "",
balanceLabel:
balanceValue !== ""
? "剩余" + meta.unit + "" + formatTransferRecordNumber(balanceValue)
: "当前" + meta.unit + "流水",
assetLabel: meta.unit,
feeText: noteText || (orderSn ? "单号 " + orderSn : meta.subtitle),
directionLabel: direction,
actionSymbol: directionPresentation.actionSymbol,
orderSn: orderSn,
tag: directionPresentation.income ? "收" : "支",
tone: directionPresentation.income ? "success" : "danger",
cardTone: directionPresentation.income ? "success" : "danger",
};
});
}
function buildRedeemConsumeText(item, meta) {
const fragments = [];
if (meta.type === 0) {
const voucherValue = pickFirstValue(item, [
"voucher_num",
"coin",
"deduct_coin",
"use_coin",
]);
const couponValue = pickFirstValue(item, [
"coupon_num",
"diamond",
"deduct_diamond",
"use_diamond",
]);
if (voucherValue !== "") {
fragments.push("抵用券 " + formatTransferRecordNumber(voucherValue));
}
if (couponValue !== "") {
fragments.push("消费券 " + formatTransferRecordNumber(couponValue));
}
} else {
const pointValue = pickFirstValue(item, [
"point",
"points",
"point_num",
"use_point",
"integral",
]);
const powerValue = pickFirstValue(item, [
"power",
"power_num",
"c_power",
"use_power",
]);
if (pointValue !== "") {
fragments.push("积分 " + formatTransferRecordNumber(pointValue));
}
if (powerValue !== "") {
fragments.push("算力 " + formatTransferRecordNumber(powerValue));
}
}
if (fragments.length) {
return "消耗" + fragments.join(" / ");
}
return String(
pickFirstValue(item, ["remark", "desc", "memo", "note", "status_text"]) ||
meta.subtitle ||
"",
);
}
function mapRedeemRecords(list, meta) {
return normalizeListData(list).map(function (item) {
const primaryValue = pickFirstValue(item, meta.amountKeys);
const orderSn = String(
pickFirstValue(item, ["order_sn", "trade_no", "bill_no", "sn"]) || "",
);
const balanceValue = pickFirstValue(item, [
"balance",
"after_balance",
"surplus",
"remain",
]);
const noteText = buildRedeemConsumeText(item, meta);
return {
id: buildRecordId(item, meta.key || "redeem"),
title:
pickFirstValue(item, ["title", "name", "type_name"]) ||
meta.title ||
"兑换记录",
subtitle: orderSn ? "单号 " + orderSn : noteText,
time: pickFirstValue(item, [
"add_time",
"create_time",
"created_at",
"time",
"update_time",
]),
amount: "+" + formatLedgerRecordNumber(primaryValue),
balance:
balanceValue !== ""
? "结余 " + formatTransferRecordNumber(balanceValue) + " " + meta.unit
: "",
balanceLabel:
balanceValue !== ""
? "剩余" + meta.unit + "" + formatTransferRecordNumber(balanceValue)
: "本次到账" + meta.unit,
assetLabel: meta.unit,
feeText: noteText,
directionLabel: "兑换",
actionSymbol: "+",
orderSn: orderSn,
tag: "兑",
tone: "success",
cardTone: "success",
};
});
}
function getTransferRecordUnit(item) { function getTransferRecordUnit(item) {
return Number(item && item.type) === 0 ? "算力" : "积分"; return Number(item && item.type) === 0 ? "算力" : "积分";
} }
@ -505,6 +792,30 @@ async function fetchTransferLedgerData(requestOptions) {
); );
} }
async function fetchWalletFlowListData(flowType, requestOptions) {
return fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.walletFlowList,
data: {
type: flowType,
},
}, requestOptions),
"资产流水加载失败",
);
}
async function fetchRedeemRecordListData(redeemType, requestOptions) {
return fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.redeemRecordList,
data: {
type: redeemType,
},
}, requestOptions),
"兑换记录加载失败",
);
}
export async function fetchAssetHome(requestOptions) { export async function fetchAssetHome(requestOptions) {
const result = await Promise.all([ const result = await Promise.all([
fetchPriceData(requestOptions), fetchPriceData(requestOptions),
@ -760,10 +1071,35 @@ export async function fetchWithdrawDetail(requestOptions) {
}; };
} }
export function submitAssetWithdraw(payload, requestOptions) { export async function submitAssetWithdraw(payload, requestOptions) {
return Promise.reject( const address = String(
createError("当前接口文档未提供 BMT 提取提交接口"), payload && payload.address ? payload.address : "",
).trim();
const amount = toNumber(payload && payload.amount);
if (!address) {
throw createError("请先添加钱包地址");
}
if (!amount) {
throw createError("请输入提取数量");
}
await fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.withdrawSubmit,
method: "POST",
data: {
address: address,
number: String(amount),
},
}, requestOptions),
"提取失败",
); );
return {
success: true,
};
} }
export async function fetchLedgerDetail(type, requestOptions) { export async function fetchLedgerDetail(type, requestOptions) {
@ -778,24 +1114,81 @@ export async function fetchLedgerDetail(type, requestOptions) {
} }
if (type === "points") { if (type === "points") {
const result = await Promise.all([ const data = await fetchWalletFlowListData(0, requestOptions);
fetchHomeBalanceData(requestOptions),
fetchPointsConvertList(requestOptions),
]);
const balances = normalizeBalances(result[0]);
const pointList = Array.isArray(result[1] && result[1].list)
? result[1].list
: [];
return { return {
type: type, type: type,
title: "我的积分", title: "我的积分",
subtitle: "可转换积分记录", subtitle: "可用积分收支记录",
summary: { records: mapWalletFlowRecords(data, {
label: "有效积分", key: "points",
value: toFixedNumber(balances.points, 0), unit: "积分",
}, title: "积分记录",
records: mapPointsConvertRecords(pointList), subtitle: "可用积分流水",
}),
};
}
if (type === "power-flow") {
const data = await fetchWalletFlowListData(1, requestOptions);
return {
type: type,
title: "算力记录",
subtitle: "算力收支记录",
records: mapWalletFlowRecords(data, {
key: "power-flow",
unit: "算力",
title: "算力记录",
subtitle: "算力流水",
}),
};
}
if (type === "power") {
const data = await fetchRedeemRecordListData(0, requestOptions);
return {
type: type,
title: "兑换记录",
subtitle: "算力兑换记录",
records: mapRedeemRecords(data, {
key: "power",
type: 0,
unit: "算力",
title: "兑换算力",
subtitle: "算力兑换",
amountKeys: ["power", "power_num", "c_power", "redeem_power", "num", "number"],
}),
};
}
if (type === "bmt") {
const data = await fetchRedeemRecordListData(1, requestOptions);
return {
type: type,
title: "兑换记录",
subtitle: "BMT兑换记录",
records: mapRedeemRecords(data, {
key: "bmt",
type: 1,
unit: "BMT",
title: "兑换BMT",
subtitle: "BMT兑换",
amountKeys: ["bmt", "bmt_num", "redeem_bmt", "num", "number"],
}),
};
}
if (type === "withdraw") {
const data = await fetchWalletFlowListData(2, requestOptions);
return {
type: type,
title: "提取记录",
subtitle: "BMT收支记录",
records: mapWalletFlowRecords(data, {
key: "withdraw",
unit: "BMT",
title: "BMT记录",
subtitle: "BMT流水",
}),
}; };
} }

View File

@ -23,15 +23,15 @@
:src="statusIcon" :src="statusIcon"
mode="aspectFit" mode="aspectFit"
></image> ></image>
<text v-if="message" class="popup-panel__status-text">{{ <text v-if="message" class="popup-panel__status-text asset-number-font">{{
message message
}}</text> }}</text>
</view> </view>
<text v-else-if="message" class="popup-panel__message">{{ <text v-else-if="message" class="popup-panel__message asset-number-font">{{
message message
}}</text> }}</text>
<text v-if="description" class="popup-panel__description">{{ <text v-if="description" class="popup-panel__description asset-number-font">{{
description description
}}</text> }}</text>
@ -169,8 +169,8 @@ export default {
} }
.popup-panel__title { .popup-panel__title {
font-size: 28rpx; font-size: 32rpx;
font-weight: 700; font-weight: 500;
color: #ffffff; color: #ffffff;
} }
@ -190,7 +190,7 @@ export default {
.popup-panel__message { .popup-panel__message {
display: block; display: block;
margin-top: 34rpx; margin-top: 34rpx;
font-size: 24rpx; font-size: 30rpx;
line-height: 1.8; line-height: 1.8;
color: #edf2ff; color: #edf2ff;
} }

View File

@ -12,18 +12,18 @@
<view class="record-item__head"> <view class="record-item__head">
<text class="record-item__title">{{ item.title }}</text> <text class="record-item__title">{{ item.title }}</text>
<text <text
class="record-item__amount" class="record-item__amount asset-number-font"
:class="'record-item__amount--' + (item.tone || 'info')" :class="'record-item__amount--' + (item.tone || 'info')"
> >
{{ item.amount }} {{ item.amount }}
</text> </text>
</view> </view>
<text v-if="item.subtitle" class="record-item__subtitle">{{ <text v-if="item.subtitle" class="record-item__subtitle asset-number-font">{{
item.subtitle item.subtitle
}}</text> }}</text>
<view class="record-item__meta"> <view class="record-item__meta">
<text class="record-item__time">{{ item.time }}</text> <text class="record-item__time asset-number-font">{{ item.time }}</text>
<text v-if="item.balance" class="record-item__balance">{{ <text v-if="item.balance" class="record-item__balance asset-number-font">{{
item.balance item.balance
}}</text> }}</text>
</view> </view>

View File

@ -11,9 +11,9 @@
@confirm="$emit('confirm')" @confirm="$emit('confirm')"
> >
<view class="wallet-dialog"> <view class="wallet-dialog">
<text v-if="message" class="wallet-dialog__message">{{ message }}</text> <text v-if="message" class="wallet-dialog__message asset-number-font">{{ message }}</text>
<view v-if="address" class="wallet-dialog__address">{{ address }}</view> <view v-if="address" class="wallet-dialog__address asset-number-font">{{ address }}</view>
<text v-if="description" class="wallet-dialog__description">{{ <text v-if="description" class="wallet-dialog__description asset-number-font">{{
description description
}}</text> }}</text>
</view> </view>

View File

@ -14,8 +14,11 @@ const serviceConfig = {
transferPowerSubmit: "/api/hn/transfer/transferPower", transferPowerSubmit: "/api/hn/transfer/transferPower",
transferPointsSubmit: "/api/hn/transfer/transferPoint", transferPointsSubmit: "/api/hn/transfer/transferPoint",
transferLedger: "/api/hn/transfer/transferList", transferLedger: "/api/hn/transfer/transferList",
walletFlowList: "/api/hn/wallet_flow/getList",
redeemRecordList: "/api/hn/redeem/redeemList",
walletDetail: "/api/hn/wallet/getWalletAddress", walletDetail: "/api/hn/wallet/getWalletAddress",
walletSave: "/api/hn/wallet/saveAddress", walletSave: "/api/hn/wallet/saveAddress",
withdrawSubmit: "/api/hn/wallet/withdraw",
pointsConvertList: "/api/integral/transferList", pointsConvertList: "/api/integral/transferList",
pointsConvertSubmit: "/api/integral/doTransfer", pointsConvertSubmit: "/api/integral/doTransfer",
pointsConvertInfo: "/api/integral/transferInfo", pointsConvertInfo: "/api/integral/transferInfo",

View File

@ -16,7 +16,7 @@
<text class="hero-card__coin-text">BMT</text> <text class="hero-card__coin-text">BMT</text>
</view> </view>
<text class="hero-card__label">可用BMT:</text> <text class="hero-card__label">可用BMT:</text>
<text class="hero-card__value">{{ displayBmt }}</text> <text class="hero-card__value asset-number-font">{{ displayBmt }}</text>
</view> </view>
</view> </view>
@ -30,7 +30,7 @@
></image> ></image>
<text class="info-row__label">我的抵用券</text> <text class="info-row__label">我的抵用券</text>
</view> </view>
<text class="info-row__value">{{ displayVoucher }}</text> <text class="info-row__value asset-number-font">{{ displayVoucher }}</text>
</view> </view>
<view class="info-row"> <view class="info-row">
@ -42,7 +42,7 @@
></image> ></image>
<text class="info-row__label">我的消费券</text> <text class="info-row__label">我的消费券</text>
</view> </view>
<text class="info-row__value">{{ displayCoupon }}</text> <text class="info-row__value asset-number-font">{{ displayCoupon }}</text>
</view> </view>
<view class="info-row info-row--last"> <view class="info-row info-row--last">
@ -55,14 +55,14 @@
<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">
<text class="info-row__value">{{ displayPrice }}</text> <text class="info-row__value asset-number-font">{{ displayPrice }}</text>
<text class="info-row__unit">CNY/BMT</text> <text class="info-row__unit">CNY/BMT</text>
</view> </view>
</view> </view>
<view class="info-card__estimate"> <view class="info-card__estimate">
<text>全部兑换预估可得</text> <text>全部兑换预估可得</text>
<text class="info-card__estimate-value">{{ allEstimateBmt }}</text> <text class="info-card__estimate-value asset-number-font">{{ allEstimateBmt }}</text>
<text>BMT</text> <text>BMT</text>
</view> </view>
</view> </view>
@ -80,7 +80,7 @@
<view class="form-input"> <view class="form-input">
<input <input
v-model="form.points" v-model="form.points"
class="form-input__field" class="form-input__field asset-number-font"
type="number" type="number"
placeholder="请输入积分数量" placeholder="请输入积分数量"
placeholder-class="form-input__placeholder" placeholder-class="form-input__placeholder"
@ -93,7 +93,7 @@
<view class="preview-card__left"> <view class="preview-card__left">
<text class="preview-card__label">预估兑换BMT</text> <text class="preview-card__label">预估兑换BMT</text>
</view> </view>
<text class="preview-card__value">{{ estimateBmt }}</text> <text class="preview-card__value asset-number-font">{{ estimateBmt }}</text>
</view> </view>
<view class="preview-card__row"> <view class="preview-card__row">
<view class="preview-card__left"> <view class="preview-card__left">
@ -101,7 +101,7 @@
>消耗算力</text >消耗算力</text
> >
</view> </view>
<text class="preview-card__value preview-card__value--light">{{ <text class="preview-card__value preview-card__value--light asset-number-font">{{
powerCost powerCost
}}</text> }}</text>
</view> </view>
@ -114,8 +114,8 @@
:key="tip" :key="tip"
class="tips-block__item" class="tips-block__item"
> >
<text class="tips-block__index">{{ index + 1 }}.</text> <text class="tips-block__index asset-number-font">{{ index + 1 }}.</text>
<text class="tips-block__text">{{ tip }}</text> <text class="tips-block__text asset-number-font">{{ tip }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -139,15 +139,15 @@
> >
<view class="popup-line"> <view class="popup-line">
<text class="meta-pair__label">输入积分</text> <text class="meta-pair__label">输入积分</text>
<text class="meta-pair__value">{{ formatAmount(pointsValue, 0) }}</text> <text class="meta-pair__value asset-number-font">{{ formatAmount(pointsValue, 0) }}</text>
</view> </view>
<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">{{ estimateBmt }}</text> <text class="meta-pair__value asset-number-font">{{ estimateBmt }}</text>
</view> </view>
<view class="popup-line"> <view class="popup-line">
<text class="meta-pair__label">消耗算力</text> <text class="meta-pair__label">消耗算力</text>
<text class="meta-pair__value">{{ powerCost }}</text> <text class="meta-pair__value asset-number-font">{{ powerCost }}</text>
</view> </view>
</asset-confirm-popup> </asset-confirm-popup>
</view> </view>

View File

@ -4,9 +4,11 @@
<view class="asset-scroll" :class="{ 'ledger-scroll': isTransferLedger }"> <view class="asset-scroll" :class="{ 'ledger-scroll': isTransferLedger }">
<template v-if="isTransferLedger"> <template v-if="isTransferLedger">
<view class="transfer-ledger-head"> <view class="transfer-ledger-head">
<text class="transfer-ledger-head__eyebrow">最近记录</text> <text class="transfer-ledger-head__eyebrow">{{
ledger.title || "记录"
}}</text>
<text class="transfer-ledger-head__desc">{{ <text class="transfer-ledger-head__desc">{{
ledger.subtitle || "积分与算力转赠流水" ledger.subtitle || "资产流水记录"
}}</text> }}</text>
</view> </view>
@ -36,7 +38,7 @@
}}</text> }}</text>
<text <text
v-if="item.orderSn || item.subtitle" v-if="item.orderSn || item.subtitle"
class="transfer-record-card__order" class="transfer-record-card__order asset-number-font"
> >
{{ item.orderSn ? "单号 " + item.orderSn : item.subtitle }} {{ item.orderSn ? "单号 " + item.orderSn : item.subtitle }}
</text> </text>
@ -47,7 +49,7 @@
item.assetLabel item.assetLabel
}}</text> }}</text>
<text <text
class="transfer-record-card__amount" class="transfer-record-card__amount asset-number-font"
:class=" :class="
'transfer-record-card__amount--' + 'transfer-record-card__amount--' +
(item.cardTone || item.tone || 'info') (item.cardTone || item.tone || 'info')
@ -61,16 +63,16 @@
<view <view
class="transfer-record-card__row transfer-record-card__row--middle" class="transfer-record-card__row transfer-record-card__row--middle"
> >
<text class="transfer-record-card__balance">{{ <text class="transfer-record-card__balance asset-number-font">{{
item.balanceLabel || item.balance item.balanceLabel || item.balance
}}</text> }}</text>
<text class="transfer-record-card__fee">{{ item.feeText }}</text> <text class="transfer-record-card__fee asset-number-font">{{ item.feeText }}</text>
</view> </view>
<view <view
class="transfer-record-card__row transfer-record-card__row--bottom" class="transfer-record-card__row transfer-record-card__row--bottom"
> >
<text class="transfer-record-card__time">{{ item.time }}</text> <text class="transfer-record-card__time asset-number-font">{{ item.time }}</text>
<text <text
class="transfer-record-card__direction" class="transfer-record-card__direction"
:class=" :class="
@ -86,9 +88,11 @@
</view> </view>
<view v-else class="transfer-empty"> <view v-else class="transfer-empty">
<text class="transfer-empty__title">暂无转赠记录</text> <text class="transfer-empty__title">{{
"暂无" + (ledger.title || "记录")
}}</text>
<text class="transfer-empty__desc"> <text class="transfer-empty__desc">
当前还没有积分或算力的转赠流水 {{ ledger.subtitle || "当前暂无相关流水记录。" }}
</text> </text>
</view> </view>
</template> </template>
@ -101,19 +105,19 @@
<text class="page-hero__text">{{ pageMark }}</text> <text class="page-hero__text">{{ pageMark }}</text>
</view> </view>
<text class="page-hero__value">{{ ledger.title || "记录" }}</text> <text class="page-hero__value">{{ ledger.title || "记录" }}</text>
<text v-if="ledger.subtitle" class="page-hero__desc">{{ <text v-if="ledger.subtitle" class="page-hero__desc asset-number-font">{{
ledger.subtitle ledger.subtitle
}}</text> }}</text>
</view> </view>
<view class="section glass-panel panel-block"> <view class="section glass-panel panel-block">
<text class="section-label">{{ ledger.title }}</text> <text class="section-label">{{ ledger.title }}</text>
<text class="section-subtitle">{{ ledger.subtitle }}</text> <text class="section-subtitle asset-number-font">{{ ledger.subtitle }}</text>
</view> </view>
<view v-if="ledger.summary" class="section glass-panel panel-block"> <view v-if="ledger.summary" class="section glass-panel panel-block">
<text class="section-label">{{ ledger.summary.label }}</text> <text class="section-label">{{ ledger.summary.label }}</text>
<text class="summary-hero">{{ ledger.summary.value }}</text> <text class="summary-hero asset-number-font">{{ ledger.summary.value }}</text>
</view> </view>
<view <view
@ -168,7 +172,16 @@ export default {
}, },
computed: { computed: {
isTransferLedger() { isTransferLedger() {
return this.type === "transfer"; return [
"transfer",
"points",
"power-flow",
"power",
"bmt",
"withdraw",
"voucher",
"coupon",
].indexOf(this.type) > -1;
}, },
currentList() { currentList() {
if (!this.ledger.recordsByTab || !this.activeTab) { if (!this.ledger.recordsByTab || !this.activeTab) {

View File

@ -16,13 +16,13 @@
<text class="hero-card__coin-text">积分</text> <text class="hero-card__coin-text">积分</text>
</view> </view>
<text class="hero-card__label">可用积分:</text> <text class="hero-card__label">可用积分:</text>
<text class="hero-card__value">{{ displayAvailablePoints }}</text> <text class="hero-card__value asset-number-font">{{ displayAvailablePoints }}</text>
</view> </view>
</view> </view>
<view class="pending-card"> <view class="pending-card">
<text class="pending-card__label">未转换积分释放中的积分</text> <text class="pending-card__label">未转换积分释放中的积分</text>
<text class="pending-card__value">{{ displayPendingPoints }}</text> <text class="pending-card__value asset-number-font">{{ displayPendingPoints }}</text>
</view> </view>
<view class="tips-block"> <view class="tips-block">
@ -31,8 +31,8 @@
:key="tip" :key="tip"
class="tips-block__item" class="tips-block__item"
> >
<text class="tips-block__index">{{ index + 1 }}.</text> <text class="tips-block__index asset-number-font">{{ index + 1 }}.</text>
<text class="tips-block__text">{{ tip }}</text> <text class="tips-block__text asset-number-font">{{ tip }}</text>
</view> </view>
</view> </view>

View File

@ -9,14 +9,14 @@
<view class="hero-card__coin"> <view class="hero-card__coin">
<image <image
class="hero-card__coin-image" class="hero-card__coin-image"
:src="pageIcon('power')" src="https://imgs.agrimedia.cn/bm-bmt/s-w.png"
mode="aspectFit" mode="aspectFit"
></image> ></image>
</view> </view>
<text class="hero-card__coin-text">算力</text> <text class="hero-card__coin-text">算力</text>
</view> </view>
<text class="hero-card__label">已有算力:</text> <text class="hero-card__label">已有算力:</text>
<text class="hero-card__value">{{ displayPower }}</text> <text class="hero-card__value asset-number-font">{{ displayPower }}</text>
</view> </view>
</view> </view>
@ -30,7 +30,7 @@
></image> ></image>
<text class="info-row__label">我的抵用券</text> <text class="info-row__label">我的抵用券</text>
</view> </view>
<text class="info-row__value">{{ displayVoucher }}</text> <text class="info-row__value asset-number-font">{{ displayVoucher }}</text>
</view> </view>
<view class="info-row"> <view class="info-row">
@ -42,7 +42,7 @@
></image> ></image>
<text class="info-row__label">我的消费券</text> <text class="info-row__label">我的消费券</text>
</view> </view>
<text class="info-row__value">{{ displayCoupon }}</text> <text class="info-row__value asset-number-font">{{ displayCoupon }}</text>
</view> </view>
<view class="info-row info-row--last"> <view class="info-row info-row--last">
@ -55,14 +55,14 @@
<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">
<text class="info-row__value">{{ displayPrice }}</text> <text class="info-row__value asset-number-font">{{ displayPrice }}</text>
<text class="info-row__unit">RMB/BMT</text> <text class="info-row__unit">RMB/BMT</text>
</view> </view>
</view> </view>
<view class="info-card__estimate"> <view class="info-card__estimate">
<text>全部兑换预估可得</text> <text>全部兑换预估可得</text>
<text class="info-card__estimate-value">{{ allEstimatePower }}</text> <text class="info-card__estimate-value asset-number-font">{{ allEstimatePower }}</text>
<text>算力</text> <text>算力</text>
</view> </view>
</view> </view>
@ -92,7 +92,7 @@
<view class="form-input"> <view class="form-input">
<input <input
v-model="form.amount" v-model="form.amount"
class="form-input__field" class="form-input__field asset-number-font"
type="number" type="number"
:placeholder="'请输入' + currentModeLabel + '数量'" :placeholder="'请输入' + currentModeLabel + '数量'"
placeholder-class="form-input__placeholder" placeholder-class="form-input__placeholder"
@ -105,7 +105,7 @@
<view class="preview-card__left"> <view class="preview-card__left">
<text class="preview-card__label">预估兑换算力</text> <text class="preview-card__label">预估兑换算力</text>
</view> </view>
<text class="preview-card__value">{{ estimatePower }}</text> <text class="preview-card__value asset-number-font">{{ estimatePower }}</text>
</view> </view>
</view> </view>
@ -116,8 +116,8 @@
:key="tip" :key="tip"
class="tips-block__item" class="tips-block__item"
> >
<text class="tips-block__index">{{ index + 1 }}.</text> <text class="tips-block__index asset-number-font">{{ index + 1 }}.</text>
<text class="tips-block__text">{{ tip }}</text> <text class="tips-block__text asset-number-font">{{ tip }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -489,6 +489,7 @@ export default {
font-size: 32rpx; font-size: 32rpx;
font-weight: 800; font-weight: 800;
line-height: 1.1; line-height: 1.1;
font-family: "DIN-Bold", DIN, sans-serif;
color: #ffffff; color: #ffffff;
} }

View File

@ -23,7 +23,7 @@
mode="aspectFit" mode="aspectFit"
></image> ></image>
<text class="section-head__title">{{ currentTabLabel }}转赠</text> <text class="section-head__title">{{ currentTabLabel }}转赠</text>
<text class="section-head__meta" <text class="section-head__meta asset-number-font"
>可用{{ currentBalanceDisplay }}</text >可用{{ currentBalanceDisplay }}</text
> >
</view> </view>
@ -31,7 +31,7 @@
<view class="input-bar"> <view class="input-bar">
<input <input
v-model="form.amount" v-model="form.amount"
class="input-bar__field" class="input-bar__field asset-number-font"
type="number" type="number"
:placeholder="amountPlaceholder" :placeholder="amountPlaceholder"
placeholder-class="input-bar__placeholder" placeholder-class="input-bar__placeholder"
@ -45,8 +45,8 @@
:key="tip" :key="tip"
class="tips-list__item" class="tips-list__item"
> >
<text class="tips-list__index">{{ index + 1 }}.</text> <text class="tips-list__index asset-number-font">{{ index + 1 }}.</text>
<text class="tips-list__text">{{ tip }}</text> <text class="tips-list__text asset-number-font">{{ tip }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -71,7 +71,7 @@
<view class="input-bar recipient-search"> <view class="input-bar recipient-search">
<input <input
v-model="searchId" v-model="searchId"
class="input-bar__field" class="input-bar__field asset-number-font"
type="number" type="number"
placeholder="请输入被赠人ID" placeholder="请输入被赠人ID"
placeholder-class="input-bar__placeholder" placeholder-class="input-bar__placeholder"
@ -85,7 +85,7 @@
@click="selectCurrent" @click="selectCurrent"
> >
<view class="target-card__top"> <view class="target-card__top">
<text class="target-card__id">ID: {{ currentTarget.id }}</text> <text class="target-card__id asset-number-font">ID: {{ currentTarget.id }}</text>
<view class="target-card__select"> <view class="target-card__select">
<text class="target-card__select-text">选择</text> <text class="target-card__select-text">选择</text>
<view class="target-card__select-dot"></view> <view class="target-card__select-dot"></view>
@ -135,15 +135,15 @@
@confirm="submit" @confirm="submit"
> >
<view class="confirm-detail"> <view class="confirm-detail">
<text class="confirm-detail__summary"> <text class="confirm-detail__summary asset-number-font">
转赠{{ currentTabLabel }}{{ amountDisplay }} 转赠{{ currentTabLabel }}{{ amountDisplay }}
<text class="confirm-detail__summary-sub" <text class="confirm-detail__summary-sub asset-number-font"
>实际到账{{ receivedDisplay }}</text >实际到账{{ receivedDisplay }}</text
> >
</text> </text>
<view class="confirm-detail__target"> <view class="confirm-detail__target">
<text class="confirm-detail__id">ID: {{ currentTarget.id }}</text> <text class="confirm-detail__id asset-number-font">ID: {{ currentTarget.id }}</text>
<view class="confirm-detail__line"></view> <view class="confirm-detail__line"></view>
<view class="confirm-detail__profile"> <view class="confirm-detail__profile">
<view class="target-card__profile"> <view class="target-card__profile">

View File

@ -18,7 +18,7 @@
<view class="wallet-input"> <view class="wallet-input">
<input <input
v-model="form.address" v-model="form.address"
class="wallet-input__field" class="wallet-input__field asset-number-font"
type="text" type="text"
:placeholder="form.id ? '粘贴新钱包地址' : '粘贴新钱包地址'" :placeholder="form.id ? '粘贴新钱包地址' : '粘贴新钱包地址'"
placeholder-class="wallet-input__placeholder" placeholder-class="wallet-input__placeholder"
@ -264,7 +264,7 @@ export default {
.wallet-form-panel__subtitle { .wallet-form-panel__subtitle {
margin-left: 16rpx; margin-left: 16rpx;
max-width: 280rpx; max-width: 280rpx;
font-size: 22rpx; font-size: 26rpx;
line-height: 1.4; line-height: 1.4;
text-align: right; text-align: right;
flex-shrink: 0; flex-shrink: 0;
@ -285,7 +285,7 @@ export default {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
height: 94rpx; height: 94rpx;
font-size: 22rpx; font-size: 28rpx;
color: #ffffff; color: #ffffff;
} }
@ -295,15 +295,15 @@ export default {
.wallet-input__paste { .wallet-input__paste {
margin-left: 18rpx; margin-left: 18rpx;
font-size: 24rpx; font-size: 28rpx;
font-weight: 700; font-weight: 500;
color: #1fb7f9; color: #1fb7f9;
} }
.wallet-form-panel__helper { .wallet-form-panel__helper {
display: block; display: block;
margin-top: 18rpx; margin-top: 18rpx;
font-size: 22rpx; font-size: 26rpx;
line-height: 1.6; line-height: 1.6;
color: rgba(174, 183, 211, 0.82); color: rgba(174, 183, 211, 0.82);
} }

View File

@ -1,6 +1,14 @@
<template> <template>
<view class="asset-page asset-theme wallet-page"> <view class="asset-page asset-theme wallet-page">
<asset-page-shell title="钱包地址" /> <view class="wallet-nav">
<view class="wallet-nav__side">
<view class="wallet-nav__back" @click="handleBack">
<text class="wallet-nav__back-icon"></text>
</view>
</view>
<text class="wallet-nav__title">钱包地址</text>
<view class="wallet-nav__side"></view>
</view>
<view class="asset-scroll wallet-scroll"> <view class="asset-scroll wallet-scroll">
<view class="wallet-panel"> <view class="wallet-panel">
@ -39,7 +47,7 @@
<view class="wallet-actions"> <view class="wallet-actions">
<view class="wallet-button wallet-button--primary" @click="openForm()"> <view class="wallet-button wallet-button--primary" @click="openForm()">
{{ currentWallet ? "修改钱包地址" : "新增钱包地址" }} {{ currentWallet ? "修改钱包地址" : "保存" }}
</view> </view>
<view <view
class="wallet-button wallet-button--secondary" class="wallet-button wallet-button--secondary"
@ -72,33 +80,24 @@
</template> </template>
<script> <script>
import AssetPageShell from "../../components/asset-page-shell.vue";
import WalletActionPopup from "../../components/wallet-action-popup.vue"; import WalletActionPopup from "../../components/wallet-action-popup.vue";
import { fetchWalletDetail, deleteAssetWallet } from "../../api/assets"; import { fetchWalletDetail, deleteAssetWallet } from "../../api/assets";
export default { export default {
components: { components: {
AssetPageShell,
WalletActionPopup, WalletActionPopup,
}, },
data() { data() {
return { return {
hasShown: false,
wallets: [], wallets: [],
deleteDialogVisible: false, deleteDialogVisible: false,
removing: false,
}; };
}, },
onLoad() { onLoad() {
this.loadPage(true); this.loadPage();
}, },
onShow() { onShow() {
if (this.hasShown) {
this.loadPage(); this.loadPage();
return;
}
this.hasShown = true;
}, },
computed: { computed: {
currentWallet() { currentWallet() {
@ -112,16 +111,9 @@ export default {
}, },
}, },
methods: { methods: {
async loadPage(showLoading) { async loadPage() {
try { try {
const result = await fetchWalletDetail( const result = await fetchWalletDetail();
showLoading
? {
showLoading: true,
loadingText: "加载中",
}
: null,
);
this.wallets = result.wallets || []; this.wallets = result.wallets || [];
} catch (error) { } catch (error) {
uni.showToast({ uni.showToast({
@ -172,17 +164,8 @@ export default {
return; return;
} }
if (this.removing) {
return;
}
this.removing = true;
try { try {
await deleteAssetWallet(this.currentWallet.id, { await deleteAssetWallet(this.currentWallet.id);
showLoading: true,
loadingText: "删除中",
});
this.deleteDialogVisible = false; this.deleteDialogVisible = false;
uni.showToast({ uni.showToast({
title: "删除成功", title: "删除成功",
@ -194,8 +177,6 @@ export default {
title: error.message || "删除失败", title: error.message || "删除失败",
icon: "none", icon: "none",
}); });
} finally {
this.removing = false;
} }
}, },
}, },
@ -211,6 +192,40 @@ export default {
background: #191e32; background: #191e32;
} }
.wallet-nav {
display: grid;
grid-template-columns: 120rpx 1fr 120rpx;
align-items: center;
padding: calc(env(safe-area-inset-top) + 12rpx) 14rpx 12rpx;
}
.wallet-nav__side {
display: flex;
align-items: center;
}
.wallet-nav__back {
display: flex;
align-items: center;
justify-content: center;
width: 56rpx;
height: 56rpx;
}
.wallet-nav__back-icon {
margin-top: -4rpx;
font-size: 56rpx;
line-height: 1;
color: #ffffff;
}
.wallet-nav__title {
text-align: center;
font-size: 36rpx;
font-weight: 700;
color: #ffffff;
}
.wallet-scroll { .wallet-scroll {
min-height: calc(100vh - env(safe-area-inset-top) - 104rpx); min-height: calc(100vh - env(safe-area-inset-top) - 104rpx);
display: flex; display: flex;

View File

@ -16,8 +16,8 @@
<text class="hero-card__coin-text">BMT</text> <text class="hero-card__coin-text">BMT</text>
</view> </view>
<text class="hero-card__label">本地钱包可提取BMT:</text> <text class="hero-card__label">本地钱包可提取BMT:</text>
<text class="hero-card__value">{{ displayWithdrawable }}</text> <text class="hero-card__value asset-number-font">{{ displayWithdrawable }}</text>
<text class="hero-card__price" <text class="hero-card__price asset-number-font"
>(BMT实时价格 {{ displayPrice }}CNY/BMT)</text >(BMT实时价格 {{ displayPrice }}CNY/BMT)</text
> >
</view> </view>
@ -36,7 +36,7 @@
<view class="amount-input"> <view class="amount-input">
<input <input
v-model="form.amount" v-model="form.amount"
class="amount-input__field" class="amount-input__field asset-number-font"
type="number" type="number"
placeholder="请输入提取数量" placeholder="请输入提取数量"
placeholder-class="amount-input__placeholder" placeholder-class="amount-input__placeholder"
@ -45,8 +45,8 @@
</view> </view>
<view class="fee-card"> <view class="fee-card">
<text class="fee-card__label">提取手续费1%</text> <text class="fee-card__label asset-number-font">提取手续费1%</text>
<text class="fee-card__value">{{ feeText }}</text> <text class="fee-card__value asset-number-font">{{ feeText }}</text>
</view> </view>
</view> </view>
@ -76,7 +76,7 @@
<text class="wallet-box__action" @click="copyWallet">复制</text> <text class="wallet-box__action" @click="copyWallet">复制</text>
</view> </view>
</view> </view>
<text class="wallet-box__address">{{ walletDisplayAddress }}</text> <text class="wallet-box__address asset-number-font">{{ walletDisplayAddress }}</text>
</view> </view>
<view v-else class="wallet-box wallet-box--empty" @click="openWallet"> <view v-else class="wallet-box wallet-box--empty" @click="openWallet">
@ -107,17 +107,17 @@
<view class="popup-detail"> <view class="popup-detail">
<view class="popup-detail__row"> <view class="popup-detail__row">
<text class="meta-pair__label">钱包地址</text> <text class="meta-pair__label">钱包地址</text>
<text class="meta-pair__value popup-address">{{ <text class="meta-pair__value popup-address asset-number-font">{{
detail.defaultWallet ? detail.defaultWallet.address : "未设置" detail.defaultWallet ? detail.defaultWallet.address : "未设置"
}}</text> }}</text>
</view> </view>
<view class="popup-detail__row"> <view class="popup-detail__row">
<text class="meta-pair__label">手续费</text> <text class="meta-pair__label">手续费</text>
<text class="meta-pair__value">{{ feeText }}</text> <text class="meta-pair__value asset-number-font">{{ feeText }}</text>
</view> </view>
<view class="popup-detail__row"> <view class="popup-detail__row">
<text class="meta-pair__label">预计到账</text> <text class="meta-pair__label">预计到账</text>
<text class="meta-pair__value">{{ actualText }}</text> <text class="meta-pair__value asset-number-font">{{ actualText }}</text>
</view> </view>
</view> </view>
</asset-confirm-popup> </asset-confirm-popup>
@ -324,7 +324,7 @@ export default {
try { try {
await submitAssetWithdraw({ await submitAssetWithdraw({
amount: this.amountValue, amount: this.amountValue,
walletId: this.detail.defaultWallet.id, address: this.detail.defaultWallet.address,
}, { }, {
showLoading: true, showLoading: true,
loadingText: "提交中", loadingText: "提交中",
@ -610,7 +610,7 @@ export default {
} }
.wallet-box__empty-text { .wallet-box__empty-text {
font-size: 22rpx; font-size: 26rpx;
font-weight: 600; font-weight: 600;
color: #20b6f5; color: #20b6f5;
} }

View File

@ -25,10 +25,20 @@
class="stat-card" class="stat-card"
:class="'stat-card--' + item.accent" :class="'stat-card--' + item.accent"
> >
<view
class="stat-card__icon-box"
:class="'stat-card__icon-box--' + item.accent"
>
<image
class="stat-card__icon-image"
:src="statIcon(item.key)"
mode="aspectFit"
></image>
</view>
<view class="stat-card__body"> <view class="stat-card__body">
<text class="stat-card__label">{{ item.title }}</text> <text class="stat-card__label">{{ item.title }}</text>
<view class="stat-card__value-row"> <view class="stat-card__value-row">
<text class="stat-card__value">{{ item.value }}</text> <text class="stat-card__value asset-number-font">{{ item.value }}</text>
<text class="stat-card__unit">{{ item.unit }}</text> <text class="stat-card__unit">{{ item.unit }}</text>
</view> </view>
</view> </view>
@ -45,7 +55,6 @@
v-for="item in overview.quickAssets" v-for="item in overview.quickAssets"
:key="item.key" :key="item.key"
class="asset-mini-card" class="asset-mini-card"
:class="'asset-mini-card--' + item.accent"
@click="openQuickAsset(item)" @click="openQuickAsset(item)"
> >
<image <image
@ -63,7 +72,7 @@
</view> </view>
<text class="asset-mini-card__label">{{ item.title }}</text> <text class="asset-mini-card__label">{{ item.title }}</text>
</view> </view>
<text class="asset-mini-card__value">{{ item.value }}</text> <text class="asset-mini-card__value asset-number-font">{{ item.value }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -205,7 +214,7 @@ export default {
points: "/pages/assets/ledger?type=points", points: "/pages/assets/ledger?type=points",
voucher: "/pages/assets/ledger?type=voucher", voucher: "/pages/assets/ledger?type=voucher",
coupon: "/pages/assets/ledger?type=coupon", coupon: "/pages/assets/ledger?type=coupon",
power: "/pages/assets/ledger?type=power", power: "/pages/assets/ledger?type=power-flow",
}; };
const targetUrl = urlMap[item.key]; const targetUrl = urlMap[item.key];
@ -260,6 +269,7 @@ export default {
align-items: center; align-items: center;
height: 52rpx; height: 52rpx;
color: rgba(229, 235, 255, 0.82); color: rgba(229, 235, 255, 0.82);
padding-right: 10rpx;
} }
.home-wallet-btn__icon { .home-wallet-btn__icon {
@ -481,22 +491,6 @@ export default {
height: 100%; height: 100%;
} }
.asset-mini-card--blue {
background: linear-gradient(135deg, #10acee 0%, #1aa4ff 100%);
}
.asset-mini-card--green {
background: linear-gradient(135deg, #25d8a4 0%, #36e08f 100%);
}
.asset-mini-card--orange {
background: linear-gradient(135deg, #ff8d58 0%, #ff7d7d 100%);
}
.asset-mini-card--violet {
background: linear-gradient(135deg, #a667f3 0%, #b27cff 100%);
}
.asset-mini-card__head, .asset-mini-card__head,
.asset-mini-card__value { .asset-mini-card__value {
position: relative; position: relative;
@ -505,8 +499,9 @@ export default {
.asset-mini-card__head { .asset-mini-card__head {
display: flex; display: flex;
font-size: 26rpx;
align-items: center; align-items: center;
min-width: 0;
font-size: 26rpx;
} }
.asset-mini-card__icon { .asset-mini-card__icon {
@ -604,7 +599,6 @@ export default {
height: 28rpx; height: 28rpx;
margin-right: 8rpx; margin-right: 8rpx;
margin-top: 4rpx; margin-top: 4rpx;
border-radius: 50%;
background: linear-gradient(180deg, #ffd764 0%, #ffbb2e 100%); background: linear-gradient(180deg, #ffd764 0%, #ffbb2e 100%);
font-size: 16rpx; font-size: 16rpx;
font-weight: 700; font-weight: 700;

BIN
static/fonts/din-bold-2.ttf Normal file

Binary file not shown.