(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); })();