import serviceConfig from "../config/service"; import request from "../utils/request"; import { getCurrentWebviewToken } from "../utils/webview-token"; const HOME_TICKER_STORAGE_KEY = "asset_home_ticker_cache"; let runtimeHomeTickerCache = null; function createError(message, raw) { return { message: message || "接口请求失败", raw: raw, }; } function toNumber(value) { const number = Number(value || 0); return Number.isFinite(number) ? number : 0; } function toFixedNumber(value, digits) { return toNumber(value).toFixed(digits); } function formatHomeNumber(value, digits) { const number = toNumber(value); 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.round(number) .toString() .replace(/\B(?=(\d{3})+(?!\d))/g, ","); } function isSuccessPayload(payload) { if (!payload || typeof payload !== "object") { return false; } const statusCode = payload.code !== undefined ? Number(payload.code) : Number(payload.status); return statusCode === 200; } function unwrapPayload(payload, fallbackMessage) { if (isSuccessPayload(payload)) { return payload.data; } if (payload && typeof payload === "object") { throw createError( payload.msg || payload.message || fallbackMessage || "接口请求失败", payload, ); } throw createError(fallbackMessage || "接口返回异常", payload); } async function fetchPayload(options, fallbackMessage) { try { const payload = await request(options); return unwrapPayload(payload, fallbackMessage); } catch (error) { if (error && error.message) { throw error; } throw createError(fallbackMessage || "接口请求失败", error); } } function createRequestOptions(baseOptions, requestOptions) { return Object.assign({}, baseOptions, requestOptions || {}); } function normalizeTicker(data) { const close = toNumber(data && (data.close || data.cnyPrice)); const lastDayClose = toNumber(data && data.lastDayClose); const rawChange = data && data.change; let change = typeof rawChange === "string" ? rawChange : ""; if (!change) { if (close && lastDayClose) { const percent = ((close - lastDayClose) / lastDayClose) * 100; const prefix = percent >= 0 ? "+" : ""; change = prefix + percent.toFixed(2) + "%"; } else { change = "0.00%"; } } return { symbol: (data && data.symbol) || "BMT/CNY", close: close, cnyPrice: (data && data.cnyPrice) || (close ? close.toFixed(2) : "0.00"), lastDayClose: lastDayClose, change: change, }; } function setHomeTickerCache(ticker) { const normalizedTicker = normalizeTicker(ticker); runtimeHomeTickerCache = normalizedTicker; try { if (typeof uni !== "undefined" && uni.setStorageSync) { uni.setStorageSync(HOME_TICKER_STORAGE_KEY, normalizedTicker); } } catch (error) { // Ignore storage failures and keep runtime cache fallback. } return normalizedTicker; } function getHomeTickerCache() { if (runtimeHomeTickerCache) { return runtimeHomeTickerCache; } try { if (typeof uni !== "undefined" && uni.getStorageSync) { const storedTicker = uni.getStorageSync(HOME_TICKER_STORAGE_KEY); if (storedTicker && typeof storedTicker === "object") { runtimeHomeTickerCache = normalizeTicker(storedTicker); } } } catch (error) { // Ignore storage failures. } return runtimeHomeTickerCache || normalizeTicker(null); } function normalizeBalances(data) { return { points: toNumber(data && data.point), power: toNumber(data && data.c_power), bmt: toNumber(data && data.bmt_num), withdrawableBmt: toNumber(data && data.bmt_num), voucher: toNumber(data && data.coin), coupon: toNumber(data && data.diamond_balance), balance: toNumber(data && data.brokerage_price), }; } function toRawDisplayValue(value) { if (value === undefined || value === null || value === "") { return "0"; } return String(value); } function buildHomeOverview(balanceData, tickerData) { const balances = normalizeBalances(balanceData); const ticker = normalizeTicker(tickerData); const rawQuickAssets = { balance: toRawDisplayValue(balanceData && balanceData.brokerage_price), points: toRawDisplayValue(balanceData && balanceData.point), voucher: toRawDisplayValue(balanceData && balanceData.coin), coupon: toRawDisplayValue(balanceData && balanceData.diamond_balance), power: toRawDisplayValue(balanceData && balanceData.c_power), }; return { title: "数字资产", ticker: ticker, topStats: [ { key: "wallet-bmt", title: "可提取BMT", value: toFixedNumber(balances.withdrawableBmt, 2), unit: "BMT", accent: "gold", }, { key: "ticker", title: "BMT实时价格", value: toFixedNumber(ticker.close || ticker.cnyPrice, 3), unit: "BMT/CNY", accent: "green", }, ], quickAssets: [ { key: "points", title: "可用积分", value: rawQuickAssets.points, accent: "gold", }, { key: "power", title: "算力", value: rawQuickAssets.power, accent: "violet", }, { key: "coupon", title: "消费券", value: rawQuickAssets.coupon, accent: "teal", }, { key: "voucher", title: "抵用券", value: rawQuickAssets.voucher, accent: "rose", }, { key: "balance", title: "余额", value: rawQuickAssets.balance, accent: "blue", }, ], features: [ { key: "points-convert", title: "积分转换", desc: "释放中的积分转换为可用积分", accent: "pink", }, { key: "power-exchange", title: "算力兑换", desc: "抵用券与消费券兑换算力", accent: "amber", }, { key: "bmt-flash", title: "BMT闪兑", desc: "BMT闪兑", accent: "indigo", }, { key: "transfer", title: "转赠中心", desc: "积分或算力转赠好友", accent: "indigo", }, { key: "bmt-exchange", title: "BMT兑换", desc: "积分与算力兑换 BMT", accent: "mint", }, { key: "withdraw", title: "BMT提取", desc: "钱包中的 BMT 可提取到交易所进行交易", accent: "pink", }, ], notice: "数字资产是您在平台上的虚拟资产,请谨慎管理;BMT可在交易所中进行交易。", }; } function buildTransferTips(feePercent) { const percentText = toNumber(feePercent) || 10; return { points: [ "只能转赠100的整数倍", "凌晨00:00至02:00为系统维护时段不可赠送", "转赠系统会扣除" + percentText + "%的手续费", ], power: [ "只能转赠1的整数倍", "转赠系统会扣除" + percentText + "%的手续费", ], }; } function buildWalletList(address) { const normalizedAddress = String(address || "").trim(); if (!normalizedAddress) { return []; } return [ { id: "default-wallet", name: serviceConfig.WALLET_NAME, address: normalizedAddress, isDefault: true, }, ]; } function buildWalletPayload(address) { return { wallets: buildWalletList(address), instructions: [ "点击交易所 App 底部“资产”进入钱包页", "搜索或输入大写字母 BMT", "点击“充币 / 充值”进入收款地址页面", "复制钱包地址后回填到当前页面", ], }; } 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 []; } const DEFAULT_LIST_PAGE = 1; const DEFAULT_LIST_PAGE_SIZE = 10; function hasPaginationKey(value) { if (!value || typeof value !== "object") { return false; } return ( value.page !== undefined || value.pageSize !== undefined || value.page_size !== undefined || value.pagesize !== undefined || value.size !== undefined || value.limit !== undefined ); } function normalizePaginationOptions(pagination) { const source = pagination && typeof pagination === "object" ? pagination : {}; const page = Math.max( 1, Math.floor( toNumber( pickFirstValue(source, ["page", "current_page", "currentPage", "p"]) || DEFAULT_LIST_PAGE, ), ), ); const pageSize = Math.max( 1, Math.floor( toNumber( pickFirstValue(source, [ "pageSize", "page_size", "pagesize", "size", "limit", "per_page", ]) || DEFAULT_LIST_PAGE_SIZE, ), ), ); return { page: page, pageSize: pageSize, }; } function resolvePagingArguments(paginationOrRequestOptions, requestOptions) { if (requestOptions || hasPaginationKey(paginationOrRequestOptions)) { return { pagination: normalizePaginationOptions(paginationOrRequestOptions), requestOptions: requestOptions || null, }; } return { pagination: normalizePaginationOptions(null), requestOptions: paginationOrRequestOptions || null, }; } function buildPagingRequestData(baseData, pagination) { const normalizedPagination = normalizePaginationOptions(pagination); return Object.assign({}, baseData || {}, { page: normalizedPagination.page, limit: normalizedPagination.pageSize, }); } function parseBooleanLike(value) { if (typeof value === "boolean") { return value; } if (typeof value === "number") { return value > 0; } if (typeof value === "string") { const normalized = value.trim().toLowerCase(); if (!normalized) { return null; } if ( normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "y" ) { return true; } if ( normalized === "0" || normalized === "false" || normalized === "no" || normalized === "n" ) { return false; } } return null; } function buildPaginationMeta(data, requestPagination) { const normalizedData = data && typeof data === "object" ? data : {}; const normalizedRequestPagination = normalizePaginationOptions(requestPagination); const list = normalizeListData(normalizedData); const page = Math.floor( toNumber( pickFirstValue(normalizedData, [ "page", "current_page", "currentPage", "page_num", ]), ), ) || normalizedRequestPagination.page; const pageSize = Math.floor( toNumber( pickFirstValue(normalizedData, [ "page_size", "pagesize", "size", "limit", "per_page", ]), ), ) || normalizedRequestPagination.pageSize; const total = Math.floor( toNumber( pickFirstValue(normalizedData, [ "total", "count", "total_count", "totalCount", "record_count", "all_count", ]), ), ); const lastPage = Math.floor( toNumber( pickFirstValue(normalizedData, [ "last_page", "lastPage", "page_total", "total_page", "pages", "pageCount", ]), ), ); const hasMoreRaw = pickFirstValue(normalizedData, [ "has_more", "hasMore", "more", "is_more", "next_page", "nextPage", ]); const hasMoreByRawValue = parseBooleanLike(hasMoreRaw); let hasMore = hasMoreByRawValue; if (hasMore === null && lastPage > 0) { hasMore = page < lastPage; } if (hasMore === null && total > 0 && pageSize > 0) { hasMore = page * pageSize < total; } if (hasMore === null) { hasMore = list.length >= pageSize && list.length > 0; } if (!list.length) { hasMore = false; } return { page: page, pageSize: pageSize, total: total, lastPage: lastPage, hasMore: Boolean(hasMore), }; } function formatTransferRecordNumber(value) { const number = toNumber(value); 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 normalizeAvailablePointsText(text) { const safeText = String(text || ""); if (!safeText) { return ""; } return safeText .replace(/可用积分/g, "__AVAILABLE_POINTS__") .replace(/积分/g, "可用积分") .replace(/__AVAILABLE_POINTS__/g, "可用积分"); } 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", "gold_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 + "记录"; const isPointsLedger = String(meta && meta.key ? meta.key : "") === "points"; const displayTitle = isPointsLedger ? normalizeAvailablePointsText(title) : title; const displayNoteText = isPointsLedger ? normalizeAvailablePointsText(noteText) : noteText; const displayDirection = isPointsLedger ? normalizeAvailablePointsText(direction) : direction; const displaySubtitle = orderSn ? "单号 " + orderSn : displayNoteText || displayDirection; const displayFeeText = displayNoteText || (orderSn ? "单号 " + orderSn : meta.subtitle); return { id: buildRecordId(item, meta.key || "flow"), sourceId: String(pickFirstValue(item, ["id", "log_id", "uid"]) || ""), title: displayTitle, subtitle: displaySubtitle, 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: displayFeeText, directionLabel: displayDirection, actionSymbol: directionPresentation.actionSymbol, orderSn: orderSn, noteText: displayNoteText, 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 !== "") { const pointLabel = meta.type === 1 ? "可用积分" : "积分"; fragments.push(pointLabel + " " + 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 titleText = String( pickFirstValue(item, ["title", "name", "type_name"]) || meta.title || "兑换记录", ); const noteText = buildRedeemConsumeText(item, meta); return { id: buildRecordId(item, meta.key || "redeem"), title: titleText, 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, feeDisplayText: meta.key === "bmt-flash" ? "BMT闪兑" : meta.key === "bmt" ? "BMT兑换" : "", directionLabel: "兑换", actionSymbol: "+", orderSn: orderSn, tag: "兑", tone: "success", cardTone: "success", }; }); } function getTransferRecordUnit(item) { return Number(item && item.type) === 0 ? "算力" : "可用积分"; } function normalizeTransferPointsText(text, item) { if (Number(item && item.type) === 0) { return String(text || ""); } const safeText = String(text || ""); return safeText .replace(/可用积分/g, "__POINTS_LABEL__") .replace(/积分/g, "可用积分") .replace(/__POINTS_LABEL__/g, "可用积分"); } function getTransferRecordTone(item) { return Number(item && item.io_type) === 1 ? "success" : "danger"; } function getTransferRecordTag(item) { return Number(item && item.io_type) === 1 ? "收" : "赠"; } function getTransferRecordDirection(item) { return Number(item && item.io_type) === 1 ? "转入" : "转出"; } function getTransferRecordTitle(item) { const unit = getTransferRecordUnit(item); return Number(item && item.io_type) === 1 ? unit + "获赠" : unit + "转赠"; } function getTransferRecordSymbol(item) { return Number(item && item.io_type) === 1 ? "+" : "-"; } function getTransferRecordAmount(item) { const numberText = formatTransferRecordNumber(item && item.num); return getTransferRecordSymbol(item) + numberText; } function extractTransferTitleFeeValue(item) { const titleText = String(pickFirstValue(item, ["title", "name"]) || "").trim(); if (!titleText) { return ""; } if (/^-?\d+(?:\.\d+)?$/.test(titleText)) { return titleText; } const titleFeeMatch = titleText.match( /手续费(?:\s*[::]?\s*|\s*[((]\s*)(-?\d+(?:\.\d+)?)\s*[))]?/, ); return titleFeeMatch && titleFeeMatch[1] !== undefined ? titleFeeMatch[1] : ""; } function getTransferRecordFee(item) { const titleFeeValue = extractTransferTitleFeeValue(item); if (titleFeeValue !== "") { return toNumber(titleFeeValue); } if ( item && item.fee !== undefined && item.fee !== null && String(item.fee).trim() !== "" ) { return toNumber(item.fee); } return (toNumber(item && item.num) * toNumber(item && item.fee_percent)) / 100; } function getTransferRecordFeeText(item) { const percent = toNumber(item && item.fee_percent); const unit = getTransferRecordUnit(item); const feeText = formatHomeNumber(getTransferRecordFee(item), 2); if (percent > 0) { return "手续费: " + feeText; } return "手续费: " + feeText + " " + unit; } function getTransferRecordBalance(item) { const unit = getTransferRecordUnit(item); return "结余 " + toFixedNumber(item && item.balance, 2) + " " + unit; } function getTransferRecordBalanceLabel(item) { const unit = getTransferRecordUnit(item); return "剩余" + unit + ":" + formatTransferRecordNumber(item && item.balance); } function mapTransferRecords(list) { return (Array.isArray(list) ? list : []).map(function (item) { const titleText = item.title || getTransferRecordTitle(item); return { id: item.order_sn || item.id || String(Math.random()), title: normalizeTransferPointsText(titleText, item), subtitle: item.order_sn ? "单号 " + item.order_sn : getTransferRecordDirection(item), time: item.add_time || "", amount: getTransferRecordAmount(item), balance: getTransferRecordBalance(item), balanceLabel: getTransferRecordBalanceLabel(item), assetLabel: getTransferRecordUnit(item), feeText: getTransferRecordFeeText(item), directionLabel: getTransferRecordDirection(item), actionSymbol: getTransferRecordSymbol(item), orderSn: item.order_sn || "", tag: getTransferRecordTag(item), tone: getTransferRecordTone(item), cardTone: getTransferRecordTone(item), }; }); } function mapPointsConvertRecords(list) { return normalizeListData(list).map(function (item) { const rawTransferPointValue = pickFirstValue(item, [ "transfer_point_num", "transfer_coin_num", "point_num", "coin_num", "value", ]); const hasTransferPointValue = rawTransferPointValue !== ""; const amountValue = pickFirstValue(item, [ "gold_num", "number", "transfer_point_num", "transfer_coin_num", "point_num", "num", "amount", "value", ]); const rawStatusText = String( pickFirstValue(item, [ "status_text", "status_name", "status_desc", "transfer_status_text", ]) || "", ); const rawStatusCode = String( pickFirstValue(item, ["status", "state", "transfer_status"]) || "", ); let statusText = rawStatusText; let disabled = false; if (!statusText) { if (rawStatusCode === "1") { statusText = "兑换中"; } else if (rawStatusCode === "2") { statusText = "已转换"; } else if (rawStatusCode === "3") { statusText = "转换失败"; } } if ( /中/.test(statusText) || /完成/.test(statusText) || /成功/.test(statusText) || /失败/.test(statusText) ) { disabled = true; } if (hasTransferPointValue && toNumber(rawTransferPointValue) <= 0) { disabled = true; } return { id: String( pickFirstValue(item, ["id", "bill_id", "log_id", "sn"]) || Math.random(), ), sourceId: String(pickFirstValue(item, ["id", "bill_id", "log_id"]) || ""), orderSn: String( pickFirstValue(item, ["order_sn", "trade_no", "bill_no", "sn"]) || "", ), title: pickFirstValue(item, ["title", "name", "type_name"]) || "系统赠送积分", subtitle: "可转数量 " + formatTransferRecordNumber( rawTransferPointValue || 0, ), time: pickFirstValue(item, [ "add_time", "create_time", "created_at", "time", "update_time", ]), amount: "+" + formatLedgerRecordNumber(amountValue), amountValue: toNumber(amountValue), transferPointValue: toNumber(rawTransferPointValue), transfer_point_num: toNumber(rawTransferPointValue), statusText: statusText, disabled: disabled, balance: item && item.userBillRelease && item.userBillRelease.total !== undefined && item.userBillRelease.total !== null ? "释放总量 " + formatTransferRecordNumber(item.userBillRelease.total) : "", tag: "积", tone: disabled ? "warning" : "success", }; }); } function extractMonthLabel(value) { const raw = String(value || "").trim(); if (!raw) { const currentDate = new Date(); const year = currentDate.getFullYear(); const month = String(currentDate.getMonth() + 1).padStart(2, "0"); return year + "-" + month; } const matcher = raw.match(/(\d{4})[-/.](\d{1,2})/); if (matcher) { return matcher[1] + "-" + String(matcher[2]).padStart(2, "0"); } const date = new Date(raw.replace(/-/g, "/")); if (Number.isNaN(date.getTime())) { return raw.slice(0, 7); } return ( date.getFullYear() + "-" + String(date.getMonth() + 1).padStart(2, "0") ); } function buildPointsHistoryRecords(list) { return mapWalletFlowRecords(list, { key: "points-convert-history", unit: "积分", title: "积分记录", subtitle: "可用积分流水", }).map(function (item) { return Object.assign({}, item, { month: extractMonthLabel(item.time), detailAvailable: canOpenPointsConvertRecordDetail(item), amountTone: item.actionSymbol === "+" ? "increase" : "decrease", }); }); } function buildMonthOptions(list) { const months = (Array.isArray(list) ? list : []).reduce(function ( result, item, ) { const month = item && item.month ? item.month : extractMonthLabel(item && item.time); if (month && result.indexOf(month) === -1) { result.push(month); } return result; }, []); months.sort(function (left, right) { return right.localeCompare(left); }); if (!months.length) { months.push(extractMonthLabel("")); } return months; } function canOpenPointsConvertRecordDetail(item) { const target = item && typeof item === "object" ? item : {}; const contentText = [ target.title, target.subtitle, target.noteText, target.feeText, target.directionLabel, ] .join(" ") .toLowerCase(); return ( Boolean(target.orderSn || target.sourceId) && /转换/.test(contentText) && !/bmt/.test(contentText) ); } function extractPointsConvertDetailItems(data) { if (Array.isArray(data)) { return data; } if (!data || typeof data !== "object") { return []; } if (Array.isArray(data.list)) { return data.list; } if (Array.isArray(data.items)) { return data.items; } if (Array.isArray(data.details)) { return data.details; } if (Array.isArray(data.records)) { return data.records; } return []; } function buildPointsConvertDetailFallback(record) { const fallback = record || {}; const amountValue = String(fallback.amount || "").replace(/[^\d.-]/g, ""); return { orderSn: fallback.orderSn || "", totalAmount: fallback.amount && String(fallback.amount).trim() ? String(fallback.amount) : "+" + formatLedgerRecordNumber(amountValue), time: fallback.time || "", details: [ { id: fallback.id || fallback.orderSn || "fallback-record", title: fallback.title || "积分转换", amount: fallback.amount && String(fallback.amount).trim() ? String(fallback.amount) : "+" + formatLedgerRecordNumber(amountValue), time: fallback.time || "", }, ], }; } function buildPointsConvertDetailPayload(data, fallbackRecord) { const detailItems = extractPointsConvertDetailItems(data); const summarySource = data && typeof data === "object" && !Array.isArray(data) ? data : {}; const fallback = fallbackRecord || {}; const summaryTotalValue = pickFirstValue(summarySource, [ "gold_num", "number", "num", "amount", "point_num", "transfer_coin_num", "total", ]); const detailFallbackTotal = detailItems.reduce(function (total, item) { const value = pickFirstValue(item, [ "gold_num", "number", "num", "amount", "point_num", "transfer_coin_num", "value", ]); return total + toNumber(value); }, 0); const totalValue = summaryTotalValue !== "" ? summaryTotalValue : detailFallbackTotal; const totalAmountText = totalValue !== "" ? "+" + formatLedgerRecordNumber(totalValue) : fallback.amount || "+0"; const detailList = detailItems.map(function (item, index) { const amountValue = pickFirstValue(item, [ "gold_num", "number", "num", "amount", "point_num", "transfer_coin_num", "value", ]); return { id: String( pickFirstValue(item, ["id", "bill_id", "log_id", "sn"]) || "detail-" + index, ), title: pickFirstValue(item, ["title", "name", "type_name"]) || fallback.title || "系统赠送积分", amount: "+" + formatLedgerRecordNumber(amountValue), time: pickFirstValue(item, [ "add_time", "create_time", "created_at", "time", "update_time", ]) || fallback.time || "", }; }); if (!detailList.length) { return buildPointsConvertDetailFallback({ id: fallback.id, orderSn: String( pickFirstValue(summarySource, [ "order_sn", "trade_no", "bill_no", "sn", ]) || fallback.orderSn || "", ), title: pickFirstValue(summarySource, ["title", "name", "type_name"]) || fallback.title, amount: totalAmountText, time: pickFirstValue(summarySource, [ "add_time", "create_time", "created_at", "time", "update_time", ]) || fallback.time, }); } return { orderSn: String( pickFirstValue(summarySource, ["order_sn", "trade_no", "bill_no", "sn"]) || fallback.orderSn || "", ), totalAmount: totalAmountText, time: pickFirstValue(summarySource, [ "add_time", "create_time", "created_at", "time", "update_time", ]) || fallback.time || "", details: detailList, }; } function buildDefaultLedger(type, balances) { const map = { power: { title: "兑换记录", subtitle: "算力兑换记录", }, bmt: { title: "兑换记录", subtitle: "BMT兑换记录", }, withdraw: { title: "提取记录", subtitle: "BMT提取流水", }, coupon: { title: "消费券", subtitle: "当前消费券 " + toFixedNumber(balances.coupon, 2), }, voucher: { title: "抵用券记录", subtitle: "可用抵用券 " + toFixedNumber(balances.voucher, 2), }, }; return { type: type, title: map[type].title, subtitle: map[type].subtitle, records: [], }; } function normalizeTransferTarget(data, fallbackId) { if (data && typeof data === "object" && !Array.isArray(data)) { const id = String(data.uid || data.id || fallbackId || "").trim(); if (!id) { throw createError("未查询到好友", data); } return { id: id, nickname: data.nickname || data.nick_name || data.username || "用户" + id, phone: data.mobile || data.phone || "ID已通过校验", avatar: data.avatar || data.headimg || "", }; } if (data === true) { const id = String(fallbackId || "").trim(); if (!id) { throw createError("未查询到好友", data); } return { id: id, nickname: "用户" + id, phone: "ID已通过校验", avatar: "", }; } throw createError("未查询到好友", data); } function sumBy(list, key) { return (Array.isArray(list) ? list : []).reduce(function (total, item) { return total + toNumber(item && item[key]); }, 0); } async function fetchPriceData(requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.price, }, requestOptions), "实时价格加载失败", ); } async function fetchHomeBalanceData(requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.homeBalance, }, requestOptions), "首页资产加载失败", ); } async function fetchBmtPowerRateData(requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.bmtRedeemPowerRate, }, requestOptions), "兑换比例加载失败", ); } async function fetchPowerExchangeMuitData(requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.powerExchangeMuit, }, requestOptions), "兑换倍率加载失败", ); } function resolveRedeemPowerRate(data) { const sourceValue = data && typeof data === "object" ? pickFirstValue(data, [ "r", "rate", "power_rate", "powerRate", "redeem_power_rate", "redeemRate", "value", "num", "number", ]) : data; const normalizedRate = toNumber(sourceValue); return normalizedRate > 0 ? normalizedRate : 0; } async function fetchTransferFeeData(requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.transferFee, }, 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({ url: serviceConfig.ENDPOINTS.walletDetail, }, 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, ).trim(); if (!rawInterval) { return serviceConfig.POINTS_CONVERT_INTERVAL; } const matcher = rawInterval.match( /^(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)$/, ); if (!matcher) { return serviceConfig.POINTS_CONVERT_INTERVAL; } const start = toNumber(matcher[1]); const end = toNumber(matcher[2]); if (!Number.isFinite(start) || !Number.isFinite(end)) { return serviceConfig.POINTS_CONVERT_INTERVAL; } return String(start) + "," + String(end); } async function fetchPointsConvertList(pagination, requestOptions, interval) { const normalizedInterval = normalizePointsConvertInterval(interval); return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.pointsConvertAvailableList, data: buildPagingRequestData({ interval: normalizedInterval, }, pagination), }, requestOptions), "积分转换列表加载失败", ); } async function fetchPointsConvertHistoryListData( month, pagination, requestOptions, ) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.pointsConvertHistoryList, data: buildPagingRequestData({ month: month, }, pagination), }, requestOptions), "积分兑换列表加载失败", ); } async function fetchTransferLedgerData(pagination, requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.transferLedger, data: buildPagingRequestData({}, pagination), }, requestOptions), "转赠记录加载失败", ); } async function fetchWalletFlowListData(flowType, pagination, requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.walletFlowList, data: buildPagingRequestData({ type: flowType, }, pagination), }, requestOptions), "资产流水加载失败", ); } async function fetchRedeemRecordListData(redeemType, pagination, requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.redeemRecordList, data: buildPagingRequestData({ type: redeemType, }, pagination), }, requestOptions), "兑换记录加载失败", ); } async function fetchPointsConvertInfoData(query, requestOptions) { return fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.pointsConvertRecordDetail, data: query || {}, }, requestOptions), "积分转换详情加载失败", ); } export async function fetchAssetHome(requestOptions) { const result = await Promise.all([ fetchPriceData(requestOptions), fetchHomeBalanceData(requestOptions), ]); const overview = buildHomeOverview(result[1], result[0]); setHomeTickerCache(overview.ticker); 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 token = String(getCurrentWebviewToken() || "").trim(); let targetUrl = serviceConfig.HTTP_REQUEST_URL + "/MD/pages/redeemVoucher/index?canRedeem=" + encodeURIComponent(canRedeem === "" ? "0" : String(canRedeem)); if (token) { targetUrl += (targetUrl.indexOf("?") > -1 ? "&" : "?") + "token=" + encodeURIComponent(token); } return { canRedeem: canRedeem === "" ? "0" : String(canRedeem), token: token, targetUrl: targetUrl, encodedTargetUrl: encodeURIComponent(targetUrl), }; } export async function fetchPointsConvertHome( month, paginationOrRequestOptions, requestOptions, ) { const params = resolvePagingArguments( paginationOrRequestOptions, requestOptions, ); const pagination = params.pagination; const mergedRequestOptions = params.requestOptions; const result = await Promise.all([ fetchHomeBalanceData(mergedRequestOptions), fetchPointsConvertHistoryListData( month, pagination, mergedRequestOptions, ), ]); const balances = normalizeBalances(result[0]); const records = buildPointsHistoryRecords(result[1]).map(function (item) { return Object.assign({}, item, { month: extractMonthLabel(item.time) || month, detailAvailable: canOpenPointsConvertRecordDetail(item), }); }); return { availablePoints: formatHomeNumber(balances.points, 0), records: records, pagination: buildPaginationMeta(result[1], pagination), }; } export async function fetchPointsConvertSelection( paginationOrRequestOptions, requestOptions, ) { const interval = paginationOrRequestOptions && typeof paginationOrRequestOptions === "object" ? paginationOrRequestOptions.interval : ""; const params = resolvePagingArguments( paginationOrRequestOptions, requestOptions, ); const data = await fetchPointsConvertList( params.pagination, params.requestOptions, interval, ); const items = mapPointsConvertRecords(data); const pagination = buildPaginationMeta(data, params.pagination); return { items: items, pagination: pagination, }; } export async function fetchPointsConvertRecordDetail(record, requestOptions) { const fallbackRecord = record || {}; const query = {}; if (fallbackRecord.sourceId) { query.id = fallbackRecord.sourceId; } else if ( fallbackRecord.id && fallbackRecord.orderSn && fallbackRecord.id !== fallbackRecord.orderSn ) { query.id = fallbackRecord.id; } if (fallbackRecord.orderSn) { query.order_sn = fallbackRecord.orderSn; query.sn = fallbackRecord.orderSn; } if (!Object.keys(query).length) { return buildPointsConvertDetailFallback(fallbackRecord); } try { const data = await fetchPointsConvertInfoData(query, requestOptions); return buildPointsConvertDetailPayload(data, fallbackRecord); } catch (error) { return buildPointsConvertDetailFallback(fallbackRecord); } } export async function submitAssetPointsConvert(payload, requestOptions) { const ids = Array.isArray(payload && payload.ids) ? payload.ids : []; if (!ids.length) { throw createError("暂无可转换积分"); } await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.pointsConvertSubmit, method: "POST", data: { ids: ids.join(","), type: 1, }, }, requestOptions), "积分转换失败", ); return { success: true, message: "转换成功", }; } export async function fetchTransferDetail(requestOptions) { const result = await Promise.all([ fetchHomeBalanceData(requestOptions), fetchTransferFeeData(requestOptions), ]); const balances = normalizeBalances(result[0]); const feePercent = toNumber(result[1] && result[1].r) || 10; return { balances: { points: toFixedNumber(balances.points, 0), power: toFixedNumber(balances.power, 0), }, feePercent: feePercent, tips: buildTransferTips(feePercent), }; } export async function searchTransferUser(uid, requestOptions) { const keyword = String(uid || "").trim(); if (!keyword) { throw createError("请输入被赠人ID"); } const data = await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.transferUser, method: "POST", data: { uid: keyword, }, }, requestOptions), "查询好友失败", ); return normalizeTransferTarget(data, keyword); } export async function submitAssetTransfer(payload, requestOptions) { const transferType = payload && payload.type === "power" ? "power" : "points"; const targetId = String(payload && payload.targetId ? payload.targetId : "").trim(); const amount = toNumber(payload && payload.amount); if (!targetId) { throw createError("请选择被赠送人"); } if (!amount) { throw createError("请输入转赠数量"); } const result = await Promise.all([ fetchTransferFeeData(requestOptions), fetchPayload( createRequestOptions({ url: transferType === "power" ? serviceConfig.ENDPOINTS.transferPowerSubmit : serviceConfig.ENDPOINTS.transferPointsSubmit, method: "POST", data: { uid: targetId, number: String(amount), }, }, requestOptions), "转赠失败", ), ]); const feePercent = toNumber(result[0] && result[0].r) || 10; const fee = (amount * feePercent) / 100; const received = amount - fee; return { success: true, fee: toFixedNumber(fee, 2), received: toFixedNumber(received, 2), }; } 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, 2), brokerage_price: toFixedNumber(balances.balance, 2), }, tips: [ "算力 = 输入数量 ÷ BMT实时价格", "兑换算力时所需的抵用券、消费券、余额。必须大于10的倍数", "算力用于兑换BMT使用", ], }; } export async function submitAssetPowerExchange(payload, requestOptions) { const mode = payload && payload.mode === "coupon" ? "coupon" : payload && payload.mode === "balance" ? "balance" : "voucher"; const amount = toNumber(payload && payload.amount); if (!amount) { throw createError("请输入兑换数量"); } await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.powerExchangeSubmit, method: "POST", data: { type: mode === "coupon" ? 1 : mode === "balance" ? 2 : 0, number: String(amount), }, }, requestOptions), "算力兑换失败", ); return { success: true, }; } export async function fetchBmtFlashExchangeDetail(requestOptions) { const result = await Promise.all([ fetchPriceData(requestOptions), fetchHomeBalanceData(requestOptions), ]); const ticker = normalizeTicker(result[0]); const balances = normalizeBalances(result[1]); setHomeTickerCache(ticker); return { ticker: ticker, balances: { bmt: toFixedNumber(balances.bmt, 2), coupon: toFixedNumber(balances.coupon, 2), voucher: toFixedNumber(balances.voucher, 2), brokerage_price: toFixedNumber(balances.balance, 2), }, tips: [ "BMT闪兑 = 输入数量 ÷ BMT实时价格", "BMT闪兑时所需的抵用券、消费券、余额。必须大于10的倍数。", "闪兑成功后数量将直接结算到可用BMT。", ], }; } export async function submitAssetBmtFlashExchange(payload, requestOptions) { const mode = payload && payload.mode === "coupon" ? "coupon" : payload && payload.mode === "balance" ? "balance" : "voucher"; const amount = toNumber(payload && payload.amount); if (!amount) { throw createError("请输入闪兑数量"); } await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.bmtFlashExchangeSubmit, method: "POST", data: { type: mode === "coupon" ? 1 : mode === "balance" ? 2 : 0, number: String(amount), }, }, requestOptions), "BMT闪兑失败", ); return { success: true, }; } // BMT兑换 export async function fetchBmtExchangeDetail(requestOptions) { const result = await Promise.all([ fetchHomeBalanceData(requestOptions), fetchBmtPowerRateData(requestOptions), ]); const ticker = getHomeTickerCache(); const balances = normalizeBalances(result[0]); const powerRate = resolveRedeemPowerRate(result[1]); return { ticker: ticker, powerRate: powerRate, balances: { points: balances.points, power: balances.power, bmt: balances.bmt, voucher: balances.voucher, coupon: balances.coupon, }, tips: [ "预估 BMT数= 输入可用积分数÷BMT 实时价格。", `兑换会同步消耗算力, 1 点可用积分,需同步消耗${powerRate}点算力。`, "仅支持 100 的正整数倍, 不足 100的可用积分无法发起兑换。", "凌晨00:00至02:00为积分维护时段,期间暂停兑换服务,请避开该时间段操作。", ], }; } export async function submitAssetBmtExchange(payload, requestOptions) { const amount = toNumber(payload && payload.amount); if (!amount) { throw createError("请输入积分数量"); } await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.bmtExchangeSubmit, method: "POST", data: { number: String(amount), }, }, requestOptions), "BMT兑换失败", ); return { success: true, }; } export async function fetchWithdrawDetail(requestOptions) { const result = await Promise.all([ 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, brokerage_price: toFixedNumber(balances.balance, 2), }, wallets: walletPayload.wallets, defaultWallet: walletPayload.wallets[0] || null, }; } export async function submitAssetWithdraw(payload, requestOptions) { const address = String( 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, paginationOrRequestOptions, requestOptions, ) { const params = resolvePagingArguments( paginationOrRequestOptions, requestOptions, ); const pagination = params.pagination; const mergedRequestOptions = params.requestOptions; if (type === "transfer") { const data = await fetchTransferLedgerData(pagination, mergedRequestOptions); return { type: type, title: "转赠记录", subtitle: "可用积分与算力转赠流水", records: mapTransferRecords(normalizeListData(data)), pagination: buildPaginationMeta(data, pagination), }; } if (type === "points") { const data = await fetchWalletFlowListData(0, pagination, mergedRequestOptions); return { type: type, title: "可用积分记录", subtitle: "可用积分收支记录", records: mapWalletFlowRecords(data, { key: "points", unit: "可用积分", title: "可用积分记录", subtitle: "可用积分流水", }), pagination: buildPaginationMeta(data, pagination), }; } if (type === "power-flow") { const data = await fetchWalletFlowListData(1, pagination, mergedRequestOptions); return { type: type, title: "算力记录", subtitle: "算力收支记录", records: mapWalletFlowRecords(data, { key: "power-flow", unit: "算力", title: "算力记录", subtitle: "算力流水", }), pagination: buildPaginationMeta(data, pagination), }; } if (type === "power") { const data = await fetchRedeemRecordListData(0, pagination, mergedRequestOptions); return { type: type, title: "兑换记录", subtitle: "算力兑换记录", records: mapRedeemRecords(data, { key: "power", type: 0, unit: "算力", title: "兑换算力", subtitle: "算力兑换", amountKeys: [ "num", "number", "power", "power_num", "c_power", "redeem_power", ], }), pagination: buildPaginationMeta(data, pagination), }; } if (type === "bmt") { const data = await fetchRedeemRecordListData(1, pagination, mergedRequestOptions); 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"], }), pagination: buildPaginationMeta(data, pagination), }; } if (type === "bmt-flash") { const data = await fetchRedeemRecordListData(1, pagination, mergedRequestOptions); return { type: type, title: "闪兑记录", subtitle: "BMT闪兑记录", records: mapRedeemRecords(data, { key: "bmt-flash", type: 1, unit: "BMT", title: "闪兑BMT", subtitle: "BMT闪兑", amountKeys: ["bmt", "bmt_num", "redeem_bmt", "num", "number"], }), pagination: buildPaginationMeta(data, pagination), }; } if (type === "withdraw") { const data = await fetchWalletFlowListData(2, pagination, mergedRequestOptions); return { type: type, title: "提取记录", subtitle: "BMT收支记录", records: mapWalletFlowRecords(data, { key: "withdraw", unit: "BMT", title: "BMT记录", subtitle: "BMT流水", }), pagination: buildPaginationMeta(data, pagination), }; } const homeData = await fetchHomeBalanceData(mergedRequestOptions); const balances = normalizeBalances(homeData); return Object.assign({}, buildDefaultLedger(type, balances), { pagination: { page: pagination.page, pageSize: pagination.pageSize, total: 0, lastPage: 0, hasMore: false, }, }); } export async function fetchWalletDetail(requestOptions) { const data = await fetchWalletAddressData(requestOptions); return buildWalletPayload(data && data.address); } export async function saveAssetWallet(payload, requestOptions) { const address = String(payload && payload.address ? payload.address : "").trim(); if (!address) { throw createError("请输入钱包地址"); } await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.walletSave, method: "POST", data: { address: address, }, }, requestOptions), "保存失败", ); return { success: true, }; } export async function deleteAssetWallet(id, requestOptions) { await fetchPayload( createRequestOptions({ url: serviceConfig.ENDPOINTS.walletSave, method: "POST", data: { address: "", }, }, requestOptions), "删除失败", ); return { success: true, }; }