2026-07-17 11:54:43 +08:00

398 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function () {
var ui = window.FamiCenterUI;
var fallbackAvatar =
'../../products/fami/centers/assets/fami/bd-avatar.png';
var dates = [];
var contactController = null;
var state = {
profile: null,
owner: null,
agencies: [],
dailyAgencies: {},
dailyRequestSequence: 0,
inviteProfile: null,
inviting: false,
};
var mockItems = Array.from({ length: 5 }, function (_, index) {
return {
agency: {
agency_id: 'agency-' + index,
name: 'agency ' + (index + 1),
avatar: fallbackAvatar,
},
owner: {
user_id: 'owner-' + index,
display_user_id: '12345' + (index + 10),
username: 'agency ' + (index + 1),
avatar: fallbackAvatar,
},
diamond_earnings: 123214,
};
});
var mock = {
user: {
user_id: 'bd-123456789',
display_user_id: '123456789',
username: 'konghuimingc',
avatar: fallbackAvatar,
contact_info: '+65 1234 5678',
},
overview: {
profile: {
user_id: 'bd-123456789',
display_user_id: '123456789',
username: 'konghuimingc',
avatar: fallbackAvatar,
},
},
stats: { items: mockItems },
};
function normalizeAgency(item) {
item = item || {};
var agency = item.agency || {};
var owner = item.owner || {};
return {
id: String(agency.agency_id || ''),
displayId: String(owner.display_user_id || ''),
name: String(owner.username || agency.name || 'Agency'),
avatar: String(owner.avatar || agency.avatar || ''),
diamondEarnings: ui.number(item.diamond_earnings),
};
}
function applyStats(payload, date) {
var data = ui.unwrap(payload) || {};
var items = Array.isArray(data.items)
? data.items.map(normalizeAgency)
: [];
state.agencies = items;
if (date) state.dailyAgencies[date] = items;
}
function agencyValue(agency, index) {
var date = dates[index] && dates[index].value;
var daily = state.dailyAgencies[date] || [];
var item = daily.find(function (candidate) {
return candidate.id === agency.id;
});
return item ? item.diamondEarnings : 0;
}
function renderProfile() {
var profile = state.profile || {};
var owner = state.owner || profile;
ui.setAvatar(ui.$('profileAvatar'), profile.avatar, fallbackAvatar);
ui.$('profileName').textContent = profile.name || '-';
ui.$('profileUserId').textContent = ui
.t('fami.user_id', 'User ID:{id}')
.replace('{id}', profile.displayId || '-');
ui.$('contactName').textContent = owner.name || profile.name || '-';
ui.$('contactUserId').textContent = ui
.t('fami.user_id', 'User ID:{id}')
.replace('{id}', owner.displayId || profile.displayId || '-');
if (contactController)
contactController.setContact(owner.contact || '');
}
function renderTable() {
dates = ui.dateWindow(9);
var grid = document.createElement('div');
grid.className = 'bd-agency-table__grid';
var header = document.createElement('div');
header.className = 'bd-agency-table__header';
dates.forEach(function (date) {
var head = document.createElement('span');
head.className = 'bd-agency-table__head';
head.textContent = ui.isMock()
? ui.t('fami.today', 'Today')
: date.label;
head.setAttribute('aria-label', date.label + ' ' + date.value);
header.appendChild(head);
});
var rows = document.createElement('div');
rows.className = 'bd-agency-table__rows';
state.agencies.forEach(function (agency) {
var avatar = document.createElement('img');
avatar.className = 'bd-agency-table__avatar';
avatar.alt = '';
ui.setAvatar(avatar, agency.avatar, fallbackAvatar);
rows.appendChild(avatar);
dates.slice(0, 8).forEach(function (_, index) {
var value = document.createElement('span');
value.className = 'bd-agency-table__value';
value.textContent = ui
.formatNumber(agencyValue(agency, index))
.replace(/,/g, '');
rows.appendChild(value);
});
});
grid.appendChild(header);
grid.appendChild(rows);
ui.$('agencyTable').replaceChildren(grid);
}
function render() {
renderProfile();
renderTable();
}
function applyPayloads(userPayload, overviewPayload, statsPayload) {
var overview = ui.unwrap(overviewPayload) || {};
state.profile = ui.profileFrom(overview.profile || overview, 'BD');
state.owner = ui.profileFrom(userPayload, state.profile.name);
applyStats(statsPayload, dates[0] && dates[0].value);
render();
}
function loadDailyMatrix() {
if (ui.isMock()) {
dates.slice(0, 8).forEach(function (date) {
state.dailyAgencies[date.value] =
mockItems.map(normalizeAgency);
});
renderTable();
return;
}
var api = window.HyAppAPI && window.HyAppAPI.bdCenter;
if (!api || !api.stats) return;
var sequence = ++state.dailyRequestSequence;
// 每列独立读取对应 UTC 日,单日失败只留空该列;复制聚合值会把真实团队收益错误归到其他日期。
Promise.all(
dates.slice(0, 8).map(function (date) {
return ui.safe('bd-stats-' + date.value, function () {
return api.stats({
start_date: date.value,
end_date: date.value,
});
});
})
).then(function (payloads) {
if (sequence !== state.dailyRequestSequence) return;
payloads.forEach(function (payload, index) {
var day = dates[index] && dates[index].value;
var data = ui.unwrap(payload) || {};
state.dailyAgencies[day] = Array.isArray(data.items)
? data.items.map(normalizeAgency)
: [];
});
renderTable();
});
}
function load() {
dates = ui.dateWindow(9);
if (ui.isMock()) {
applyPayloads(mock.user, mock.overview, mock.stats);
loadDailyMatrix();
return;
}
var api = window.HyAppAPI;
if (!api || !api.bdCenter || !api.bdCenter.stats) {
render();
ui.toast(
ui.t('bd_center.api_not_ready', 'API module is not ready.')
);
return;
}
// BD 资料和团队收益属于不同 owner初始只取今天建立行集合随后并行补齐八日矩阵避免用 agency 列表里的 host_count/工资字段冒充收益。
Promise.all([
ui.safe('bd-owner', function () {
return api.user.me();
}),
ui.safe('bd-overview', function () {
return api.bdCenter.overview();
}),
ui.safe('bd-stats', function () {
return api.bdCenter.stats({
start_date: dates[0].value,
end_date: dates[0].value,
});
}),
]).then(function (results) {
applyPayloads(results[0], results[1], results[2]);
loadDailyMatrix();
if (!results.some(Boolean)) {
ui.toast(
ui.t(
'bd_center.load_failed',
'Load failed. Try again later.'
)
);
}
});
}
function setInviteStatus(message, success) {
var node = ui.$('inviteStatus');
node.textContent = message || '';
node.hidden = !message;
node.classList.toggle('is-success', !!success);
}
function renderInviteResult() {
var root = ui.$('inviteResult');
root.replaceChildren();
if (!state.inviteProfile) return;
var row = document.createElement('div');
row.className = 'fami-search-result';
var avatar = document.createElement('img');
avatar.alt = '';
ui.setAvatar(avatar, state.inviteProfile.avatar, fallbackAvatar);
var copy = document.createElement('div');
copy.className = 'fami-search-result__copy';
var name = document.createElement('strong');
name.textContent = state.inviteProfile.name || 'Agency';
var id = document.createElement('span');
id.textContent = 'ID: ' + state.inviteProfile.displayId;
var action = document.createElement('button');
action.className = 'fami-search-result__action';
action.type = 'button';
action.disabled = state.inviting;
action.textContent = state.inviting
? ui.t('bd_center.pending', 'Pending')
: ui.t('bd_center.invite', 'Invite');
action.addEventListener('click', inviteAgency);
copy.appendChild(name);
copy.appendChild(id);
row.appendChild(avatar);
row.appendChild(copy);
row.appendChild(action);
root.appendChild(row);
}
function searchInvite(event) {
event.preventDefault();
var value = String(ui.$('inviteSearchInput').value || '').trim();
state.inviteProfile = null;
renderInviteResult();
if (!value) return;
if (ui.isMock()) {
state.inviteProfile = ui.profileFrom(mock.user, 'Agency');
state.inviteProfile.id = 'mock-agency-' + value;
state.inviteProfile.displayId = value;
renderInviteResult();
return;
}
var api = window.HyAppAPI && window.HyAppAPI.user;
if (!api || !api.resolveDisplayUserID) {
setInviteStatus(
ui.t('bd_center.api_not_ready', 'API module is not ready.')
);
return;
}
ui.$('inviteSearchButton').disabled = true;
setInviteStatus(ui.t('bd_center.searching', 'Searching...'));
api.resolveDisplayUserID(value)
.then(function (payload) {
state.inviteProfile = ui.profileFrom(payload, 'Agency');
if (!state.inviteProfile.id) state.inviteProfile = null;
if (state.inviteProfile && !state.inviteProfile.displayId) {
state.inviteProfile.displayId = value;
}
setInviteStatus(
state.inviteProfile
? ''
: ui.t('bd_center.no_users_found', 'No users found')
);
renderInviteResult();
})
.catch(function (error) {
setInviteStatus(
(error && error.message) ||
ui.t(
'bd_center.search_failed',
'Search failed. Try again later.'
)
);
})
.finally(function () {
ui.$('inviteSearchButton').disabled = false;
});
}
function inviteAgency() {
if (!state.inviteProfile || state.inviting) return;
if (ui.isMock()) {
setInviteStatus(
ui.t('bd_center.invitation_submitted', 'Invitation submitted'),
true
);
return;
}
var api = window.HyAppAPI && window.HyAppAPI.bdCenter;
if (!api || !api.inviteAgency) return;
state.inviting = true;
renderInviteResult();
// 创建公会邀请会触发角色与归属流转command_id 保证重试幂等,后端确认前不本地伪造公会记录。
api.inviteAgency({
command_id: ui.commandId('bd-agency'),
target_user_id: state.inviteProfile.id,
agency_name: state.inviteProfile.name,
})
.then(function () {
setInviteStatus(
ui.t(
'bd_center.invitation_submitted',
'Invitation submitted'
),
true
);
state.inviteProfile = null;
renderInviteResult();
})
.catch(function (error) {
setInviteStatus(
(error && error.message) ||
ui.t(
'bd_center.invite_failed',
'Invite failed. Try again later.'
)
);
})
.finally(function () {
state.inviting = false;
renderInviteResult();
});
}
function openInvite() {
state.inviteProfile = null;
ui.$('inviteSearchInput').value = '';
setInviteStatus('');
renderInviteResult();
ui.openModal('inviteModal');
}
function init() {
contactController = ui.bindContact();
ui.$('backButton').addEventListener('click', function () {
ui.goBack();
});
ui.$('addGuildButton').addEventListener('click', openInvite);
ui.$('inviteSearchForm').addEventListener('submit', searchInvite);
document
.querySelectorAll('[data-invite-close]')
.forEach(function (node) {
node.addEventListener('click', function () {
ui.closeModal('inviteModal');
});
});
window.addEventListener('hyapp:i18n-ready', render);
render();
load();
if (window.HyAppBridge) {
window.HyAppBridge.ready({
page: 'bd-center',
app_code: 'fami',
mock: ui.isMock(),
});
}
}
document.addEventListener('DOMContentLoaded', init);
})();