This commit is contained in:
whitechiina 2026-04-30 17:50:37 +08:00
parent df61e1614d
commit 394c32ded2
27 changed files with 676 additions and 57 deletions

187
App.vue
View File

@ -4,14 +4,144 @@ import {
refreshCurrentWebviewToken,
} from "./utils/webview-token";
let numberFontSupportPromise = null;
let numberFontSupportState = null;
function hasBrowserDom() {
return typeof window !== "undefined" && typeof document !== "undefined";
}
function toggleNumberFontReadyClass(enabled) {
if (!hasBrowserDom() || !document.documentElement) {
return;
}
document.documentElement.classList.toggle(
"asset-din-font-ready",
Boolean(enabled),
);
}
function waitForBodyReady() {
return new Promise((resolve) => {
if (!hasBrowserDom() || document.body) {
resolve();
return;
}
const finish = () => resolve();
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", finish, {
once: true,
});
return;
}
setTimeout(finish, 0);
});
}
function createMeasureNode(fontFamily) {
const node = document.createElement("span");
node.textContent = "0123456789";
node.style.position = "absolute";
node.style.left = "-99999px";
node.style.top = "-99999px";
node.style.visibility = "hidden";
node.style.whiteSpace = "nowrap";
node.style.fontSize = "32px";
node.style.fontWeight = "800";
node.style.fontFamily = fontFamily;
return node;
}
function verifyDinFontRender() {
if (!hasBrowserDom() || !document.body) {
return false;
}
const container = document.createElement("div");
container.style.position = "absolute";
container.style.left = "-99999px";
container.style.top = "-99999px";
container.style.visibility = "hidden";
container.style.pointerEvents = "none";
const fallbackFamilies = ["monospace", "sans-serif", "serif"];
const loadedWidths = [];
const fallbackWidths = [];
fallbackFamilies.forEach((family) => {
const fallbackNode = createMeasureNode(family);
const loadedNode = createMeasureNode('"DIN-Bold", ' + family);
container.appendChild(fallbackNode);
container.appendChild(loadedNode);
});
document.body.appendChild(container);
Array.prototype.forEach.call(container.childNodes, (node, index) => {
const width = node.getBoundingClientRect().width;
if (index % 2 === 0) {
fallbackWidths.push(width);
return;
}
loadedWidths.push(width);
});
const isFontAvailable = fallbackWidths.some((width, index) => {
return Math.abs(loadedWidths[index] - width) > 0.1;
});
document.body.removeChild(container);
return isFontAvailable;
}
async function ensureNumberFontSupport() {
if (!hasBrowserDom()) {
return false;
}
if (!document.fonts || typeof document.fonts.load !== "function") {
return false;
}
await waitForBodyReady();
const loadSucceeded = await Promise.race([
document.fonts
.load('800 32px "DIN-Bold"', "0123456789")
.then((fonts) => Array.isArray(fonts) ? fonts.length > 0 : true)
.catch(() => false),
new Promise((resolve) => {
setTimeout(() => resolve(false), 2500);
}),
]);
if (
!loadSucceeded ||
!document.fonts.check('800 32px "DIN-Bold"', "0123456789")
) {
return false;
}
return verifyDinFontRender();
}
export default {
onLaunch: function () {
console.log("App Launch");
this.logCurrentWebviewToken("launch");
this.syncNumberFontSupport();
},
onShow: function () {
console.log("App Show");
this.logCurrentWebviewToken("show");
this.syncNumberFontSupport();
},
onHide: function () {
console.log("App Hide");
@ -28,6 +158,31 @@ export default {
console.log("[webview-token][" + scene + "] token not found", currentUrl);
},
async syncNumberFontSupport() {
if (!hasBrowserDom()) {
return;
}
if (numberFontSupportState !== null) {
toggleNumberFontReadyClass(numberFontSupportState);
return;
}
if (!numberFontSupportPromise) {
numberFontSupportPromise = ensureNumberFontSupport()
.then((result) => {
numberFontSupportState = Boolean(result);
return numberFontSupportState;
})
.catch(() => {
numberFontSupportState = false;
return false;
});
}
const canUseDinFont = await numberFontSupportPromise;
toggleNumberFontReadyClass(canUseDinFont);
},
},
};
</script>
@ -38,20 +193,38 @@ export default {
@font-face {
font-family: "DIN-Bold";
src:
local("DIN-Bold"),
local("DIN Bold"),
local("DIN Alternate Bold"),
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;
font-display: optional;
}
:root {
--asset-number-font-family:
"Helvetica Neue",
Arial,
"PingFang SC",
sans-serif;
--asset-number-font-family-din:
"DIN-Bold",
DIN,
"DIN Alternate",
"Helvetica Neue",
Arial,
"PingFang SC",
sans-serif;
}
.asset-din-font-ready {
--asset-number-font-family: var(--asset-number-font-family-din);
}
.asset-number-font {
font-family:
"DIN-Bold",
"PingFang SC",
"Helvetica Neue",
Arial,
sans-serif !important;
font-family: var(--asset-number-font-family) !important;
font-variant-numeric: tabular-nums;
}

View File

@ -254,7 +254,7 @@ function buildTransferTips(feePercent) {
return {
points: [
"只能转赠100的整数倍",
"凌晨0点-凌晨01点系统维护不可赠送",
"凌晨00:00至02:00为系统维护时段不可赠送",
"转赠系统会扣除" + percentText + "%的手续费",
],
power: [
@ -873,7 +873,7 @@ function getTransferRecordFee(item) {
function getTransferRecordFeeText(item) {
const percent = toNumber(item && item.fee_percent);
const unit = getTransferRecordUnit(item);
const feeText = formatTransferRecordNumber(getTransferRecordFee(item));
const feeText = formatHomeNumber(getTransferRecordFee(item), 2);
if (percent > 0) {
return (
@ -1368,6 +1368,15 @@ async function fetchBmtPowerRateData(requestOptions) {
);
}
async function fetchPowerExchangeMuitData(requestOptions) {
return fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.powerExchangeMuit,
}, requestOptions),
"兑换倍率加载失败",
);
}
function resolveRedeemPowerRate(data) {
const sourceValue =
data && typeof data === "object"
@ -1397,6 +1406,45 @@ async function fetchTransferFeeData(requestOptions) {
);
}
async function fetchWithdrawRateData(requestOptions) {
return fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.withdrawRate,
}, requestOptions),
"提现费率加载失败",
);
}
function resolvePercentRate(data) {
let sourceValue =
data && typeof data === "object"
? pickFirstValue(data, [
"r",
"rate",
"fee_rate",
"feeRate",
"withdraw_rate",
"withdrawRate",
"prop",
"value",
"num",
"number",
])
: data;
if (typeof sourceValue === "string") {
sourceValue = sourceValue.replace(/%/g, "").trim();
}
const rate = toNumber(sourceValue);
if (rate > 0 && rate < 1) {
return rate * 100;
}
return rate;
}
async function fetchWalletAddressData(requestOptions) {
return fetchPayload(
createRequestOptions({
@ -1406,6 +1454,24 @@ async function fetchWalletAddressData(requestOptions) {
);
}
async function fetchCoinIndexData(requestOptions) {
return fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.coinIndex,
}, requestOptions),
"抵用券信息加载失败",
);
}
async function fetchUserProfileData(requestOptions) {
return fetchPayload(
createRequestOptions({
url: serviceConfig.ENDPOINTS.userProfile,
}, requestOptions),
"用户信息加载失败",
);
}
function normalizePointsConvertInterval(value) {
const rawInterval = String(
value === undefined || value === null ? "" : value,
@ -1511,6 +1577,40 @@ export async function fetchAssetHome(requestOptions) {
return overview;
}
export async function fetchVoucherBrokerLinkData(requestOptions) {
const data = await fetchCoinIndexData(requestOptions);
const userId = pickFirstValue(data, ["user_id", "uid", "id"]);
const balance = pickFirstValue(data, ["balance", "coin", "total"]);
if (userId === "") {
throw createError("未获取到用户信息", data);
}
return {
userId: String(userId),
balance: balance === "" ? "0" : String(balance),
};
}
export async function fetchCouponRedeemLinkData(requestOptions) {
const userInfo = await fetchUserProfileData(requestOptions);
const canRedeem = pickFirstValue(userInfo, [
"is_show_merchant_button",
"canRedeem",
"can_redeem",
]);
const targetUrl =
serviceConfig.HTTP_REQUEST_URL +
"/MD/pages/redeemVoucher/index?canRedeem=" +
encodeURIComponent(canRedeem === "" ? "0" : String(canRedeem));
return {
canRedeem: canRedeem === "" ? "0" : String(canRedeem),
targetUrl: targetUrl,
encodedTargetUrl: encodeURIComponent(targetUrl),
};
}
export async function fetchPointsConvertHome(month, requestOptions) {
const result = await Promise.all([
fetchHomeBalanceData(requestOptions),
@ -1696,18 +1796,21 @@ export async function fetchPowerExchangeDetail(requestOptions) {
const result = await Promise.all([
fetchPriceData(requestOptions),
fetchHomeBalanceData(requestOptions),
fetchPowerExchangeMuitData(requestOptions),
]);
const ticker = normalizeTicker(result[0]);
const balances = normalizeBalances(result[1]);
const exchangeMultiplier = resolveRedeemPowerRate(result[2]) || 1;
return {
ticker: ticker,
exchangeMultiplier: exchangeMultiplier,
balances: {
coupon: toFixedNumber(balances.coupon, 2),
voucher: toFixedNumber(balances.voucher, 2),
power: toFixedNumber(balances.power, 0),
},
tips: [
"算力 = 抵用券或消费券 × BMT实时价格",
"算力 = 抵用券或消费券 × BMT实时价格 × 兑换倍率",
"抵用券和消费券总数小于100券的不可兑换",
"算力用于兑换BMT使用。",
],
@ -1765,7 +1868,7 @@ export async function fetchBmtExchangeDetail(requestOptions) {
"预估 BMT数= 输入可用积分数÷BMT 实时价格。",
`兑换会同步消耗算力, 1 点可用积分,需同步消耗${powerRate}点算力。`,
"仅支持 100 的正整数倍, 不足 100的可用积分无法发起兑换。",
"凌晨 00:00 至 01:00 为积分系统维护时段,期间暂停兑换服务,请避开该时间段操作。",
"凌晨00:00至02:00为积分维护时段",
],
};
}
@ -1798,14 +1901,23 @@ export async function fetchWithdrawDetail(requestOptions) {
fetchPriceData(requestOptions),
fetchHomeBalanceData(requestOptions),
fetchWalletAddressData(requestOptions),
fetchWithdrawRateData(requestOptions),
]);
const ticker = normalizeTicker(result[0]);
const balances = normalizeBalances(result[1]);
const walletPayload = buildWalletPayload(result[2] && result[2].address);
const withdrawRate = resolvePercentRate(result[3]);
setHomeTickerCache(ticker);
return {
ticker: ticker,
withdrawableBmt: toFixedNumber(balances.withdrawableBmt, 2),
withdrawRate: withdrawRate,
balances: {
voucher: balances.voucher,
coupon: balances.coupon,
},
wallets: walletPayload.wallets,
defaultWallet: walletPayload.wallets[0] || null,
};

View File

@ -1,5 +1,10 @@
const HOST_URL = "https://tpoint.agrimedia.cn";
// const HOST_URL = window.location.protocol + "//" + window.location.host;
const serviceConfig = {
BASE_URL: "https://tpoint.agrimedia.cn",
BASE_URL: HOST_URL,
HTTP_REQUEST_URL: HOST_URL,
TIMEOUT: 10000,
WALLET_NAME: "海南农综交易所",
POINTS_CONVERT_INTERVAL: "0,20",
@ -7,17 +12,20 @@ const serviceConfig = {
price: "/api/hn/getPrice",
homeBalance: "/api/hn/getAllBalance",
powerExchangeSubmit: "/api/hn/redeem/power",
powerExchangeMuit: "/api/hn/redeem/getMuit",
bmtRedeemPowerRate: "/api/hn/redeem/getRedeemPowerRate",
bmtExchangeSubmit: "/api/hn/redeem/redeem_bmt",
transferFee: "/api/hn/transfer/getProp",
transferUser: "/api/hn/transfer/getUserInfo",
transferPowerSubmit: "/api/hn/transfer/transferPower",
transferPointsSubmit: "/api/hn/transfer/transferPoint",
transferLedger: "/api/hn/transfer/transferList",
walletFlowList: "/api/hn/wallet_flow/getList",
redeemRecordList: "/api/hn/redeem/redeemList",
coinIndex: "/api/coin/index",
userProfile: "/api/user",
walletDetail: "/api/hn/wallet/getWalletAddress",
walletSave: "/api/hn/wallet/saveAddress",
withdrawRate: "/api/hn/wallet/getRate",
withdrawSubmit: "/api/hn/wallet/withdraw",
pointsConvertHistoryList: "/api/integral/getTransferList",
pointsConvertAvailableList: "/api/integral/transferList",

View File

@ -66,7 +66,9 @@
<text class="transfer-record-card__balance asset-number-font">{{
item.balanceLabel || item.balance
}}</text>
<text class="transfer-record-card__fee asset-number-font">{{ item.feeText }}</text>
<text class="transfer-record-card__fee asset-number-font">{{
item.feeDisplayText || item.feeText
}}</text>
</view>
<view

View File

@ -73,6 +73,12 @@
</view>
</view>
</view>
<view v-if="showLoadMoreState" class="record-load-more">
<text class="record-load-more__text asset-number-font">{{
loadMoreText
}}</text>
</view>
</view>
<view v-else class="empty-card">
@ -99,6 +105,10 @@ export default {
availablePoints: "0",
records: [],
},
page: 1,
pageSize: 10,
hasMore: false,
loadingMore: false,
};
},
computed: {
@ -115,20 +125,87 @@ export default {
filteredRecords() {
return Array.isArray(this.detail.records) ? this.detail.records : [];
},
showLoadMoreState() {
return this.filteredRecords.length > 0;
},
loadMoreText() {
if (this.loadingMore) {
return "加载中...";
}
if (this.hasMore) {
return "上拉加载更多";
}
return "没有更多了";
},
},
onLoad() {
this.selectedMonth = this.currentMonth();
this.loadPage(true);
this.resetPagingState();
this.loadPage(true, 1);
},
onShow() {
if (this.hasShown) {
this.loadPage();
this.resetPagingState();
this.loadPage(false, 1);
return;
}
this.hasShown = true;
},
onReachBottom() {
this.loadMore();
},
methods: {
resetPagingState() {
this.page = 1;
this.hasMore = false;
this.loadingMore = false;
},
updatePaging(result, requestedPage, receivedLength) {
const pagination =
result && result.pagination && typeof result.pagination === "object"
? result.pagination
: null;
this.page =
Number(pagination && pagination.page) || Number(requestedPage) || this.page || 1;
if (pagination && typeof pagination.hasMore === "boolean") {
this.hasMore = pagination.hasMore;
return;
}
this.hasMore = receivedLength >= this.pageSize;
},
mergeRecords(currentRecords, nextRecords) {
const mergedMap = {};
const mergedList = [];
const appendItem = (item) => {
const key =
String(item && item.id ? item.id : "").trim() ||
[
item && item.orderSn,
item && item.time,
item && item.title,
item && item.amount,
]
.map((value) => String(value || ""))
.join("-");
if (!key || mergedMap[key]) {
return;
}
mergedMap[key] = true;
mergedList.push(item);
};
(Array.isArray(currentRecords) ? currentRecords : []).forEach(appendItem);
(Array.isArray(nextRecords) ? nextRecords : []).forEach(appendItem);
return mergedList;
},
currentMonth() {
const currentDate = new Date();
return (
@ -161,28 +238,71 @@ export default {
event && event.detail ? event.detail.value : 0,
);
this.selectedMonth = this.monthOptions[nextIndex] || this.activeMonth;
this.loadPage();
this.resetPagingState();
this.loadPage(true, 1);
},
async loadPage(showLoading) {
async loadPage(showLoading, targetPage) {
const page = Number(targetPage || 1);
const isLoadMore = page > 1;
if (isLoadMore && this.loadingMore) {
return;
}
if (isLoadMore) {
this.loadingMore = true;
}
try {
const result = await fetchPointsConvertHome(
this.activeMonth,
showLoading
const requestOptions =
!isLoadMore && showLoading
? {
showLoading: true,
loadingText: "加载中",
}
: null,
: null;
const result = await fetchPointsConvertHome(
this.activeMonth,
{
page: page,
pageSize: this.pageSize,
},
requestOptions,
);
this.detail = result;
const incomingRecords = Array.isArray(result.records) ? result.records : [];
const previousCount = this.filteredRecords.length;
const mergedRecords = isLoadMore
? this.mergeRecords(this.filteredRecords, incomingRecords)
: incomingRecords;
this.detail = Object.assign({}, this.detail, result, {
records: mergedRecords,
});
this.updatePaging(result, page, incomingRecords.length);
if (isLoadMore && mergedRecords.length <= previousCount) {
this.hasMore = false;
}
} catch (error) {
uni.showToast({
title: error.message || "页面加载失败",
title: error.message || (isLoadMore ? "加载更多失败" : "页面加载失败"),
icon: "none",
});
} finally {
if (isLoadMore) {
this.loadingMore = false;
}
}
},
loadMore() {
if (this.loadingMore || !this.hasMore) {
return;
}
this.loadPage(false, this.page + 1);
},
openConvertList() {
uni.navigateTo({
url: "/pages/assets/points-convert-list",
@ -406,6 +526,18 @@ export default {
color: rgba(255, 255, 255, 0.96);
}
.record-load-more {
display: flex;
align-items: center;
justify-content: center;
padding: 28rpx 0 8rpx;
}
.record-load-more__text {
font-size: 24rpx;
color: rgba(179, 189, 214, 0.78);
}
.empty-card {
margin-top: 22rpx;
padding: 60rpx 28rpx;

View File

@ -165,6 +165,7 @@ export default {
detail: {
ticker: {},
balances: {},
exchangeMultiplier: 1,
tips: [],
},
hasShown: false,
@ -216,12 +217,19 @@ export default {
this.detail.ticker.close || this.detail.ticker.cnyPrice || 0,
);
},
exchangeMultiplierNumber() {
const value = Number(this.detail.exchangeMultiplier || 1);
return value > 0 ? value : 1;
},
estimatePower() {
if (!this.amountValue || !this.priceNumber) {
return "0";
}
return this.formatAmount(this.amountValue * this.priceNumber, 2);
return this.formatAmount(
this.amountValue * this.priceNumber * this.exchangeMultiplierNumber,
2,
);
},
allEstimatePower() {
if (!this.priceNumber) {
@ -232,16 +240,19 @@ export default {
Number(this.detail.balances.voucher || 0) +
Number(this.detail.balances.coupon || 0);
return this.formatAmount(totalTickets / this.priceNumber, 2);
return this.formatAmount(
totalTickets * this.priceNumber * this.exchangeMultiplierNumber,
2,
);
},
displayPower() {
return this.formatAmount(this.detail.balances.power, 0);
return this.formatAmount(this.detail.balances.power, 2);
},
displayVoucher() {
return this.formatAmount(this.detail.balances.voucher, 0);
return this.formatAmount(this.detail.balances.voucher, 2);
},
displayCoupon() {
return this.formatAmount(this.detail.balances.coupon, 0);
return this.formatAmount(this.detail.balances.coupon, 2);
},
displayPrice() {
return this.priceNumber ? this.priceNumber : "0.00";
@ -252,7 +263,7 @@ export default {
}
return [
"算力 = 抵用券或消费券 * BMT实时价格",
"算力 = 抵用券或消费券 * BMT实时价格 * 兑换倍率",
"抵用券和消费券总数小于100券的不可兑换",
"算力用于兑换BMT使用。",
];
@ -489,7 +500,7 @@ export default {
font-size: 32rpx;
font-weight: 800;
line-height: 1.1;
font-family: "DIN-Bold", DIN, sans-serif;
font-family: var(--asset-number-font-family);
color: #ffffff;
}

View File

@ -273,7 +273,7 @@ export default {
const received = this.amountValue
? this.amountValue * (1 - this.feePercent / 100)
: 0;
return this.formatAmount(received, 0);
return this.formatAmount(received, 2);
},
amountPlaceholder() {
return this.activeTab === "power"

View File

@ -45,7 +45,9 @@
</view>
<view class="fee-card">
<text class="fee-card__label asset-number-font">提取手续费1%</text>
<text class="fee-card__label asset-number-font"
>提取手续费{{ withdrawRateLabel }}</text
>
<text class="fee-card__value asset-number-font">{{ feeText }}</text>
</view>
</view>
@ -112,7 +114,19 @@
}}</text>
</view>
<view class="popup-detail__row">
<text class="meta-pair__label">手续费</text>
<text class="meta-pair__label">BMT实时价格</text>
<text class="meta-pair__value asset-number-font"
>{{ displayPrice }} CNY/BMT</text
>
</view>
<view class="popup-detail__row">
<text class="meta-pair__label">手续费费率</text>
<text class="meta-pair__value asset-number-font">{{
withdrawRateLabel
}}</text>
</view>
<view class="popup-detail__row">
<text class="meta-pair__label">提取手续费</text>
<text class="meta-pair__value asset-number-font">{{ feeText }}</text>
</view>
<view class="popup-detail__row">
@ -139,6 +153,11 @@ export default {
detail: {
ticker: {},
withdrawableBmt: "0",
withdrawRate: 0,
balances: {
voucher: 0,
coupon: 0,
},
defaultWallet: null,
},
hasShown: false,
@ -169,13 +188,16 @@ export default {
return this.formatAmount(this.amountValue, 2);
},
feeText() {
const fee = (this.amountValue * this.withdrawRateNumber) / 100;
return this.amountValue
? this.formatAmount(this.amountValue * 0.01, 2) + " BMT"
? this.formatAmount(fee, 2) + " BMT"
: "0.00 BMT";
},
actualText() {
const fee = (this.amountValue * this.withdrawRateNumber) / 100;
const actual = Math.max(0, this.amountValue - fee);
return this.amountValue
? this.formatAmount(this.amountValue * 0.99, 2) + " BMT"
? this.formatAmount(actual, 2) + " BMT"
: "0.00 BMT";
},
displayWithdrawable() {
@ -193,6 +215,17 @@ export default {
}
return price.toFixed(3);
},
withdrawRateNumber() {
const rate = Number(this.detail.withdrawRate || 0);
return Number.isFinite(rate) && rate > 0 ? rate : 0;
},
withdrawRateLabel() {
if (!this.withdrawRateNumber) {
return "0%";
}
return this.stripTrailingZero(this.withdrawRateNumber) + "%";
},
walletDisplayAddress() {
if (!this.detail.defaultWallet || !this.detail.defaultWallet.address) {
return "";
@ -237,6 +270,15 @@ export default {
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
stripTrailingZero(value) {
const number = Number(value || 0);
if (!Number.isFinite(number)) {
return "0";
}
return number.toFixed(4).replace(/\.?0+$/, "");
},
async loadPage(showLoading) {
try {
this.detail = await fetchWithdrawDetail(
@ -522,6 +564,46 @@ export default {
color: #ff9367;
}
.calc-sheet {
margin-top: 16rpx;
padding: 18rpx 20rpx;
border-radius: 10rpx;
background: rgba(18, 23, 42, 0.72);
}
.calc-sheet__row {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
.calc-sheet__row + .calc-sheet__row {
margin-top: 14rpx;
}
.calc-sheet__row--formula {
align-items: center;
}
.calc-sheet__label {
flex-shrink: 0;
font-size: 24rpx;
color: rgba(188, 198, 223, 0.82);
}
.calc-sheet__value {
margin-left: 24rpx;
text-align: right;
font-size: 24rpx;
color: #ffffff;
}
.calc-sheet__value--formula {
max-width: 380rpx;
line-height: 1.5;
color: #ffcf8a;
}
.wallet-card__head {
display: flex;
align-items: center;
@ -670,4 +752,11 @@ export default {
text-align: right;
word-break: break-all;
}
.popup-formula {
max-width: 320rpx;
text-align: right;
line-height: 1.5;
color: #ffcf8a;
}
</style>

View File

@ -146,7 +146,12 @@
</template>
<script>
import { fetchAssetHome } from "../../api/assets";
import {
fetchAssetHome,
fetchCouponRedeemLinkData,
fetchVoucherBrokerLinkData,
} from "../../api/assets";
import serviceConfig from "../../config/service";
export default {
data() {
@ -154,6 +159,8 @@ export default {
isHomeLoading: true,
hasLoadedOnce: false,
isFetchingHome: false,
isOpeningCouponRedeem: false,
isOpeningVoucherBroker: false,
overview: {
title: "数字资产",
heroTitle: "BM数字资产管理",
@ -273,10 +280,18 @@ export default {
});
},
openQuickAsset(item) {
if (item && item.key === "voucher") {
this.openVoucherBroker();
return;
}
if (item && item.key === "coupon") {
this.openCouponRedeem();
return;
}
const urlMap = {
points: "/pages/assets/ledger?type=points",
voucher: "/pages/assets/ledger?type=voucher",
coupon: "/pages/assets/ledger?type=coupon",
power: "/pages/assets/ledger?type=power-flow",
};
@ -289,6 +304,83 @@ export default {
url: targetUrl,
});
},
navigateToExternalUrl(targetUrl) {
if (!targetUrl) {
return;
}
if (typeof window !== "undefined" && window.location) {
window.location.href = targetUrl;
return;
}
if (
typeof plus !== "undefined" &&
plus.webview &&
plus.webview.currentWebview
) {
const currentWebview = plus.webview.currentWebview();
if (currentWebview && typeof currentWebview.loadURL === "function") {
currentWebview.loadURL(targetUrl);
return;
}
}
uni.navigateTo({
url: targetUrl,
});
},
async openVoucherBroker() {
if (this.isOpeningVoucherBroker) {
return;
}
this.isOpeningVoucherBroker = true;
try {
const result = await fetchVoucherBrokerLinkData({
showLoading: true,
loadingText: "加载中",
});
const targetUrl =
serviceConfig.HTTP_REQUEST_URL +
"/JXH5/pages/users/user_broker/index?user_id=" +
encodeURIComponent(result.userId) +
"&total=" +
encodeURIComponent(result.balance);
this.navigateToExternalUrl(targetUrl);
} catch (error) {
uni.showToast({
title: error.message || "跳转失败",
icon: "none",
});
} finally {
this.isOpeningVoucherBroker = false;
}
},
async openCouponRedeem() {
if (this.isOpeningCouponRedeem) {
return;
}
this.isOpeningCouponRedeem = true;
try {
const result = await fetchCouponRedeemLinkData({
showLoading: true,
loadingText: "加载中",
});
this.navigateToExternalUrl(result.targetUrl);
} catch (error) {
uni.showToast({
title: error.message || "跳转失败",
icon: "none",
});
} finally {
this.isOpeningCouponRedeem = false;
}
},
openWallet() {
uni.navigateTo({
url: "/pages/assets/wallet",

View File

@ -1,2 +1,2 @@
<!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>白马交易所</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=/bmt/static/index.883130ca.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=/bmt/static/js/chunk-vendors.98a0fd8f.js></script><script src=/bmt/static/js/index.3dd40b51.js></script></body></html>
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=/bmt/static/index.883130ca.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=/bmt/static/js/chunk-vendors.a58c62f3.js></script><script src=/bmt/static/js/index.5ed2281f.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long