lalu store
This commit is contained in:
parent
0c5d01072d
commit
527484d3d8
@ -232,7 +232,11 @@
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
background:
|
||||
linear-gradient(145deg, rgba(255, 255, 255, 0.14), transparent),
|
||||
linear-gradient(
|
||||
145deg,
|
||||
rgba(255, 255, 255, 0.14),
|
||||
transparent
|
||||
),
|
||||
#1a1822;
|
||||
box-shadow:
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.08),
|
||||
@ -448,10 +452,7 @@
|
||||
<p class="brand-name" id="hostName">Lalu</p>
|
||||
</div>
|
||||
|
||||
<p
|
||||
class="message"
|
||||
data-i18n="lalu_landing.message"
|
||||
>
|
||||
<p class="message" data-i18n="lalu_landing.message">
|
||||
送你一份礼物,快来和我一起玩吧!
|
||||
</p>
|
||||
|
||||
@ -511,9 +512,7 @@
|
||||
<img src="assets/lalu-logo.png" alt="Lalu" />
|
||||
<div class="app-copy">
|
||||
<strong>Lalu</strong>
|
||||
<span data-i18n="lalu_landing.tagline">
|
||||
结识新朋友
|
||||
</span>
|
||||
<span data-i18n="lalu_landing.tagline"> 结识新朋友 </span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
@ -556,7 +555,11 @@
|
||||
}
|
||||
|
||||
function resolveDownloadURL() {
|
||||
var commonURL = firstParam(['downloadUrl', 'download_url', 'url']);
|
||||
var commonURL = firstParam([
|
||||
'downloadUrl',
|
||||
'download_url',
|
||||
'url',
|
||||
]);
|
||||
var iosURL = firstParam(['iosUrl', 'ios_url']);
|
||||
var androidURL =
|
||||
firstParam(['androidUrl', 'android_url']) ||
|
||||
|
||||
@ -9,7 +9,10 @@
|
||||
<title>BD Center</title>
|
||||
<link rel="stylesheet" href="../../common/theme.css" />
|
||||
<link rel="stylesheet" href="../common/center.css" />
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="./style.css?v=20260604-bd-center-real-skeleton"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -292,6 +295,6 @@
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/i18n.js"></script>
|
||||
<script src="../../common/api.js?v=20260604-bd-center"></script>
|
||||
<script src="./script.js?v=20260604-bd-center-api"></script>
|
||||
<script src="./script.js?v=20260604-bd-center-real-skeleton"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,85 +1,30 @@
|
||||
(function () {
|
||||
var FIRST_BILL_MONTH = '2026-06';
|
||||
var BD_SALARY_ASSET = 'BD_SALARY_USD';
|
||||
var query = new URLSearchParams(window.location.search);
|
||||
var mock = {
|
||||
profile: {
|
||||
name: 'BD_Jasmine',
|
||||
uid: 'BD-163008',
|
||||
avatar: avatarData('B', '#dbc8ff', '#7d57c7'),
|
||||
},
|
||||
balance: {
|
||||
available: 48620.8,
|
||||
},
|
||||
billMonth: currentMonth(),
|
||||
agencyBill: {
|
||||
billTitle: '2026.06',
|
||||
agencyNumber: 12,
|
||||
totalSalary: 128450.35,
|
||||
totalRecharge: 356900.0,
|
||||
memberBillList: [
|
||||
{
|
||||
name: 'Yumi Star Agency',
|
||||
account: '163003',
|
||||
avatar: avatarData('Y', '#dbc8ff', '#7d57c7'),
|
||||
teamSalaryAmount: 38420.55,
|
||||
teamRechargeAmount: 126880,
|
||||
teamMemberCount: 28,
|
||||
},
|
||||
{
|
||||
name: 'Moon Live Agency',
|
||||
account: '163086',
|
||||
avatar: avatarData('M', '#f4ebff', '#7d57c7'),
|
||||
teamSalaryAmount: 29106.2,
|
||||
teamRechargeAmount: 98540,
|
||||
teamMemberCount: 19,
|
||||
},
|
||||
{
|
||||
name: 'Nova Host Guild',
|
||||
account: '163221',
|
||||
avatar: avatarData('N', '#dbc8ff', '#7d57c7'),
|
||||
teamSalaryAmount: 22450,
|
||||
teamRechargeAmount: 73150,
|
||||
teamMemberCount: 16,
|
||||
},
|
||||
],
|
||||
},
|
||||
inviteRecords: [],
|
||||
searchPool: [
|
||||
{
|
||||
userId: '3187099',
|
||||
id: '3187099',
|
||||
name: 'Agent_River',
|
||||
account: '168899',
|
||||
avatar: avatarData('R', '#dbc8ff', '#7d57c7'),
|
||||
},
|
||||
{
|
||||
userId: '3187100',
|
||||
id: '3187100',
|
||||
name: 'Agent_Sara',
|
||||
account: '168900',
|
||||
avatar: avatarData('S', '#f4ebff', '#7d57c7'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
var data = {
|
||||
profile: mock.profile,
|
||||
balance: mock.balance,
|
||||
billMonth: mock.billMonth,
|
||||
agencyBill: mock.agencyBill,
|
||||
inviteRecords: mock.inviteRecords,
|
||||
profile: null,
|
||||
balance: { available: 0 },
|
||||
billMonth: currentMonth(),
|
||||
agencyBill: {
|
||||
agencyNumber: 0,
|
||||
totalSalary: 0,
|
||||
totalRecharge: 0,
|
||||
memberBillList: [],
|
||||
},
|
||||
inviteRecords: [],
|
||||
};
|
||||
|
||||
var state = {
|
||||
billMonth: normalizeBillMonth(mock.billMonth),
|
||||
billMonth: normalizeBillMonth(data.billMonth),
|
||||
inviteQuery: '',
|
||||
inviteMode: 'records',
|
||||
inviteStatus: '',
|
||||
inviteStatusType: '',
|
||||
searched: [],
|
||||
inviting: {},
|
||||
isMock: query.get('mock') === '1',
|
||||
searching: false,
|
||||
loading: true,
|
||||
};
|
||||
|
||||
function $(id) {
|
||||
@ -256,6 +201,16 @@
|
||||
});
|
||||
}
|
||||
|
||||
function setSkeleton(element, loading, text) {
|
||||
if (!element) return;
|
||||
element.classList.toggle('skeleton-line', Boolean(loading));
|
||||
if (loading) {
|
||||
element.textContent = '';
|
||||
return;
|
||||
}
|
||||
element.textContent = text || '';
|
||||
}
|
||||
|
||||
function renderImageAvatar(container, src, name, fallbackClass) {
|
||||
container.textContent = '';
|
||||
if (!src) {
|
||||
@ -355,9 +310,22 @@
|
||||
function renderProfile() {
|
||||
var image = $('profileAvatar');
|
||||
var fallback = $('profileAvatarFallback');
|
||||
var profile = data.profile || mock.profile;
|
||||
$('profileName').textContent = profile.name || '-';
|
||||
$('profileUID').textContent = 'UID: ' + (profile.uid || '-');
|
||||
var profile = data.profile || {};
|
||||
var loading = Boolean(state.loading);
|
||||
setSkeleton($('profileName'), loading, profile.name || '-');
|
||||
setSkeleton(
|
||||
$('profileUID'),
|
||||
loading,
|
||||
'UID: ' + (profile.uid || '-')
|
||||
);
|
||||
fallback.classList.toggle('avatar-skeleton', loading);
|
||||
if (loading) {
|
||||
image.hidden = true;
|
||||
image.removeAttribute('src');
|
||||
fallback.hidden = false;
|
||||
fallback.textContent = '';
|
||||
return;
|
||||
}
|
||||
fallback.textContent = initial(profile.name) || 'B';
|
||||
image.onload = function () {
|
||||
image.hidden = false;
|
||||
@ -375,7 +343,14 @@
|
||||
}
|
||||
|
||||
function renderBalance() {
|
||||
$('availableBalance').textContent = money(data.balance && data.balance.available);
|
||||
var loading = Boolean(state.loading);
|
||||
var coinIcon = document.querySelector('.salary-value .coin-icon');
|
||||
if (coinIcon) coinIcon.classList.toggle('skeleton-coin', loading);
|
||||
setSkeleton(
|
||||
$('availableBalance'),
|
||||
loading,
|
||||
money(data.balance && data.balance.available)
|
||||
);
|
||||
}
|
||||
|
||||
function summaryCell(label, value) {
|
||||
@ -389,6 +364,43 @@
|
||||
return cell;
|
||||
}
|
||||
|
||||
function summarySkeletonCell() {
|
||||
var cell = document.createElement('div');
|
||||
var labelNode = document.createElement('span');
|
||||
var valueNode = document.createElement('strong');
|
||||
labelNode.className = 'skeleton-line';
|
||||
valueNode.className = 'skeleton-line';
|
||||
cell.appendChild(labelNode);
|
||||
cell.appendChild(valueNode);
|
||||
return cell;
|
||||
}
|
||||
|
||||
function skeletonMemberRow() {
|
||||
var row = document.createElement('article');
|
||||
var avatar = document.createElement('div');
|
||||
var main = document.createElement('div');
|
||||
var name = document.createElement('div');
|
||||
var meta = document.createElement('div');
|
||||
var side = document.createElement('div');
|
||||
row.className = 'member-row is-skeleton';
|
||||
avatar.className = 'member-avatar avatar-skeleton';
|
||||
main.className = 'member-main';
|
||||
name.className = 'member-name skeleton-line';
|
||||
meta.className = 'member-meta skeleton-line';
|
||||
side.className = 'member-side';
|
||||
for (var i = 0; i < 3; i += 1) {
|
||||
var line = document.createElement('div');
|
||||
line.className = 'skeleton-line';
|
||||
side.appendChild(line);
|
||||
}
|
||||
main.appendChild(name);
|
||||
main.appendChild(meta);
|
||||
row.appendChild(avatar);
|
||||
row.appendChild(main);
|
||||
row.appendChild(side);
|
||||
return row;
|
||||
}
|
||||
|
||||
function memberRow(item) {
|
||||
var row = document.createElement('article');
|
||||
var avatar = document.createElement('div');
|
||||
@ -427,10 +439,23 @@
|
||||
}
|
||||
|
||||
function renderTeamList() {
|
||||
var bill = data.agencyBill || mock.agencyBill;
|
||||
var bill = data.agencyBill;
|
||||
$('billMonthText').textContent = monthLabel(state.billMonth);
|
||||
$('billRange').textContent = state.billMonth.replace('-', '.');
|
||||
|
||||
if (state.loading) {
|
||||
replaceChildren($('teamListSummary'), [
|
||||
summarySkeletonCell(),
|
||||
summarySkeletonCell(),
|
||||
]);
|
||||
replaceChildren($('teamListContent'), [
|
||||
skeletonMemberRow(),
|
||||
skeletonMemberRow(),
|
||||
skeletonMemberRow(),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
replaceChildren($('teamListSummary'), [
|
||||
summaryCell(
|
||||
t('bd_center.agency_number', 'Agency number'),
|
||||
@ -502,9 +527,6 @@
|
||||
state.billMonth = nextMonth;
|
||||
closeMonthSheet();
|
||||
renderTeamList();
|
||||
if (state.isMock) {
|
||||
toast(t('bd_center.mock_bill_loaded', 'Mock bill loaded.'));
|
||||
}
|
||||
}
|
||||
|
||||
function inviteProfile(item) {
|
||||
@ -599,7 +621,8 @@
|
||||
replaceChildren($('inviteList'), rows);
|
||||
$('inviteEmpty').hidden =
|
||||
rows.length > 0 || Boolean(state.inviteStatus);
|
||||
$('inviteSearchButton').disabled = !state.inviteQuery.trim();
|
||||
$('inviteSearchButton').disabled =
|
||||
!state.inviteQuery.trim() || Boolean(state.searching);
|
||||
}
|
||||
|
||||
function openInviteModal() {
|
||||
@ -608,6 +631,7 @@
|
||||
state.searched = [];
|
||||
state.inviteStatus = '';
|
||||
state.inviteStatusType = '';
|
||||
state.searching = false;
|
||||
$('inviteSearchInput').value = '';
|
||||
$('inviteModal').hidden = false;
|
||||
$('inviteModal').setAttribute('aria-hidden', 'false');
|
||||
@ -624,17 +648,6 @@
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
|
||||
function searchMockInvite(queryValue) {
|
||||
var queryLower = queryValue.toLowerCase();
|
||||
return mock.searchPool.filter(function (profile) {
|
||||
return (
|
||||
profile.name.toLowerCase().indexOf(queryLower) >= 0 ||
|
||||
profile.account.indexOf(queryLower) >= 0 ||
|
||||
profile.id.indexOf(queryLower) >= 0
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function searchInvite(event) {
|
||||
event.preventDefault();
|
||||
var queryValue = state.inviteQuery.trim();
|
||||
@ -646,17 +659,6 @@
|
||||
renderInviteModal();
|
||||
return;
|
||||
}
|
||||
if (state.isMock) {
|
||||
state.searched = searchMockInvite(queryValue);
|
||||
if (!state.searched.length) {
|
||||
state.inviteStatus = t(
|
||||
'bd_center.no_users_found',
|
||||
'No users found'
|
||||
);
|
||||
}
|
||||
renderInviteModal();
|
||||
return;
|
||||
}
|
||||
if (!api().user || !api().user.resolveDisplayUserID) {
|
||||
state.inviteStatus = t(
|
||||
'bd_center.api_not_ready',
|
||||
@ -667,6 +669,7 @@
|
||||
return;
|
||||
}
|
||||
state.inviteStatus = t('bd_center.searching', 'Searching...');
|
||||
state.searching = true;
|
||||
renderInviteModal();
|
||||
api()
|
||||
.user.resolveDisplayUserID(queryValue)
|
||||
@ -686,25 +689,16 @@
|
||||
state.inviteStatusType = 'error';
|
||||
state.searched = [];
|
||||
renderInviteModal();
|
||||
})
|
||||
.finally(function () {
|
||||
state.searching = false;
|
||||
renderInviteModal();
|
||||
});
|
||||
}
|
||||
|
||||
function submitInvite(profile) {
|
||||
var targetUserID = String(profile.userId || profile.id || '');
|
||||
if (!targetUserID) return;
|
||||
if (state.isMock) {
|
||||
data.inviteRecords.unshift({
|
||||
id: 'inv-' + Date.now(),
|
||||
status: 'success',
|
||||
profile: profile,
|
||||
});
|
||||
state.inviteMode = 'records';
|
||||
state.searched = [];
|
||||
state.inviteStatus = t('bd_center.agency_added', 'Agency added.');
|
||||
state.inviteStatusType = 'success';
|
||||
renderInviteModal();
|
||||
return;
|
||||
}
|
||||
if (!centerAPI() || !centerAPI().inviteAgency) {
|
||||
state.inviteStatus = t(
|
||||
'bd_center.api_not_ready',
|
||||
@ -758,17 +752,44 @@
|
||||
'../withdraw-exchange/index.html?' + params.toString();
|
||||
}
|
||||
|
||||
function setLoading(loading) {
|
||||
state.loading = Boolean(loading);
|
||||
render();
|
||||
}
|
||||
|
||||
function loadRealData() {
|
||||
var service = centerAPI();
|
||||
if (state.isMock || !service) return Promise.resolve(false);
|
||||
setLoading(true);
|
||||
if (
|
||||
!service ||
|
||||
!service.overview ||
|
||||
!service.agencies ||
|
||||
!service.inviteAgency
|
||||
) {
|
||||
setLoading(false);
|
||||
return Promise.reject(
|
||||
new Error(t('bd_center.api_not_ready', 'API module is not ready.'))
|
||||
);
|
||||
}
|
||||
return Promise.all([
|
||||
service.overview(),
|
||||
service.agencies(50),
|
||||
]).then(function (results) {
|
||||
applyOverview(results[0] || {});
|
||||
applyAgencies(results[1] || {});
|
||||
render();
|
||||
return true;
|
||||
}).catch(function (error) {
|
||||
data.profile = null;
|
||||
data.balance = { available: 0 };
|
||||
data.agencyBill = {
|
||||
agencyNumber: 0,
|
||||
totalSalary: 0,
|
||||
totalRecharge: 0,
|
||||
memberBillList: [],
|
||||
};
|
||||
throw error;
|
||||
}).finally(function () {
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -827,7 +848,6 @@
|
||||
if (window.HyAppBridge) {
|
||||
window.HyAppBridge.ready({
|
||||
page: 'bd-center',
|
||||
mock: state.isMock,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -70,6 +70,12 @@
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.bd-center .salary-value strong.skeleton-line {
|
||||
width: 180px;
|
||||
height: 42px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.team-stats-card,
|
||||
.team-users-card {
|
||||
display: grid;
|
||||
@ -180,6 +186,18 @@
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.team-list-summary span.skeleton-line {
|
||||
width: 96px;
|
||||
height: 13px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
.team-list-summary strong.skeleton-line {
|
||||
width: 112px;
|
||||
height: 19px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.team-list-content {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
@ -265,6 +283,33 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.member-row.is-skeleton {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.member-row.is-skeleton .member-avatar {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.member-row.is-skeleton .member-name.skeleton-line {
|
||||
width: min(132px, 100%);
|
||||
height: 18px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
.member-row.is-skeleton .member-meta.skeleton-line {
|
||||
width: 92px;
|
||||
height: 14px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
.member-row.is-skeleton .member-side .skeleton-line {
|
||||
width: 122px;
|
||||
max-width: 28vw;
|
||||
height: 13px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.empty-state,
|
||||
.invite-empty {
|
||||
display: flex;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user