新增BMTR转赠:转赠页BMTR选项卡、BMTR余额/手续费接口、BMTR转赠记录

This commit is contained in:
yankang 2026-08-05 10:43:17 +08:00
parent ee88485316
commit ce8d83b510
4 changed files with 185 additions and 25 deletions

View File

@ -269,8 +269,9 @@ function buildHomeOverview(balanceData, tickerData, userData) {
};
}
function buildTransferTips(feePercent) {
function buildTransferTips(feePercent, bmtrFeePercent) {
const percentText = toNumber(feePercent) || 10;
const bmtrPercentText = toNumber(bmtrFeePercent) || 10;
return {
points: [
@ -279,6 +280,10 @@ function buildTransferTips(feePercent) {
"转赠系统会扣除" + percentText + "%的手续费",
],
power: ["只能转赠1的整数倍", "转赠系统会扣除" + percentText + "%的手续费"],
bmtr: [
"只能转赠1的整数倍",
"转赠系统会扣除" + bmtrPercentText + "%的手续费",
],
};
}
@ -981,6 +986,58 @@ function mapTransferRecords(list) {
});
}
function mapBmtrTransferRecords(list) {
return normalizeListData(list).map(function (item) {
// 交易类型0 支出1 收入2 退回
const bmtrType = Number(item && item.bmtr_type);
const isIncome = bmtrType === 1 || bmtrType === 2;
const amountValue = Math.abs(toNumber(item && item.bmtr));
const orderSn = String(pickFirstValue(item, ["order_sn", "sn"]) || "");
const tipsText = String(
pickFirstValue(item, ["bmtr_type_tips", "title"]) || "",
);
const titleText =
tipsText ||
(bmtrType === 2 ? "BMTR退回" : isIncome ? "BMTR获赠" : "BMTR转赠");
const balanceValue = pickFirstValue(item, [
"bmtr_after",
"balance",
"after_balance",
]);
const feeValue = extractTransferTitleFeeValue({ title: tipsText });
return {
id: buildRecordId(item, "bmtr-transfer"),
title: titleText,
subtitle: orderSn ? "单号 " + orderSn : tipsText,
time: String(
pickFirstValue(item, ["add_time", "create_time", "created_at", "time"]) ||
"",
),
amount: (isIncome ? "+" : "-") + formatTransferRecordNumber(amountValue),
balance:
balanceValue !== ""
? "结余 " + formatTransferRecordNumber(balanceValue) + " BMTR"
: "",
balanceLabel:
balanceValue !== ""
? "剩余BMTR" + formatTransferRecordNumber(balanceValue)
: "本次到账BMTR",
assetLabel: "BMTR",
feeText:
feeValue !== ""
? "手续费: " + formatHomeNumber(toNumber(feeValue), 2)
: "",
directionLabel: bmtrType === 2 ? "退回" : isIncome ? "转入" : "转出",
actionSymbol: isIncome ? "+" : "-",
orderSn: orderSn,
tag: isIncome ? "收" : "赠",
tone: isIncome ? "success" : "danger",
cardTone: isIncome ? "success" : "danger",
};
});
}
function mapPointsConvertRecords(list) {
return normalizeListData(list).map(function (item) {
const rawTransferPointValue = pickFirstValue(item, [
@ -1495,6 +1552,30 @@ async function fetchTransferFeeData(requestOptions) {
);
}
async function fetchTransferBmtrFeeData(requestOptions) {
return fetchPayload(
createRequestOptions(
{
url: serviceConfig.ENDPOINTS.transferBmtrFee,
},
requestOptions,
),
"BMTR手续费比例加载失败",
);
}
async function fetchTransferBmtrBalanceData(requestOptions) {
return fetchPayload(
createRequestOptions(
{
url: serviceConfig.ENDPOINTS.transferBmtrBalance,
},
requestOptions,
),
"BMTR余额加载失败",
);
}
async function fetchWithdrawRateData(requestOptions) {
return fetchPayload(
createRequestOptions(
@ -1653,6 +1734,19 @@ async function fetchTransferLedgerData(pagination, requestOptions) {
);
}
async function fetchBmtrTransferLedgerData(pagination, requestOptions) {
return fetchPayload(
createRequestOptions(
{
url: serviceConfig.ENDPOINTS.transferBmtrList,
data: buildPagingRequestData({}, pagination),
},
requestOptions,
),
"BMTR转赠记录加载失败",
);
}
async function fetchWalletFlowListData(flowType, pagination, requestOptions) {
return fetchPayload(
createRequestOptions(
@ -1879,17 +1973,26 @@ export async function fetchTransferDetail(requestOptions) {
const result = await Promise.all([
fetchHomeBalanceData(requestOptions),
fetchTransferFeeData(requestOptions),
fetchTransferBmtrBalanceData(requestOptions),
fetchTransferBmtrFeeData(requestOptions),
]);
const balances = normalizeBalances(result[0]);
const feePercent = toNumber(result[1] && result[1].r) || 10;
const bmtrFeePercent = toNumber(result[3] && result[3].r) || 10;
// 转赠数量只能为整数,余额向下取整展示,避免全部赠送时超出实际可用
const bmtrBalance = Math.floor(
toNumber(result[2] && result[2].balance),
);
return {
balances: {
points: toFixedNumber(balances.points, 0),
power: toFixedNumber(balances.power, 0),
bmtr: String(bmtrBalance),
},
feePercent: feePercent,
tips: buildTransferTips(feePercent),
bmtrFeePercent: bmtrFeePercent,
tips: buildTransferTips(feePercent, bmtrFeePercent),
};
}
@ -1917,7 +2020,9 @@ export async function searchTransferUser(uid, requestOptions) {
}
export async function submitAssetTransfer(payload, requestOptions) {
const transferType = payload && payload.type === "power" ? "power" : "points";
const rawType = payload && payload.type;
const transferType =
rawType === "power" ? "power" : rawType === "bmtr" ? "bmtr" : "points";
const targetId = String(
payload && payload.targetId ? payload.targetId : "",
).trim();
@ -1931,15 +2036,21 @@ export async function submitAssetTransfer(payload, requestOptions) {
throw createError("请输入转赠数量");
}
const submitUrl =
transferType === "power"
? serviceConfig.ENDPOINTS.transferPowerSubmit
: transferType === "bmtr"
? serviceConfig.ENDPOINTS.transferBmtrSubmit
: serviceConfig.ENDPOINTS.transferPointsSubmit;
const result = await Promise.all([
fetchTransferFeeData(requestOptions),
transferType === "bmtr"
? fetchTransferBmtrFeeData(requestOptions)
: fetchTransferFeeData(requestOptions),
fetchPayload(
createRequestOptions(
{
url:
transferType === "power"
? serviceConfig.ENDPOINTS.transferPowerSubmit
: serviceConfig.ENDPOINTS.transferPointsSubmit,
url: submitUrl,
method: "POST",
data: {
uid: targetId,
@ -2224,6 +2335,20 @@ export async function fetchLedgerDetail(
};
}
if (type === "bmtr-transfer") {
const data = await fetchBmtrTransferLedgerData(
pagination,
mergedRequestOptions,
);
return {
type: type,
title: "转赠记录",
subtitle: "BMTR转赠流水",
records: mapBmtrTransferRecords(data),
pagination: buildPaginationMeta(data, pagination),
};
}
if (type === "points") {
const data = await fetchWalletFlowListData(
0,

View File

@ -22,6 +22,10 @@ const serviceConfig = {
transferPowerSubmit: "/api/hn/transfer/transferPower",
transferPointsSubmit: "/api/hn/transfer/transferPoint",
transferLedger: "/api/hn/transfer/transferList",
transferBmtrSubmit: "/api/hn/transfer/transferBmtr",
transferBmtrFee: "/api/hn/transfer/getPropBmtr",
transferBmtrBalance: "/api/hn/transfer/getBmtrBalance",
transferBmtrList: "/api/hn/transfer/getBmtrList",
walletFlowList: "/api/hn/wallet_flow/getList",
redeemRecordList: "/api/hn/redeem/redeemList",
coinIndex: "/api/coin/index",

View File

@ -185,6 +185,7 @@ export default {
isTransferLedger() {
return [
"transfer",
"bmtr-transfer",
"points",
"power-flow",
"power",
@ -221,6 +222,7 @@ export default {
pageMark() {
const markMap = {
transfer: "⇄",
"bmtr-transfer": "B",
power: "⚡",
bmt: "D",
"bmt-flash": "D",
@ -234,6 +236,10 @@ export default {
},
onLoad(options) {
this.type = (options && options.type) || "transfer";
// value=bmtr BMTR
if (options && options.value === "bmtr") {
this.type = "bmtr-transfer";
}
this.resetPagingState();
this.loadPage(true, 1);
},

View File

@ -19,7 +19,7 @@
<view class="section-head">
<image
class="section-head__icon"
:src="pageIcon(activeTab === 'power' ? 'power' : 'points')"
:src="pageIcon(activeTab)"
mode="aspectFit"
></image>
<text class="section-head__title">{{ currentTabLabel }}转赠</text>
@ -206,6 +206,10 @@ export default {
label: "算力转赠",
value: "power",
},
{
label: "BMTR转赠",
value: "bmtr",
},
],
activeTab: "points",
targets: [],
@ -213,8 +217,10 @@ export default {
balances: {
points: "0",
power: "0",
bmtr: "0",
},
feePercent: 10,
bmtrFeePercent: 10,
tips: {
points: [],
power: [],
@ -235,7 +241,16 @@ export default {
},
computed: {
currentTabLabel() {
return this.activeTab === "power" ? "算力" : "可用积分";
if (this.activeTab === "power") {
return "算力";
}
if (this.activeTab === "bmtr") {
return "BMTR";
}
return "可用积分";
},
currentFeePercent() {
return this.activeTab === "bmtr" ? this.bmtrFeePercent : this.feePercent;
},
currentBalance() {
return Number(this.balances[this.activeTab] || 0);
@ -252,14 +267,21 @@ export default {
if (this.activeTab === "power") {
return [
"只能转赠1的整数倍",
"转赠系统会扣除" + this.feePercent + "%的手续费",
"转赠系统会扣除" + this.currentFeePercent + "%的手续费",
];
}
if (this.activeTab === "bmtr") {
return [
"只能转赠1的整数倍",
"转赠系统会扣除" + this.currentFeePercent + "%的手续费",
];
}
return [
"只能转赠1的整数倍",
"凌晨0点-凌晨01点系统维护不可赠送",
"转赠系统会扣除" + this.feePercent + "%的手续费",
"转赠系统会扣除" + this.currentFeePercent + "%的手续费",
];
},
currentTarget() {
@ -273,7 +295,7 @@ export default {
},
receivedDisplay() {
const received = this.amountValue
? this.amountValue * (1 - this.feePercent / 100)
? this.amountValue * (1 - this.currentFeePercent / 100)
: 0;
return this.formatAmount(received, 2);
},
@ -291,6 +313,7 @@ export default {
voucher: "https://imgs.agrimedia.cn/bm-bmt/quan-icon.png",
points: "https://imgs.agrimedia.cn/bm-bmt/j.png",
coupon: "https://imgs.agrimedia.cn/bm-bmt/xiaofei-icon.png",
bmtr: "https://imgs.agrimedia.cn/webimg/202607171808386371853.svg",
};
return iconMap[type] || "";
@ -327,6 +350,7 @@ export default {
);
this.balances = result.balances || this.balances;
this.feePercent = Number(result.feePercent || 10);
this.bmtrFeePercent = Number(result.bmtrFeePercent || 10);
this.tips = result.tips || this.tips;
} catch (error) {
uni.showToast({
@ -394,17 +418,14 @@ export default {
return;
}
if (this.activeTab === "points" && !Number.isInteger(this.amountValue)) {
if (!Number.isInteger(this.amountValue)) {
const unitMap = {
points: "积分",
power: "算力",
bmtr: "BMTR",
};
uni.showToast({
title: "积分只能转赠1的整数倍",
icon: "none",
});
return;
}
if (this.activeTab === "power" && !Number.isInteger(this.amountValue)) {
uni.showToast({
title: "算力只能转赠1的整数倍",
title: (unitMap[this.activeTab] || "数量") + "只能转赠1的整数倍",
icon: "none",
});
return;
@ -445,8 +466,9 @@ export default {
}
},
openLedger() {
const valueParam = this.activeTab === "bmtr" ? "&value=bmtr" : "";
uni.navigateTo({
url: "/pages/assets/ledger?type=transfer",
url: "/pages/assets/ledger?type=transfer" + valueParam,
});
},
},
@ -468,7 +490,8 @@ export default {
.mode-tabs {
display: flex;
width: 400rpx;
width: 620rpx;
max-width: 100%;
margin: 26rpx auto 0;
padding: 4rpx;
border-radius: 999rpx;
@ -482,9 +505,11 @@ export default {
justify-content: center;
flex: 1;
height: 60rpx;
padding: 0 12rpx;
border-radius: 999rpx;
font-size: 28rpx;
font-weight: 600;
white-space: nowrap;
color: rgba(210, 219, 242, 0.72);
}