fix: show coin seller transfer details
This commit is contained in:
parent
f7a3a68a1d
commit
d2cc6a3dd4
@ -158,6 +158,11 @@
|
||||
return Number.isFinite(number) ? number : 0;
|
||||
}
|
||||
|
||||
function positiveNumber(value) {
|
||||
var number = toNumber(value);
|
||||
return number > 0 ? number : 0;
|
||||
}
|
||||
|
||||
function firstValue(source, keys) {
|
||||
if (!source) return '';
|
||||
for (var i = 0; i < keys.length; i += 1) {
|
||||
@ -210,9 +215,7 @@
|
||||
|
||||
function hasAPI() {
|
||||
return (
|
||||
window.HyAppAPI &&
|
||||
window.HyAppAPI.user &&
|
||||
window.HyAppAPI.wallet
|
||||
window.HyAppAPI && window.HyAppAPI.user && window.HyAppAPI.wallet
|
||||
);
|
||||
}
|
||||
|
||||
@ -340,6 +343,67 @@
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeTransferAmount(item) {
|
||||
// 转账美金来自服务端账务 metadata;不同入账来源汇率可能不同,前端不能用金币数反推,缺字段时保持不展示。
|
||||
var minor = positiveNumber(
|
||||
firstValue(item, [
|
||||
'transfer_usd_minor',
|
||||
'transferUsdMinor',
|
||||
'salary_usd_minor',
|
||||
'salaryUsdMinor',
|
||||
'recharge_usd_minor',
|
||||
'rechargeUsdMinor',
|
||||
'usd_minor_amount',
|
||||
'usdMinorAmount',
|
||||
])
|
||||
);
|
||||
if (minor > 0) return minor / 100;
|
||||
var micro = positiveNumber(
|
||||
firstValue(item, [
|
||||
'paid_amount_micro',
|
||||
'paidAmountMicro',
|
||||
'amount_usdt_micro',
|
||||
'amountUsdtMicro',
|
||||
])
|
||||
);
|
||||
if (micro > 0) return micro / 1000000;
|
||||
return positiveNumber(
|
||||
firstValue(item, [
|
||||
'amount_usd',
|
||||
'amountUsd',
|
||||
'transfer_amount_usd',
|
||||
'transferAmountUsd',
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeTransferCurrency(item, amount) {
|
||||
return amount > 0
|
||||
? String(
|
||||
firstValue(item, [
|
||||
'transfer_currency_code',
|
||||
'transferCurrencyCode',
|
||||
'recharge_currency_code',
|
||||
'rechargeCurrencyCode',
|
||||
'paid_currency_code',
|
||||
'paidCurrencyCode',
|
||||
'currency_code',
|
||||
'currencyCode',
|
||||
]) || 'USD'
|
||||
).toUpperCase()
|
||||
: '';
|
||||
}
|
||||
|
||||
function formatTransferAmount(amount, currency) {
|
||||
if (!amount || amount <= 0) return '';
|
||||
var code = String(currency || 'USD').toUpperCase();
|
||||
var value = Number(amount).toLocaleString('en-US', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
return code + ' ' + value;
|
||||
}
|
||||
|
||||
function normalizeResolvedUser(payload, keyword) {
|
||||
var source = unwrapData(payload) || {};
|
||||
var identity = source.identity || source.user_identity || source;
|
||||
@ -399,7 +463,8 @@
|
||||
);
|
||||
var type = delta >= 0 ? 'income' : 'expenditure';
|
||||
var counterpartyUserID = String(
|
||||
firstValue(item, ['counterparty_user_id', 'counterpartyUserId']) || ''
|
||||
firstValue(item, ['counterparty_user_id', 'counterpartyUserId']) ||
|
||||
''
|
||||
);
|
||||
var counterpartyDisplayID = String(
|
||||
firstValue(item, [
|
||||
@ -419,19 +484,21 @@
|
||||
'counterpartyAvatar',
|
||||
]);
|
||||
var counterpartyUID = counterpartyDisplayID || counterpartyUserID;
|
||||
// 入账流水也可能来自某个用户的工资转币商,标题必须优先展示对方资料;只有后台进货这类没有对方用户的流水才展示库存入账。
|
||||
var name =
|
||||
type === 'income'
|
||||
? t('coinseller_center.stock_transfer', 'Stock transfer')
|
||||
: counterpartyName ||
|
||||
(counterpartyUID
|
||||
? t(
|
||||
'coinseller_center.user_name_template',
|
||||
'User {id}'
|
||||
).replace('{id}', counterpartyUID)
|
||||
: t('coinseller_center.transfer_out', 'Transfer out'));
|
||||
counterpartyName ||
|
||||
(counterpartyUID
|
||||
? t(
|
||||
'coinseller_center.user_name_template',
|
||||
'User {id}'
|
||||
).replace('{id}', counterpartyUID)
|
||||
: type === 'income'
|
||||
? t('coinseller_center.stock_transfer', 'Stock transfer')
|
||||
: t('coinseller_center.transfer_out', 'Transfer out'));
|
||||
var uid =
|
||||
counterpartyUID ||
|
||||
(type === 'income' ? t('coinseller_center.system', 'System') : '-');
|
||||
var transferAmount = normalizeTransferAmount(item);
|
||||
return {
|
||||
id:
|
||||
firstValue(item, ['transaction_id', 'transactionId']) ||
|
||||
@ -439,14 +506,16 @@
|
||||
type: type,
|
||||
name: name,
|
||||
uid: uid,
|
||||
avatar: counterpartyAvatar || avatarData(
|
||||
name,
|
||||
type === 'income' ? '#e7f7f3' : '#dbc8ff',
|
||||
type === 'income' ? '#31a88f' : '#7d57c7'
|
||||
),
|
||||
avatar:
|
||||
counterpartyAvatar ||
|
||||
avatarData(
|
||||
name,
|
||||
type === 'income' ? '#e7f7f3' : '#dbc8ff',
|
||||
type === 'income' ? '#31a88f' : '#7d57c7'
|
||||
),
|
||||
coins: Math.abs(delta),
|
||||
amount: 0,
|
||||
currency: '',
|
||||
amount: transferAmount,
|
||||
currency: normalizeTransferCurrency(item, transferAmount),
|
||||
time: timeLabelFromMS(
|
||||
firstValue(item, ['created_at_ms', 'createdAtMs'])
|
||||
),
|
||||
@ -485,7 +554,12 @@
|
||||
|
||||
function loadRealData() {
|
||||
if (!hasAPI()) {
|
||||
toast(t('coinseller_center.load_failed', 'Load failed. Try again later.'));
|
||||
toast(
|
||||
t(
|
||||
'coinseller_center.load_failed',
|
||||
'Load failed. Try again later.'
|
||||
)
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
state.loading = true;
|
||||
@ -518,7 +592,10 @@
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (window.console && window.console.warn) {
|
||||
window.console.warn('[coinseller-center] api failed', error);
|
||||
window.console.warn(
|
||||
'[coinseller-center] api failed',
|
||||
error
|
||||
);
|
||||
}
|
||||
toast(
|
||||
t(
|
||||
@ -651,7 +728,8 @@
|
||||
return data.records
|
||||
.filter(function (record) {
|
||||
return (
|
||||
record.type === state.historyTab && recordMatchesQuery(record)
|
||||
record.type === state.historyTab &&
|
||||
recordMatchesQuery(record)
|
||||
);
|
||||
})
|
||||
.slice(0, state.historyLimit);
|
||||
@ -662,7 +740,9 @@
|
||||
var avatar = document.createElement('div');
|
||||
var main = document.createElement('div');
|
||||
var title = document.createElement('div');
|
||||
var metaGroup = document.createElement('div');
|
||||
var meta = document.createElement('div');
|
||||
var transfer = document.createElement('span');
|
||||
var side = document.createElement('div');
|
||||
var amount = document.createElement('strong');
|
||||
var time = document.createElement('span');
|
||||
@ -671,15 +751,21 @@
|
||||
avatar.className = 'record-avatar';
|
||||
main.className = 'record-main';
|
||||
title.className = 'record-title';
|
||||
metaGroup.className = 'record-meta-group';
|
||||
meta.className = 'record-meta';
|
||||
transfer.className = 'record-transfer';
|
||||
side.className =
|
||||
'record-side' + (record.type === 'income' ? ' is-income' : '');
|
||||
|
||||
renderAvatar(avatar, record);
|
||||
title.textContent = record.name || '-';
|
||||
meta.textContent = t('coinseller_center.uid_prefix', 'UID: {id}').replace(
|
||||
'{id}',
|
||||
record.uid || '-'
|
||||
meta.textContent = t(
|
||||
'coinseller_center.uid_prefix',
|
||||
'UID: {id}'
|
||||
).replace('{id}', record.uid || '-');
|
||||
transfer.textContent = formatTransferAmount(
|
||||
record.amount,
|
||||
record.currency
|
||||
);
|
||||
amount.textContent =
|
||||
(record.type === 'income' ? '+' : '-') +
|
||||
@ -689,7 +775,9 @@
|
||||
time.textContent = record.time || '';
|
||||
|
||||
main.appendChild(title);
|
||||
main.appendChild(meta);
|
||||
metaGroup.appendChild(meta);
|
||||
if (transfer.textContent) metaGroup.appendChild(transfer);
|
||||
main.appendChild(metaGroup);
|
||||
side.appendChild(amount);
|
||||
side.appendChild(time);
|
||||
row.appendChild(avatar);
|
||||
@ -709,13 +797,16 @@
|
||||
|
||||
function renderHistory() {
|
||||
document.querySelectorAll('[data-history-tab]').forEach(function (tab) {
|
||||
var active = tab.getAttribute('data-history-tab') === state.historyTab;
|
||||
var active =
|
||||
tab.getAttribute('data-history-tab') === state.historyTab;
|
||||
tab.classList.toggle('is-active', active);
|
||||
tab.setAttribute('aria-selected', String(active));
|
||||
});
|
||||
|
||||
var all = data.records.filter(function (record) {
|
||||
return record.type === state.historyTab && recordMatchesQuery(record);
|
||||
return (
|
||||
record.type === state.historyTab && recordMatchesQuery(record)
|
||||
);
|
||||
});
|
||||
var records = visibleHistoryRecords();
|
||||
$('loadMoreButton').hidden = records.length >= all.length;
|
||||
@ -783,7 +874,10 @@
|
||||
renderRechargeState();
|
||||
setStatus(
|
||||
$('searchStatus'),
|
||||
t('coinseller_center.user_not_found', 'User not found.'),
|
||||
t(
|
||||
'coinseller_center.user_not_found',
|
||||
'User not found.'
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
return;
|
||||
@ -795,7 +889,10 @@
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (window.console && window.console.warn) {
|
||||
window.console.warn('[coinseller-center] user search failed', error);
|
||||
window.console.warn(
|
||||
'[coinseller-center] user search failed',
|
||||
error
|
||||
);
|
||||
}
|
||||
state.target = null;
|
||||
renderTarget();
|
||||
@ -832,12 +929,9 @@
|
||||
function appendTransferRecord(amount, response) {
|
||||
var payload = unwrapData(response) || {};
|
||||
var coins = toNumber(
|
||||
firstValue(payload, [
|
||||
'amount',
|
||||
'coin_amount',
|
||||
'coinAmount',
|
||||
])
|
||||
firstValue(payload, ['amount', 'coin_amount', 'coinAmount'])
|
||||
);
|
||||
var transferAmount = normalizeTransferAmount(payload);
|
||||
data.records.unshift({
|
||||
id:
|
||||
firstValue(payload, ['transaction_id', 'transactionId']) ||
|
||||
@ -847,8 +941,8 @@
|
||||
uid: state.target.uid,
|
||||
avatar: state.target.avatar,
|
||||
coins: coins || amount,
|
||||
amount: 0,
|
||||
currency: '',
|
||||
amount: transferAmount,
|
||||
currency: normalizeTransferCurrency(payload, transferAmount),
|
||||
time: currentTimeLabel(),
|
||||
});
|
||||
}
|
||||
@ -858,7 +952,10 @@
|
||||
if (!state.target) {
|
||||
setStatus(
|
||||
$('rechargeStatus'),
|
||||
t('coinseller_center.select_user_first', 'Select a user first.'),
|
||||
t(
|
||||
'coinseller_center.select_user_first',
|
||||
'Select a user first.'
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
return;
|
||||
@ -877,7 +974,10 @@
|
||||
if (amount > data.balance.coins) {
|
||||
setStatus(
|
||||
$('rechargeStatus'),
|
||||
t('coinseller_center.amount_exceeds_stock', 'Amount exceeds stock.'),
|
||||
t(
|
||||
'coinseller_center.amount_exceeds_stock',
|
||||
'Amount exceeds stock.'
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
return;
|
||||
@ -921,13 +1021,19 @@
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (window.console && window.console.warn) {
|
||||
window.console.warn('[coinseller-center] transfer failed', error);
|
||||
window.console.warn(
|
||||
'[coinseller-center] transfer failed',
|
||||
error
|
||||
);
|
||||
}
|
||||
setStatus($('rechargeStatus'), '', '');
|
||||
toast(
|
||||
error && error.message
|
||||
? error.message
|
||||
: t('coinseller_center.transfer_failed', 'Transfer failed.')
|
||||
: t(
|
||||
'coinseller_center.transfer_failed',
|
||||
'Transfer failed.'
|
||||
)
|
||||
);
|
||||
})
|
||||
.finally(function () {
|
||||
@ -1006,11 +1112,13 @@
|
||||
$('helpButton').addEventListener('click', function () {
|
||||
openModal('helpModal');
|
||||
});
|
||||
document.querySelectorAll('[data-close-modal]').forEach(function (node) {
|
||||
node.addEventListener('click', function () {
|
||||
closeModal(node.getAttribute('data-close-modal'));
|
||||
document
|
||||
.querySelectorAll('[data-close-modal]')
|
||||
.forEach(function (node) {
|
||||
node.addEventListener('click', function () {
|
||||
closeModal(node.getAttribute('data-close-modal'));
|
||||
});
|
||||
});
|
||||
});
|
||||
$('searchForm').addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
var value = $('userSearchInput').value.trim();
|
||||
|
||||
@ -405,9 +405,18 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.record-meta {
|
||||
.record-meta-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 4px 8px;
|
||||
margin-top: 5px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.record-meta {
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
@ -416,6 +425,15 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.record-transfer {
|
||||
flex: 0 0 auto;
|
||||
color: var(--primary-deep);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.record-side {
|
||||
display: grid;
|
||||
justify-items: end;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user