diff --git a/BMTR.MD b/BMTR.MD
new file mode 100644
index 0000000..8c15453
--- /dev/null
+++ b/BMTR.MD
@@ -0,0 +1,267 @@
+# BMTR 资产接入实现文档
+
+## 一、需求概述
+
+在首页「我的资产」区域新增 **BMTR** 卡片,展示当前登录用户的 BMTR 数量。
+
+数据来源:
+
+```
+GET /api/mxj/api/get_user
+```
+
+返回示例:
+
+```json
+{
+ "status": 200,
+ "msg": "success",
+ "data": {
+ "uid": 94227,
+ "nickname": "siediyer",
+ "avatar": "https://thirdwx.qlogo.cn/...",
+ "mxj_points": "99999.00",
+ "bmtr": "11.0000",
+ "is_check": 1,
+ "is_idcard": 1,
+ "is_sign": 1,
+ "sign_time": 1781172245,
+ "status": 1
+ }
+}
+```
+
+---
+
+## 二、API 请求运行方式
+
+项目中的网络请求采用三层结构:
+
+```
+页面 (pages/index/index.vue)
+ ↓ 调用
+api/assets.js 中的业务方法
+ ↓ 调用
+utils/request.js 中的通用 request 方法
+ ↓ 调用
+uni.request 发送 HTTP 请求
+```
+
+### 2.1 配置层:`config/service.js`
+
+定义了接口基础地址和 endpoint 映射表。
+
+### 2.2 通用请求层:`utils/request.js`
+
+- 自动拼接 `BASE_URL` 和 `url`
+- 统一注入 `Authori-zation` / `Authorization` Token
+- 统一处理 `showLoading` / `hideLoading`
+- 对响应进行 `statusCode` 校验,返回 `response.data`
+
+### 2.3 业务 API 层:`api/assets.js`
+
+- 封装 `fetchPayload` 统一处理 `{ status: 200, data: {...} }` 结构
+- 提供 `createRequestOptions` 合并请求参数
+- 提供 `buildHomeOverview` 将原始接口数据转换为页面渲染数据
+
+---
+
+## 三、本次改动文件
+
+| 文件 | 改动内容 |
+| ----------------------- | ------------------------------------------------------------------ |
+| `config/service.js` | 新增 `getUser` endpoint |
+| `api/assets.js` | 新增 `fetchUserData`,修改 `buildHomeOverview` 和 `fetchAssetHome` |
+| `pages/index/index.vue` | 新增 BMTR 图标、背景、点击跳转 |
+| `BMTR.MD` | 本文档 |
+
+---
+
+## 四、具体改动
+
+### 4.1 `config/service.js`
+
+在 `ENDPOINTS` 中新增:
+
+```javascript
+getUser: "/api/mxj/api/get_user",
+```
+
+### 4.2 `api/assets.js`
+
+#### 4.2.1 新增获取用户数据的函数
+
+```javascript
+async function fetchUserData(requestOptions) {
+ return fetchPayload(
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.getUser,
+ },
+ requestOptions,
+ ),
+ "用户信息加载失败",
+ );
+}
+```
+
+#### 4.2.2 修改 `buildHomeOverview`
+
+函数签名从:
+
+```javascript
+function buildHomeOverview(balanceData, tickerData) {
+```
+
+改为:
+
+```javascript
+function buildHomeOverview(balanceData, tickerData, userData) {
+```
+
+在 `rawQuickAssets` 中新增 `bmtr`:
+
+```javascript
+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),
+ bmtr: toRawDisplayValue(userData && userData.bmtr),
+};
+```
+
+在 `quickAssets` 数组中新增 BMTR 项:
+
+```javascript
+{
+ key: "bmtr",
+ title: "BMTR",
+ value: rawQuickAssets.bmtr,
+ accent: "orange",
+},
+```
+
+> `value` 直接使用接口返回的 `bmtr` 字符串。
+> `accent` 设为 `orange`,与页面已有的 `.asset-mini-card--orange` 样式类对应。
+
+#### 4.2.3 修改 `fetchAssetHome`
+
+原来是同时请求价格 + 余额,现在增加用户信息请求:
+
+```javascript
+export async function fetchAssetHome(requestOptions) {
+ const result = await Promise.all([
+ fetchPriceData(requestOptions),
+ fetchHomeBalanceData(requestOptions),
+ fetchUserData(requestOptions),
+ ]);
+ const overview = buildHomeOverview(result[1], result[0], result[2]);
+ setHomeTickerCache(overview.ticker);
+ return overview;
+}
+```
+
+三个请求并行执行,BMTR 接口失败不会阻塞其他两个请求(但会进入 `Promise.all` 的 catch 逻辑,页面会显示错误提示)。
+
+### 4.3 `pages/index/index.vue`
+
+#### 4.3.1 新增图标
+
+在 `quickAssetIcon` 的 `iconMap` 中新增:
+
+```javascript
+bmtr: "https://imgs.agrimedia.cn/bm-bmt/qianbao.png",
+```
+
+> 当前复用已有的钱包图标,后续可替换为 BMTR 专属图标。
+
+#### 4.3.2 新增背景
+
+在 `quickAssetBg` 的 `bgMap` 中新增:
+
+```javascript
+bmtr: "https://imgs.agrimedia.cn/bm-bmt/suanli-bg.png",
+```
+
+> 当前复用算力卡片背景,后续可替换为 BMTR 专属背景。
+
+#### 4.3.3 新增点击跳转
+
+在 `openQuickAsset` 的 `urlMap` 中新增:
+
+```javascript
+bmtr: "/pages/assets/bmtr",
+```
+
+用户点击 BMTR 卡片后,会跳转到 `pages/assets/bmtr.vue` 页面。
+
+---
+
+## 五、首页资产卡片渲染顺序
+
+修改后,首页「我的资产」区域共 6 个卡片,顺序如下:
+
+1. 可用积分
+2. 算力
+3. 消费券
+4. 抵用券
+5. **BMTR(新增)**
+6. 余额
+
+> 由于 `balance` 卡片设置了 `grid-column: 1 / -1`,会单独占一行,所以实际布局为:
+>
+> - 第一行:可用积分、算力
+> - 第二行:消费券、抵用券
+> - 第三行:BMTR
+> - 第四行:余额(整行)
+
+如果希望调整 BMTR 的位置,修改 `api/assets.js` 中 `quickAssets` 数组的顺序即可。
+
+---
+
+## 六、待替换项
+
+| 项目 | 当前值 | 说明 |
+| --------- | ------------------------------------------------------------ | ----------------------- |
+| BMTR 图标 | `https://imgs.agrimedia.cn/webimg/202607171808386371853.svg` | BMTR 专属图标(已替换) |
+| BMTR 背景 | `https://imgs.agrimedia.cn/webimg/202607201122331061368.svg` | BMTR 专属背景(已替换) |
+
+---
+
+## 七、接口字段说明
+
+| 字段 | 类型 | 用途 |
+| ------------ | ------ | --------------------------- |
+| `uid` | number | 用户ID |
+| `nickname` | string | 用户昵称 |
+| `avatar` | string | 头像URL |
+| `mxj_points` | string | MXJ积分 |
+| `bmtr` | string | **BMTR 余额,本次使用字段** |
+| `is_check` | number | 是否通过某种校验 |
+| `is_idcard` | number | 是否实名认证 |
+| `is_sign` | number | 是否签到 |
+| `sign_time` | number | 签到时间戳 |
+| `status` | number | 用户状态 |
+
+---
+
+## 八、验证建议
+
+1. 进入首页,确认「我的资产」区域出现 BMTR 卡片
+2. 确认 BMTR 显示的数值与 `/api/mxj/api/get_user` 返回的 `data.bmtr` 一致
+3. 点击 BMTR 卡片,确认能跳转到 `pages/assets/bmtr`
+4. 检查网络面板,确认三个请求并行发送:
+ - `/api/hn/getPrice`
+ - `/api/hn/getAllBalance`
+ - `/api/mxj/api/get_user`
+5. 如果 BMTR 接口失败,首页应显示错误提示,不影响其他资产卡片的数据逻辑(但 Promise.all 会统一报错,如需降级处理可改为单独 catch)
+
+---
+
+## 九、可能的后续优化
+
+1. **接口降级**:如果 `/api/mxj/api/get_user` 不稳定,可将 `fetchUserData` 从 `Promise.all` 中拆出,单独 catch 并给 BMTR 一个默认值 `0`。
+2. **数值格式化**:当前 `bmtr` 直接显示为字符串,如需统一显示为 `11.00` 或 `11.0000`,可在 `buildHomeOverview` 中使用 `toFixedNumber` 处理。
+3. **图标替换**:拿到 BMTR 专属图标和背景后,更新 `pages/index/index.vue` 中的 `iconMap` 和 `bgMap`。
diff --git a/api/assets.js b/api/assets.js
index 013bcf7..211f99b 100644
--- a/api/assets.js
+++ b/api/assets.js
@@ -97,8 +97,7 @@ function normalizeTicker(data) {
return {
symbol: (data && data.symbol) || "BMT/CNY",
close: close,
- cnyPrice:
- (data && data.cnyPrice) || (close ? close.toFixed(2) : "0.00"),
+ cnyPrice: (data && data.cnyPrice) || (close ? close.toFixed(2) : "0.00"),
lastDayClose: lastDayClose,
change: change,
};
@@ -158,7 +157,7 @@ function toRawDisplayValue(value) {
return String(value);
}
-function buildHomeOverview(balanceData, tickerData) {
+function buildHomeOverview(balanceData, tickerData, userData) {
const balances = normalizeBalances(balanceData);
const ticker = normalizeTicker(tickerData);
const rawQuickAssets = {
@@ -167,6 +166,7 @@ function buildHomeOverview(balanceData, tickerData) {
voucher: toRawDisplayValue(balanceData && balanceData.coin),
coupon: toRawDisplayValue(balanceData && balanceData.diamond_balance),
power: toRawDisplayValue(balanceData && balanceData.c_power),
+ bmtr: toRawDisplayValue(userData && userData.bmtr),
};
return {
@@ -195,63 +195,68 @@ function buildHomeOverview(balanceData, tickerData) {
value: rawQuickAssets.points,
accent: "gold",
},
- {
- key: "power",
- title: "算力",
- value: rawQuickAssets.power,
- accent: "violet",
- },
- {
- key: "coupon",
- title: "消费券",
- value: rawQuickAssets.coupon,
- accent: "teal",
- },
+ {
+ 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",
- },
-
+ {
+ key: "balance",
+ title: "余额",
+ value: rawQuickAssets.balance,
+ accent: "blue",
+ },
+ {
+ key: "bmtr",
+ title: "BMTR",
+ value: rawQuickAssets.bmtr,
+ accent: "orange",
+ },
],
features: [
- {
- key: "points-convert",
- title: "积分转换",
- desc: "释放中的积分转换为可用积分",
- accent: "pink",
- },
+ {
+ key: "points-convert",
+ title: "积分转换",
+ desc: "释放中的积分转换为可用积分",
+ accent: "pink",
+ },
{
key: "power-exchange",
title: "算力兑换",
desc: "抵用券与消费券兑换算力",
accent: "amber",
},
- {
- key: "bmt-flash",
- title: "BMT闪兑",
- desc: "BMT闪兑",
- accent: "indigo",
- },
+ {
+ 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: "bmt-exchange",
+ title: "BMT兑换",
+ desc: "积分与算力兑换 BMT",
+ accent: "mint",
+ },
{
key: "withdraw",
title: "BMT提取",
@@ -273,10 +278,7 @@ function buildTransferTips(feePercent) {
"凌晨00:00至02:00为系统维护时段不可赠送",
"转赠系统会扣除" + percentText + "%的手续费",
],
- power: [
- "只能转赠1的整数倍",
- "转赠系统会扣除" + percentText + "%的手续费",
- ],
+ power: ["只能转赠1的整数倍", "转赠系统会扣除" + percentText + "%的手续费"],
};
}
@@ -453,7 +455,8 @@ function parseBooleanLike(value) {
function buildPaginationMeta(data, requestPagination) {
const normalizedData = data && typeof data === "object" ? data : {};
- const normalizedRequestPagination = normalizePaginationOptions(requestPagination);
+ const normalizedRequestPagination =
+ normalizePaginationOptions(requestPagination);
const list = normalizeListData(normalizedData);
const page =
Math.floor(
@@ -548,7 +551,12 @@ function formatLedgerRecordNumber(value) {
return formatTransferRecordNumber(Math.abs(toNumber(value)));
}
-function resolveRecordDirection(item, amountValue, positiveLabel, negativeLabel) {
+function resolveRecordDirection(
+ item,
+ amountValue,
+ positiveLabel,
+ negativeLabel,
+) {
const rawDirection = pickFirstValue(item, [
"io_type",
"in_out",
@@ -670,7 +678,8 @@ function mapWalletFlowRecords(list, meta) {
pickFirstValue(item, ["title", "name", "type_name"]) ||
meta.title ||
meta.unit + "记录";
- const isPointsLedger = String(meta && meta.key ? meta.key : "") === "points";
+ const isPointsLedger =
+ String(meta && meta.key ? meta.key : "") === "points";
const displayTitle = isPointsLedger
? normalizeAvailablePointsText(title)
: title;
@@ -882,7 +891,9 @@ function getTransferRecordAmount(item) {
}
function extractTransferTitleFeeValue(item) {
- const titleText = String(pickFirstValue(item, ["title", "name"]) || "").trim();
+ const titleText = String(
+ pickFirstValue(item, ["title", "name"]) || "",
+ ).trim();
if (!titleText) {
return "";
@@ -916,7 +927,9 @@ function getTransferRecordFee(item) {
return toNumber(item.fee);
}
- return (toNumber(item && item.num) * toNumber(item && item.fee_percent)) / 100;
+ return (
+ (toNumber(item && item.num) * toNumber(item && item.fee_percent)) / 100
+ );
}
function getTransferRecordFeeText(item) {
@@ -938,7 +951,9 @@ function getTransferRecordBalance(item) {
function getTransferRecordBalanceLabel(item) {
const unit = getTransferRecordUnit(item);
- return "剩余" + unit + ":" + formatTransferRecordNumber(item && item.balance);
+ return (
+ "剩余" + unit + ":" + formatTransferRecordNumber(item && item.balance)
+ );
}
function mapTransferRecords(list) {
@@ -947,7 +962,9 @@ function mapTransferRecords(list) {
return {
id: item.order_sn || item.id || String(Math.random()),
title: normalizeTransferPointsText(titleText, item),
- subtitle: item.order_sn ? "单号 " + item.order_sn : getTransferRecordDirection(item),
+ subtitle: item.order_sn
+ ? "单号 " + item.order_sn
+ : getTransferRecordDirection(item),
time: item.add_time || "",
amount: getTransferRecordAmount(item),
balance: getTransferRecordBalance(item),
@@ -1031,13 +1048,9 @@ function mapPointsConvertRecords(list) {
pickFirstValue(item, ["order_sn", "trade_no", "bill_no", "sn"]) || "",
),
title:
- pickFirstValue(item, ["title", "name", "type_name"]) ||
- "系统赠送积分",
+ pickFirstValue(item, ["title", "name", "type_name"]) || "系统赠送积分",
subtitle:
- "可转数量 " +
- formatTransferRecordNumber(
- rawTransferPointValue || 0,
- ),
+ "可转数量 " + formatTransferRecordNumber(rawTransferPointValue || 0),
time: pickFirstValue(item, [
"add_time",
"create_time",
@@ -1085,9 +1098,7 @@ function extractMonthLabel(value) {
}
return (
- date.getFullYear() +
- "-" +
- String(date.getMonth() + 1).padStart(2, "0")
+ date.getFullYear() + "-" + String(date.getMonth() + 1).padStart(2, "0")
);
}
@@ -1111,7 +1122,8 @@ function buildMonthOptions(list) {
result,
item,
) {
- const month = item && item.month ? item.month : extractMonthLabel(item && item.time);
+ const month =
+ item && item.month ? item.month : extractMonthLabel(item && item.time);
if (month && result.indexOf(month) === -1) {
result.push(month);
}
@@ -1261,22 +1273,25 @@ function buildPointsConvertDetailPayload(data, fallbackRecord) {
"created_at",
"time",
"update_time",
- ]) || fallback.time || "",
+ ]) ||
+ fallback.time ||
+ "",
};
});
if (!detailList.length) {
return buildPointsConvertDetailFallback({
id: fallback.id,
- orderSn:
- String(
- pickFirstValue(summarySource, [
- "order_sn",
- "trade_no",
- "bill_no",
- "sn",
- ]) || fallback.orderSn || "",
- ),
+ orderSn: String(
+ pickFirstValue(summarySource, [
+ "order_sn",
+ "trade_no",
+ "bill_no",
+ "sn",
+ ]) ||
+ fallback.orderSn ||
+ "",
+ ),
title:
pickFirstValue(summarySource, ["title", "name", "type_name"]) ||
fallback.title,
@@ -1294,7 +1309,12 @@ function buildPointsConvertDetailPayload(data, fallbackRecord) {
return {
orderSn: String(
- pickFirstValue(summarySource, ["order_sn", "trade_no", "bill_no", "sn"]) ||
+ pickFirstValue(summarySource, [
+ "order_sn",
+ "trade_no",
+ "bill_no",
+ "sn",
+ ]) ||
fallback.orderSn ||
"",
),
@@ -1306,7 +1326,9 @@ function buildPointsConvertDetailPayload(data, fallbackRecord) {
"created_at",
"time",
"update_time",
- ]) || fallback.time || "",
+ ]) ||
+ fallback.time ||
+ "",
details: detailList,
};
}
@@ -1352,8 +1374,7 @@ function normalizeTransferTarget(data, fallbackId) {
return {
id: id,
- nickname:
- data.nickname || data.nick_name || data.username || "用户" + id,
+ nickname: data.nickname || data.nick_name || data.username || "用户" + id,
phone: data.mobile || data.phone || "ID已通过校验",
avatar: data.avatar || data.headimg || "",
};
@@ -1384,36 +1405,48 @@ function sumBy(list, key) {
async function fetchPriceData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.price,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.price,
+ },
+ requestOptions,
+ ),
"实时价格加载失败",
);
}
async function fetchHomeBalanceData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.homeBalance,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.homeBalance,
+ },
+ requestOptions,
+ ),
"首页资产加载失败",
);
}
async function fetchBmtPowerRateData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.bmtRedeemPowerRate,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.bmtRedeemPowerRate,
+ },
+ requestOptions,
+ ),
"兑换比例加载失败",
);
}
async function fetchPowerExchangeMuitData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.powerExchangeMuit,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.powerExchangeMuit,
+ },
+ requestOptions,
+ ),
"兑换倍率加载失败",
);
}
@@ -1438,20 +1471,38 @@ function resolveRedeemPowerRate(data) {
return normalizedRate > 0 ? normalizedRate : 0;
}
+async function fetchUserData(requestOptions) {
+ return fetchPayload(
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.getUser,
+ },
+ requestOptions,
+ ),
+ "用户信息加载失败",
+ );
+}
+
async function fetchTransferFeeData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.transferFee,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.transferFee,
+ },
+ requestOptions,
+ ),
"手续费比例加载失败",
);
}
async function fetchWithdrawRateData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.withdrawRate,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.withdrawRate,
+ },
+ requestOptions,
+ ),
"提现费率加载失败",
);
}
@@ -1488,27 +1539,36 @@ function resolvePercentRate(data) {
async function fetchWalletAddressData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.walletDetail,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.walletDetail,
+ },
+ requestOptions,
+ ),
"钱包加载失败",
);
}
async function fetchCoinIndexData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.coinIndex,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.coinIndex,
+ },
+ requestOptions,
+ ),
"抵用券信息加载失败",
);
}
async function fetchUserProfileData(requestOptions) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.userProfile,
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.userProfile,
+ },
+ requestOptions,
+ ),
"用户信息加载失败",
);
}
@@ -1542,12 +1602,18 @@ function normalizePointsConvertInterval(value) {
async function fetchPointsConvertList(pagination, requestOptions, interval) {
const normalizedInterval = normalizePointsConvertInterval(interval);
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.pointsConvertAvailableList,
- data: buildPagingRequestData({
- interval: normalizedInterval,
- }, pagination),
- }, requestOptions),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.pointsConvertAvailableList,
+ data: buildPagingRequestData(
+ {
+ interval: normalizedInterval,
+ },
+ pagination,
+ ),
+ },
+ requestOptions,
+ ),
"积分转换列表加载失败",
);
}
@@ -1558,56 +1624,84 @@ async function fetchPointsConvertHistoryListData(
requestOptions,
) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.pointsConvertHistoryList,
- data: buildPagingRequestData({
- month: month,
- }, pagination),
- }, requestOptions),
+ 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),
+ 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),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.walletFlowList,
+ data: buildPagingRequestData(
+ {
+ type: flowType,
+ },
+ pagination,
+ ),
+ },
+ requestOptions,
+ ),
"资产流水加载失败",
);
}
-async function fetchRedeemRecordListData(redeemType, pagination, requestOptions) {
+async function fetchRedeemRecordListData(
+ redeemType,
+ pagination,
+ requestOptions,
+) {
return fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.redeemRecordList,
- data: buildPagingRequestData({
- type: redeemType,
- }, pagination),
- }, requestOptions),
+ 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),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.pointsConvertRecordDetail,
+ data: query || {},
+ },
+ requestOptions,
+ ),
"积分转换详情加载失败",
);
}
@@ -1616,8 +1710,9 @@ export async function fetchAssetHome(requestOptions) {
const result = await Promise.all([
fetchPriceData(requestOptions),
fetchHomeBalanceData(requestOptions),
+ fetchUserData(requestOptions),
]);
- const overview = buildHomeOverview(result[1], result[0]);
+ const overview = buildHomeOverview(result[1], result[0], result[2]);
setHomeTickerCache(overview.ticker);
return overview;
}
@@ -1678,11 +1773,7 @@ export async function fetchPointsConvertHome(
const mergedRequestOptions = params.requestOptions;
const result = await Promise.all([
fetchHomeBalanceData(mergedRequestOptions),
- fetchPointsConvertHistoryListData(
- month,
- pagination,
- mergedRequestOptions,
- ),
+ fetchPointsConvertHistoryListData(month, pagination, mergedRequestOptions),
]);
const balances = normalizeBalances(result[0]);
const records = buildPointsHistoryRecords(result[1]).map(function (item) {
@@ -1704,8 +1795,7 @@ export async function fetchPointsConvertSelection(
requestOptions,
) {
const interval =
- paginationOrRequestOptions &&
- typeof paginationOrRequestOptions === "object"
+ paginationOrRequestOptions && typeof paginationOrRequestOptions === "object"
? paginationOrRequestOptions.interval
: "";
const params = resolvePagingArguments(
@@ -1765,14 +1855,17 @@ export async function submitAssetPointsConvert(payload, requestOptions) {
}
await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.pointsConvertSubmit,
- method: "POST",
- data: {
- ids: ids.join(","),
- type: 1,
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.pointsConvertSubmit,
+ method: "POST",
+ data: {
+ ids: ids.join(","),
+ type: 1,
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"积分转换失败",
);
@@ -1807,13 +1900,16 @@ export async function searchTransferUser(uid, requestOptions) {
}
const data = await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.transferUser,
- method: "POST",
- data: {
- uid: keyword,
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.transferUser,
+ method: "POST",
+ data: {
+ uid: keyword,
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"查询好友失败",
);
@@ -1822,7 +1918,9 @@ export async function searchTransferUser(uid, requestOptions) {
export async function submitAssetTransfer(payload, requestOptions) {
const transferType = payload && payload.type === "power" ? "power" : "points";
- const targetId = String(payload && payload.targetId ? payload.targetId : "").trim();
+ const targetId = String(
+ payload && payload.targetId ? payload.targetId : "",
+ ).trim();
const amount = toNumber(payload && payload.amount);
if (!targetId) {
@@ -1836,17 +1934,20 @@ export async function submitAssetTransfer(payload, requestOptions) {
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),
+ createRequestOptions(
+ {
+ url:
+ transferType === "power"
+ ? serviceConfig.ENDPOINTS.transferPowerSubmit
+ : serviceConfig.ENDPOINTS.transferPointsSubmit,
+ method: "POST",
+ data: {
+ uid: targetId,
+ number: String(amount),
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"转赠失败",
),
]);
@@ -1901,14 +2002,17 @@ export async function submitAssetPowerExchange(payload, requestOptions) {
}
await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.powerExchangeSubmit,
- method: "POST",
- data: {
- type: mode === "coupon" ? 1 : mode === "balance" ? 2 : 0,
- number: String(amount),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.powerExchangeSubmit,
+ method: "POST",
+ data: {
+ type: mode === "coupon" ? 1 : mode === "balance" ? 2 : 0,
+ number: String(amount),
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"算力兑换失败",
);
@@ -1957,14 +2061,17 @@ export async function submitAssetBmtFlashExchange(payload, requestOptions) {
}
await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.bmtFlashExchangeSubmit,
- method: "POST",
- data: {
- type: mode === "coupon" ? 1 : mode === "balance" ? 2 : 0,
- number: String(amount),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.bmtFlashExchangeSubmit,
+ method: "POST",
+ data: {
+ type: mode === "coupon" ? 1 : mode === "balance" ? 2 : 0,
+ number: String(amount),
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"BMT闪兑失败",
);
@@ -1973,7 +2080,6 @@ export async function submitAssetBmtFlashExchange(payload, requestOptions) {
};
}
-
// BMT兑换
export async function fetchBmtExchangeDetail(requestOptions) {
const result = await Promise.all([
@@ -1984,7 +2090,7 @@ export async function fetchBmtExchangeDetail(requestOptions) {
const ticker = getHomeTickerCache();
const balances = normalizeBalances(result[0]);
const powerRate = resolveRedeemPowerRate(result[1]);
-
+
return {
ticker: ticker,
powerRate: powerRate,
@@ -2012,13 +2118,16 @@ export async function submitAssetBmtExchange(payload, requestOptions) {
}
await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.bmtExchangeSubmit,
- method: "POST",
- data: {
- number: String(amount),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.bmtExchangeSubmit,
+ method: "POST",
+ data: {
+ number: String(amount),
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"BMT兑换失败",
);
@@ -2070,14 +2179,17 @@ export async function submitAssetWithdraw(payload, requestOptions) {
}
await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.withdrawSubmit,
- method: "POST",
- data: {
- address: address,
- number: String(amount),
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.withdrawSubmit,
+ method: "POST",
+ data: {
+ address: address,
+ number: String(amount),
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"提取失败",
);
@@ -2099,7 +2211,10 @@ export async function fetchLedgerDetail(
const mergedRequestOptions = params.requestOptions;
if (type === "transfer") {
- const data = await fetchTransferLedgerData(pagination, mergedRequestOptions);
+ const data = await fetchTransferLedgerData(
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "转赠记录",
@@ -2110,7 +2225,11 @@ export async function fetchLedgerDetail(
}
if (type === "points") {
- const data = await fetchWalletFlowListData(0, pagination, mergedRequestOptions);
+ const data = await fetchWalletFlowListData(
+ 0,
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "可用积分记录",
@@ -2126,7 +2245,11 @@ export async function fetchLedgerDetail(
}
if (type === "power-flow") {
- const data = await fetchWalletFlowListData(1, pagination, mergedRequestOptions);
+ const data = await fetchWalletFlowListData(
+ 1,
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "算力记录",
@@ -2142,7 +2265,11 @@ export async function fetchLedgerDetail(
}
if (type === "power") {
- const data = await fetchRedeemRecordListData(0, pagination, mergedRequestOptions);
+ const data = await fetchRedeemRecordListData(
+ 0,
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "兑换记录",
@@ -2167,7 +2294,11 @@ export async function fetchLedgerDetail(
}
if (type === "bmt") {
- const data = await fetchRedeemRecordListData(1, pagination, mergedRequestOptions);
+ const data = await fetchRedeemRecordListData(
+ 1,
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "兑换记录",
@@ -2185,7 +2316,11 @@ export async function fetchLedgerDetail(
}
if (type === "bmt-flash") {
- const data = await fetchRedeemRecordListData(1, pagination, mergedRequestOptions);
+ const data = await fetchRedeemRecordListData(
+ 1,
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "闪兑记录",
@@ -2203,7 +2338,11 @@ export async function fetchLedgerDetail(
}
if (type === "withdraw") {
- const data = await fetchWalletFlowListData(2, pagination, mergedRequestOptions);
+ const data = await fetchWalletFlowListData(
+ 2,
+ pagination,
+ mergedRequestOptions,
+ );
return {
type: type,
title: "提取记录",
@@ -2237,20 +2376,25 @@ export async function fetchWalletDetail(requestOptions) {
}
export async function saveAssetWallet(payload, requestOptions) {
- const address = String(payload && payload.address ? payload.address : "").trim();
+ 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,
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.walletSave,
+ method: "POST",
+ data: {
+ address: address,
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"保存失败",
);
@@ -2261,13 +2405,16 @@ export async function saveAssetWallet(payload, requestOptions) {
export async function deleteAssetWallet(id, requestOptions) {
await fetchPayload(
- createRequestOptions({
- url: serviceConfig.ENDPOINTS.walletSave,
- method: "POST",
- data: {
- address: "",
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.walletSave,
+ method: "POST",
+ data: {
+ address: "",
+ },
},
- }, requestOptions),
+ requestOptions,
+ ),
"删除失败",
);
@@ -2275,3 +2422,91 @@ export async function deleteAssetWallet(id, requestOptions) {
success: true,
};
}
+
+function padTimeUnit(value) {
+ return value < 10 ? "0" + value : String(value);
+}
+
+function formatTimestamp(timestamp) {
+ const seconds = toNumber(timestamp);
+
+ if (!seconds) {
+ return "";
+ }
+
+ const date = new Date(seconds * 1000);
+
+ return (
+ date.getFullYear() +
+ "-" +
+ padTimeUnit(date.getMonth() + 1) +
+ "-" +
+ padTimeUnit(date.getDate()) +
+ " " +
+ padTimeUnit(date.getHours()) +
+ ":" +
+ padTimeUnit(date.getMinutes()) +
+ ":" +
+ padTimeUnit(date.getSeconds())
+ );
+}
+
+function mapBmtrRecords(list) {
+ return normalizeListData(list).map(function (item) {
+ const amountValue = toNumber(item && item.bmtr);
+ // 交易类型:0 支出,1 收入,2 退回
+ const bmtrType = Number(item && item.bmtr_type);
+ const isIncome = bmtrType === 1 || bmtrType === 2;
+
+ return {
+ id: buildRecordId(item, "bmtr"),
+ title: String(pickFirstValue(item, ["bmtr_type_tips", "title"]) || "BMTR记录"),
+ time: formatTimestamp(item && item.add_time),
+ amount: isIncome ? Math.abs(amountValue) : -Math.abs(amountValue),
+ orderSn: String(pickFirstValue(item, ["order_sn", "sn"]) || ""),
+ };
+ });
+}
+
+export async function fetchBmtrDetail(requestOptions) {
+ const data = await fetchPayload(
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.bmtrMonthPoints,
+ },
+ requestOptions,
+ ),
+ "BMTR信息加载失败",
+ );
+ const bmtrValue = pickFirstValue(data, ["bmtr"]);
+
+ return {
+ available: bmtrValue === "" ? "0.0000" : String(bmtrValue),
+ address: String(pickFirstValue(data, ["address"]) || ""),
+ };
+}
+
+export async function fetchBmtrRecords(
+ paginationOrRequestOptions,
+ requestOptions,
+) {
+ const params = resolvePagingArguments(
+ paginationOrRequestOptions,
+ requestOptions,
+ );
+ const data = await fetchPayload(
+ createRequestOptions(
+ {
+ url: serviceConfig.ENDPOINTS.bmtrChargeList,
+ data: buildPagingRequestData({}, params.pagination),
+ },
+ params.requestOptions,
+ ),
+ "BMTR记录加载失败",
+ );
+
+ return {
+ records: mapBmtrRecords(data),
+ pagination: buildPaginationMeta(data, params.pagination),
+ };
+}
diff --git a/config/service.js b/config/service.js
index a938e3f..32a4062 100644
--- a/config/service.js
+++ b/config/service.js
@@ -16,6 +16,7 @@ const serviceConfig = {
powerExchangeMuit: "/api/hn/redeem/getMuit",
bmtRedeemPowerRate: "/api/hn/redeem/getRedeemPowerRate",
bmtExchangeSubmit: "/api/hn/redeem/redeem_bmt",
+ getUser: "/api/mxj/api/get_user",
transferFee: "/api/hn/transfer/getProp",
transferUser: "/api/hn/transfer/getUserInfo",
transferPowerSubmit: "/api/hn/transfer/transferPower",
@@ -33,6 +34,8 @@ const serviceConfig = {
pointsConvertAvailableList: "/api/integral/transferList",
pointsConvertSubmit: "/api/integral/doTransfer",
pointsConvertRecordDetail: "/api/integral/transferInfo",
+ bmtrMonthPoints: "/api/mxj/api/get_month_points",
+ bmtrChargeList: "/api/mxj/api/get_charge_list",
},
};
diff --git a/manifest.json b/manifest.json
index ff5e05f..b9c6ccd 100644
--- a/manifest.json
+++ b/manifest.json
@@ -73,6 +73,15 @@
"router" : {
"base" : "/bmt/",
"mode" : "history"
+ },
+ "devServer" : {
+ "proxy" : {
+ "/api" : {
+ "target" : "https://tpoint.agrimedia.cn",
+ "changeOrigin" : true,
+ "secure" : false
+ }
+ }
}
}
}
diff --git a/pages.json b/pages.json
index 3f8bdcf..9df4f42 100644
--- a/pages.json
+++ b/pages.json
@@ -85,6 +85,13 @@
"navigationStyle": "custom",
"backgroundColor": "#191E32"
}
+ },
+ {
+ "path": "pages/assets/bmtr",
+ "style": {
+ "navigationStyle": "custom",
+ "backgroundColor": "#191E32"
+ }
}
],
"globalStyle": {
diff --git a/pages/assets/bmtr.vue b/pages/assets/bmtr.vue
new file mode 100644
index 0000000..6749056
--- /dev/null
+++ b/pages/assets/bmtr.vue
@@ -0,0 +1,535 @@
+
+
+
+
+
+
+
+
+
+ R
+
+ BMTR
+
+ 可用 BMTR:
+ {{
+ summary.available
+ }}
+
+
+
+
+
+
+
+
+
+ 白马提回地址
+
+
+
+ 从交易所提回BMTR的地址
+ {{ displayAddress }}
+
+
+ {{
+ isAddressVisible ? "隐藏" : "显示"
+ }}
+ 复制
+
+
+
+
+ BMTR记录
+
+
+
+
+ {{ item.title }}
+ {{ item.time }}
+
+ {{ formatAmount(item.amount) }}
+
+
+
+
+ 暂无记录
+
+
+
+ {{ loadMoreText }}
+
+
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
index 4087468..947b7ea 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -5,12 +5,9 @@
{{ overview.title || "数字资产" }}
-
+
- 钱包
+ 钱包1
@@ -19,7 +16,8 @@
-
+
@@ -29,7 +27,8 @@
-
+
@@ -39,7 +38,8 @@
-
+
@@ -63,13 +63,8 @@
-
+
{{ item.title }}
@@ -86,21 +81,11 @@
我的资产
-
-
+
+
{{ item.title }}
@@ -114,19 +99,11 @@
功能中心
-
+
-
+
{{ feature.title }}
@@ -136,15 +113,12 @@
-
+
{{ overview.notice }}
-
-
+
+
+
@@ -222,6 +196,7 @@ export default {
voucher: "https://imgs.agrimedia.cn/bm-bmt/quan-icon.png",
coupon: "https://imgs.agrimedia.cn/bm-bmt/xiaofei-icon.png",
power: "https://imgs.agrimedia.cn/bm-bmt/suanli-icon.png",
+ bmtr: "https://imgs.agrimedia.cn/webimg/202607171808386371853.svg",
};
return iconMap[key] || "";
@@ -233,6 +208,7 @@ export default {
voucher: "https://imgs.agrimedia.cn/bm-bmt/quan-bg.png",
coupon: "https://imgs.agrimedia.cn/bm-bmt/xiaofei-bg.png",
power: "https://imgs.agrimedia.cn/bm-bmt/suanli-bg.png",
+ bmtr: "https://imgs.agrimedia.cn/webimg/202607201122331061368.svg",
};
return bgMap[key] || "";
@@ -308,6 +284,7 @@ export default {
const urlMap = {
points: "/pages/assets/ledger?type=points",
power: "/pages/assets/ledger?type=power-flow",
+ bmtr: "/pages/assets/bmtr",
};
const targetUrl = urlMap[item.key];
@@ -446,6 +423,7 @@ export default {
width: 30rpx;
height: 32rpx;
margin-right: 8rpx;
+
image {
width: 30rpx;
height: 32rpx;
@@ -479,12 +457,10 @@ export default {
bottom: 0;
left: -140rpx;
width: 140rpx;
- background: linear-gradient(
- 90deg,
- rgba(255, 255, 255, 0) 0%,
- rgba(255, 255, 255, 0.24) 50%,
- rgba(255, 255, 255, 0) 100%
- );
+ background: linear-gradient(90deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(255, 255, 255, 0.24) 50%,
+ rgba(255, 255, 255, 0) 100%);
animation: home-skeleton-shimmer 1.35s linear infinite;
}
@@ -644,6 +620,7 @@ export default {
0% {
transform: translateX(0);
}
+
100% {
transform: translateX(900rpx);
}
@@ -660,13 +637,10 @@ export default {
height: 380rpx;
border-radius: 28rpx;
background:
- linear-gradient(
- 180deg,
+ linear-gradient(180deg,
rgba(5, 12, 28, 0.06) 0%,
- rgba(5, 12, 28, 0.16) 100%
- ),
- url("https://imgs.agrimedia.cn/bm-bmt/home2-bg.png")
- no-repeat;
+ rgba(5, 12, 28, 0.16) 100%),
+ url("https://imgs.agrimedia.cn/bm-bmt/home2-bg.png") no-repeat;
border: 1px solid rgba(112, 135, 196, 0.18);
background-size: cover;
box-shadow: 0 24rpx 48rpx rgba(7, 12, 32, 0.28);
@@ -710,11 +684,9 @@ export default {
min-height: 126rpx;
padding: 22rpx 22rpx 20rpx;
border-radius: 8rpx;
- background: linear-gradient(
- 180deg,
- rgba(42, 55, 82, 0.98) 0%,
- rgba(39, 51, 76, 0.98) 100%
- );
+ background: linear-gradient(180deg,
+ rgba(42, 55, 82, 0.98) 0%,
+ rgba(39, 51, 76, 0.98) 100%);
border: 1px solid rgba(121, 139, 190, 0.16);
box-shadow: 0 14rpx 24rpx rgba(5, 11, 29, 0.2);
}
@@ -742,19 +714,15 @@ export default {
}
.stat-card__icon-box--gold {
- background: linear-gradient(
- 135deg,
- rgba(20, 182, 255, 0.22) 0%,
- rgba(20, 182, 255, 0.08) 100%
- );
+ background: linear-gradient(135deg,
+ rgba(20, 182, 255, 0.22) 0%,
+ rgba(20, 182, 255, 0.08) 100%);
}
.stat-card__icon-box--green {
- background: linear-gradient(
- 135deg,
- rgba(46, 233, 167, 0.22) 0%,
- rgba(46, 233, 167, 0.08) 100%
- );
+ background: linear-gradient(135deg,
+ rgba(46, 233, 167, 0.22) 0%,
+ rgba(46, 233, 167, 0.08) 100%);
}
.stat-card__body {
@@ -844,9 +812,9 @@ export default {
background: rgba(35, 45, 79, 0.9);
}
-.asset-mini-card--full {
- grid-column: 1 / -1;
-}
+// .asset-mini-card--full {
+// grid-column: 1 / -1;
+// }
.asset-mini-card__bg {
position: absolute;
diff --git a/uni.webview.1.5.8.js b/uni.webview.1.5.8.js
new file mode 100644
index 0000000..052bce1
--- /dev/null
+++ b/uni.webview.1.5.8.js
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AtomGit - 全球开发者的开源社区,开源代码托管平台
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+