const API_BASE_URL = "https://jvapi.haiyihy.com"; let headers = { authorization: "Bearer undefined", "req-app-intel": "version=1.0.0;build=1;model=SM-G9550;sysVersion=9;channel=Google", "req-client": "Android", "req-imei": "8fa54d728ab449e04f9292329ed44bda", "req-lang": "id-ID", "req-sys-origin": "origin=ATYOU;originChild=ATYOU", "req-version": "V2", "req-zone": "Asia/Shanghai" }; const cfg = window.PAGE_CONFIG || {}; const $ = (selector, root = document) => root.querySelector(selector); const money = (v) => { const n = Number(v || 0); return Number.isFinite(n) ? n.toFixed(2).replace(/\.00$/, "") : String(v || 0); }; function lang() { const value = new URLSearchParams(location.search).get("lang") || navigator.language || "en"; if (value.startsWith("ar")) return "AR"; if (value.startsWith("tr")) return "TR"; if (value.startsWith("bn")) return "BN"; return "EN"; } function splitPairs(value) { const result = {}; String(value || "").split(";").forEach((item) => { const index = item.indexOf("="); if (index > -1) result[item.slice(0, index)] = item.slice(index + 1); }); return result; } function setAppHeaders(raw) { if (!raw) return; const data = typeof raw === "string" ? JSON.parse(raw) : raw; const appIntel = splitPairs(data["Req-App-Intel"]); const sysOrigin = splitPairs(data["Req-Sys-Origin"]); headers = { ...headers, authorization: data.Authorization || headers.authorization, "req-lang": data["Req-Lang"] || headers["req-lang"], "req-app-intel": [`version=${appIntel.version || "1.0.0"}`, `build=${appIntel.build || "1"}`, `channel=${appIntel.channel || "Web"}`].join(";"), "req-imei": appIntel["Req-Imei"] || headers["req-imei"], "req-sys-origin": [`origin=${sysOrigin.origin || "LIKEI"}`, `child=${sysOrigin.child || "LIKEI"}`].join(";") }; } async function connectApp() { if (!(window.app || window.webkit || window.FlutterPageControl)) { headers["req-lang"] = lang().toLowerCase(); return; } const raw = await new Promise((resolve) => { window.renderData = resolve; window.getIosAccessOriginParam = resolve; let attempt = 0; const poll = () => { attempt += 1; if (window.app && typeof window.app.getAccessOrigin === "function") return resolve(window.app.getAccessOrigin()); if (attempt < 50) return setTimeout(poll, 100); if (window.FlutterApp && typeof window.FlutterApp.postMessage === "function") window.FlutterApp.postMessage("requestAccessOrigin"); resolve(null); }; poll(); }); if (raw) setAppHeaders(raw); } async function request(method, path, body) { const response = await fetch(`${API_BASE_URL}${path}`, { method, headers: { ...headers, "content-type": "application/json" }, body: body === undefined ? undefined : JSON.stringify(body) }); const data = await response.json().catch(() => ({})); if (!response.ok || data.status === false) { const error = new Error(data.errorMsg || data.message || `HTTP ${response.status}`); error.response = data; throw error; } return data; } const get = (path) => request("GET", path); const post = (path, body) => request("POST", path, body); function getTeamId() { const keys = ["teamId", "TEAM_ID", "team_id"]; for (const key of keys) { const value = localStorage.getItem(key); if (value) return value.replace(/^"|"$/g, ""); } for (const key of ["teamInfo", "userInfo", "identity"]) { try { const item = JSON.parse(localStorage.getItem(key) || "{}"); if (item.teamId || item.id) return item.teamId || item.id; } catch {} } return ""; } function getIdentity() { try { const value = JSON.parse(localStorage.getItem("identity") || "{}"); return value.identity || value.role || "BD"; } catch { return "BD"; } } function toast(message) { const node = $("#toast"); node.textContent = message || "Request failed"; node.hidden = false; clearTimeout(toast.timer); toast.timer = setTimeout(() => (node.hidden = true), 2500); } function setLoading(text = "Loading...") { $("#app").innerHTML = `
${text}
`; } function row({ avatar, title, sub, side, tag, onClick }) { const node = document.createElement("button"); node.type = "button"; node.className = "row"; node.innerHTML = `${avatar !== undefined ? `` : ""}
${tag ? `` : ""}`; $(".title", node).textContent = title || "-"; $(".sub", node).textContent = sub || ""; $(".side", node).textContent = side || ""; if (tag) $(".tag", node).textContent = tag; if (onClick) node.addEventListener("click", onClick); return node; } function metrics(items) { return `
${items.map((item) => `
${item.label}
${item.value}
`).join("")}
`; } function showModal(title, content, center = false) { const mask = $("#modalMask"); mask.innerHTML = ``; $(".modal-title", mask).textContent = title || ""; $(".modal-body", mask).append(content); mask.classList.add("show"); } function closeModal() { $("#modalMask").classList.remove("show"); } function navigate(route) { const url = new URL(route, location.origin); const langParam = new URLSearchParams(location.search).get("lang"); if (langParam && !url.searchParams.has("lang")) url.searchParams.set("lang", langParam); location.href = `${url.pathname}${url.search}${url.hash}`; } function renderShell() { document.title = cfg.title || "Yumi H5"; document.body.innerHTML = `

${cfg.title || "Yumi H5"}

`; $("[data-back]").addEventListener("click", () => history.length > 1 ? history.back() : window.app?.closePage?.()); $("#modalMask").addEventListener("click", (event) => { if (event.target.id === "modalMask") closeModal(); }); } async function renderTeamHistory() { setLoading(); const [listRes, historyRes] = await Promise.allSettled([get(cfg.listEndpoint), get(cfg.historyEndpoint)]); const bill = listRes.value?.body || {}; const history = historyRes.value?.body || {}; $("#app").innerHTML = ` ${metrics([ { label: cfg.countLabel, value: bill.memberCount || 0 }, { label: cfg.totalLabel, value: `$${money(bill.totalSalary || bill.teamSalary || bill.totalRecharge || 0)}` } ])}
${bill.billTitle || cfg.title}
${cfg.totalLabel}: $${money(bill.totalSalary || 0)}
`; const list = $("#list"); (bill.memberBillList || []).forEach((item) => { list.appendChild(row({ avatar: item.agentAvatar || item.userAvatar, title: item.agentName || item.userName, sub: `ID: ${item.agentAccount || item.account || "-"}`, side: `${cfg.memberSide1}: $${money(item.teamSalaryAmount || item.salary || 0)}\n${cfg.memberSide2}: ${item.teamMemberCount || item.hostCount || item.agencyCount || 0}` })); }); if (!list.children.length) list.innerHTML = `
No data
`; $("#historyBtn").addEventListener("click", () => { const body = document.createElement("div"); body.innerHTML = metrics([ { label: "Total income", value: `$${money(history.totalIncome || 0)}` }, { label: "Previous period", value: `$${money(history.previousPeriodIncome || 0)}` } ]); const wrap = document.createElement("div"); wrap.className = "card"; (history.incomeDetails || []).forEach((item) => { wrap.appendChild(row({ title: item.billTitle || item.settlementPeriod, sub: `${cfg.countLabel}: ${item.agencyNumber || item.bdNumber || item.memberCount || 0}`, side: `$${money(item.teamSalaryAmount || item.teamTotalIncome || item.settlementSalary || 0)}`, tag: item.statusText || item.status, onClick: async () => { if (!cfg.moreEndpoint || !item.billBelong) return; try { const more = await get(`${cfg.moreEndpoint}${item.billBelong}`); const detail = document.createElement("div"); const card = document.createElement("div"); card.className = "card"; (more.body?.memberDetails || more.body?.members || []).forEach((member) => { card.appendChild(row({ avatar: member.userAvatar || member.bdUserAvatar || member.avatar, title: member.userName || member.bdUserName || member.account, sub: `ID: ${member.account || "-"}`, side: `$${money(member.salary || member.income || 0)}` })); }); detail.appendChild(card); showModal(more.body?.period || item.billTitle, detail); } catch (error) { toast(error.message); } } })); }); if (!wrap.children.length) wrap.innerHTML = `
No data
`; body.appendChild(wrap); showModal("History", body); }); } async function renderAdminTeam() { setLoading(); const res = await post("/bd/team/overview", { type: cfg.teamType }); const data = res.body || {}; $("#app").innerHTML = ` ${metrics([ { label: "Total income", value: `$${money(data.totalIncome || 0)}` }, { label: "Previous period", value: `$${money(data.previousPeriodIncome || 0)}` }, { label: cfg.memberTitle, value: data.memberCount || 0 }, { label: "Team total income", value: `$${money(data.teamTotalIncome || 0)}` } ])}
`; const members = $("#members"); (data.members || []).forEach((item) => { members.appendChild(row({ avatar: item.avatar, title: item.userName || "-", sub: `ID: ${item.account || "-"}`, side: `${cfg.subMemberLabel}: ${item.subMemberCount || 0}\n$${money(item.totalIncome || 0)}`, tag: "More", onClick: () => showAdminTeamDetail(item) })); }); if (!members.children.length) members.innerHTML = `
No data
`; } async function showAdminTeamDetail(item) { try { const res = await post("/bd/team/member/detail", { targetId: item.userId, type: cfg.detailType || cfg.teamType }); const data = res.body || {}; const body = document.createElement("div"); body.innerHTML = metrics([ { label: "Total income", value: `$${money(data.totalIncome || 0)}` }, { label: "Previous period", value: `$${money(data.previousPeriodIncome || 0)}` } ]); const card = document.createElement("div"); card.className = "card"; (data.incomeDetails || []).forEach((detail) => { card.appendChild(row({ title: detail.settlementPeriod, sub: `${cfg.subMemberLabel}: ${detail.memberCount || 0}`, side: `$${money(detail.teamTotalIncome || 0)}`, tag: detail.status || "More", onClick: () => { const detailBody = document.createElement("div"); const detailCard = document.createElement("div"); detailCard.className = "card"; (detail.members || []).forEach((member) => detailCard.appendChild(row({ avatar: member.avatar, title: member.userName, sub: `ID: ${member.account || "-"}`, side: `$${money(member.income || 0)}` }))); detailBody.appendChild(detailCard); showModal(detail.settlementPeriod, detailBody); } })); }); if (!card.children.length) card.innerHTML = `
No data
`; body.appendChild(card); showModal(`${cfg.memberTitle} ${item.account || ""}`, body); } catch (error) { toast(error.message); } } async function renderRechargeAgency() { setLoading(); const [summary, list] = await Promise.allSettled([ get("/app/h5/recharge-summary"), get("/app/h5/recharge-page?cursor=1&limit=20") ]); const data = summary.value?.body || {}; const records = list.value?.body?.records || []; $("#app").innerHTML = `${metrics([ { label: "My total income", value: `$${money(data.totalIncome || 0)}` }, { label: "This period recharge", value: `$${money(data.currentMonthRecharge || 0)}` } ])}
Recharge agency list
`; const root = $("#records"); records.forEach((item) => root.appendChild(row({ avatar: item.userAvatar, title: item.userNickname, sub: `ID: ${item.account || "-"}`, side: `This: $${money(item.thisMonth || 0)}\nLast: $${money(item.lastMonth || 0)}` }))); if (!root.children.length) root.innerHTML = `
No data
`; } async function renderMessage() { const teamId = getTeamId(); setLoading(); const res = await get(`/team/user/apply/record?teamId=${teamId}&status=WAIT`); const records = (res.body || []).map((item) => ({ id: item.id, account: item.createUserProfile?.account, name: item.createUserProfile?.userNickname, avatar: item.createUserProfile?.userAvatar })); $("#app").innerHTML = `
`; const root = $("#messages"); records.forEach((item) => { const node = row({ avatar: item.avatar, title: item.name || "Unknown user", sub: `ID: ${item.account || "-"}` }); const actions = document.createElement("div"); actions.className = "toolbar"; actions.innerHTML = ``; actions.children[0].addEventListener("click", async () => updateApply(item.id, "AGREE", node)); actions.children[1].addEventListener("click", async () => updateApply(item.id, "REJECT", node)); node.appendChild(actions); root.appendChild(node); }); if (!root.children.length) root.innerHTML = `
No data
`; } async function updateApply(id, status, node) { try { await post("/team/user/apply/record/update", { id, status }); node.remove(); toast(status === "AGREE" ? "Approved" : "Rejected"); } catch (error) { toast(error.message); } } async function renderTeamMembers() { const teamId = getTeamId(); setLoading(); const res = await get(`/team/members?id=${teamId}`); const records = res.body || []; $("#app").innerHTML = `
`; const root = $("#members"); const draw = (items) => { root.innerHTML = ""; items.forEach((member, index) => root.appendChild(row({ avatar: member.userProfile?.userAvatar, title: `${index + 1}. ${member.userProfile?.userNickname || "-"}`, sub: `ID: ${member.userProfile?.ownSpecialId?.account || member.userProfile?.account || "-"}`, side: `${member.targetFormat || "-"}\n${member.timeHours || "-"}` }))); if (!root.children.length) root.innerHTML = `
No data
`; }; draw(records); $("#searchBtn").addEventListener("click", async () => { const account = $("#search").value.trim(); if (!account) return draw(records); try { const searched = await get(`/team/search-members?account=${account}`); draw(searched.body || []); } catch (error) { toast(error.message); } }); $("#cancelBtn").addEventListener("click", () => { $("#search").value = ""; draw(records); }); } async function renderTeamBill() { const teamId = getTeamId(); setLoading(); const res = await get(`/team/bill?id=${teamId}`); const records = res.body || []; let total = 0; records.forEach((item) => { if (item.status === "SETTLED") total += Number(item.settleResult?.totalSalary || 0); }); $("#app").innerHTML = `${metrics([{ label: "History team income", value: `$${money(total)}` }])}
Work report
`; const root = $("#bills"); records.forEach((item) => root.appendChild(row({ title: item.billTitle, sub: `Host salary: $${money(item.settleResult?.memberSalary || 0)} | Agent salary: $${money(item.settleResult?.ownSalary || 0)}`, side: `$${money(item.settleResult?.totalSalary || 0)}`, tag: ({ SETTLED: "Completed", UNPAID: "In Progress", HANG_UP: "Out of account", PAY_OUT: "Completed" })[item.status] || item.status, onClick: async () => { try { const detail = await get(`/team/bill/work-members?id=${item.id}`); const body = document.createElement("div"); const card = document.createElement("div"); card.className = "card"; (detail.body || []).forEach((member) => card.appendChild(row({ avatar: member.memberProfile?.userAvatar, title: member.memberProfile?.userNickname, sub: `ID: ${member.memberProfile?.account || "-"}`, side: `Target: ${member.target?.acceptGiftValue || 0}\nDays: ${member.target?.effectiveDay || 0}` }))); body.appendChild(card); showModal(item.billTitle, body); } catch (error) { toast(error.message); } } }))); if (!root.children.length) root.innerHTML = `
No data
`; } function renderInviteProcess() { $("#app").innerHTML = `
1
Invite users to download the app.
2
Invited users log in.
3
Users join your team.
4
Enter team ID when joining.
`; } async function renderBankCards() { setLoading(); const [cards, kyc] = await Promise.allSettled([get("/wallet/bank-card/list"), get("/wallet/withdraw-info/list")]); const current = (cards.value?.body || []).find((item) => item.use); const info = kyc.value?.body?.[0]; $("#app").innerHTML = `
Bank card
KYC
`; $("#cardBox").appendChild(current ? row({ title: current.cardType, sub: `Card: ${current.cardNo}`, side: current.payee }) : row({ title: "Add payment method", sub: "No bank cards in use", tag: "Add", onClick: () => navigate("/bank-card") })); $("#kycBox").appendChild(info ? row({ title: `Status: ${info.status}`, sub: `Contact: ${info.contactNumber || "-"}`, side: info.otherDescription || "", tag: "KYC", onClick: () => navigate("/KYC") }) : row({ title: "Complete information", sub: "No KYC info", tag: "KYC", onClick: () => navigate("/KYC") })); } async function renderWalletAction() { setLoading(); const action = new URLSearchParams(location.search).get("activeAction") || cfg.action || "Exchange"; const balanceEndpoint = cfg.salaryType ? `/wallet/salary-account/balance?salaryType=${cfg.salaryType}` : "/wallet/bank/balance"; const balanceRes = await get(balanceEndpoint).catch(() => ({ body: 0 })); const balance = typeof balanceRes.body === "number" ? balanceRes.body : balanceRes.body?.availableBalance || balanceRes.body?.balance || 0; const amounts = [1, 5, 10, 50, 100, 200]; $("#app").innerHTML = ` ${metrics([{ label: "Available salaries", value: `$${money(balance)}` }])}
`; document.querySelectorAll("[data-act]").forEach((btn) => btn.addEventListener("click", () => navigate(`${location.pathname}?activeAction=${encodeURIComponent(btn.dataset.act)}&lang=${lang().toLowerCase()}`))); const panel = $("#walletPanel"); if (action === "Cash out") return renderCashOutPanel(panel); if (action === "Transfer") return renderTransferPanel(panel, amounts); renderExchangePanel(panel, amounts); } function renderExchangePanel(panel, amounts) { panel.innerHTML = `
${amounts.map((amount) => ``).join("")}
`; let selected = null; panel.querySelectorAll("[data-amount]").forEach((node) => node.addEventListener("click", () => { selected = Number(node.dataset.amount); panel.querySelectorAll(".tile").forEach((tile) => tile.classList.remove("selected")); node.classList.add("selected"); })); $("#submit").addEventListener("click", async () => { if (!selected) return toast("Please select amount"); try { const path = cfg.salaryType ? "/wallet/salary-account/exchange/gold" : "/wallet/bank/exchange/gold"; await post(path, cfg.salaryType ? { amount: selected, salaryType: cfg.salaryType } : { amount: selected }); toast("Exchange success"); } catch (error) { toast(error.message); } }); } function renderTransferPanel(panel, amounts) { panel.innerHTML = `
${amounts.map((amount) => ``).join("")}
`; let payee = null; let selected = null; $("#findPayee").addEventListener("click", async () => { try { const res = await get(`/user/user-profile/open-search?account=${encodeURIComponent($("#payee").value.trim())}`); payee = res.body; $("#payeeInfo").innerHTML = ""; $("#payeeInfo").appendChild(row({ avatar: payee.userAvatar, title: payee.userNickname || payee.name, sub: `ID: ${payee.account}`, side: "" })); } catch (error) { toast(error.message); } }); panel.querySelectorAll("[data-amount]").forEach((node) => node.addEventListener("click", () => { selected = Number(node.dataset.amount); panel.querySelectorAll(".tile").forEach((tile) => tile.classList.remove("selected")); node.classList.add("selected"); })); $("#submit").addEventListener("click", async () => { if (!selected || !payee?.id) return toast("Please select amount and payee"); try { const path = cfg.salaryType ? "/wallet/salary-account/transferGold" : "/wallet/bank/transferGold"; await post(path, cfg.salaryType ? { amount: selected, acceptUserId: payee.id, salaryType: cfg.salaryType } : { amount: selected, acceptUserId: payee.id, acceptMethod: "BANK_TRANSFER" }); toast("Transfer success"); } catch (error) { toast(error.message); } }); } async function renderCashOutPanel(panel) { const [cards, kyc] = await Promise.allSettled([get("/wallet/bank-card/list"), get("/wallet/withdraw-info/list")]); const card = (cards.value?.body || []).find((item) => item.use); const info = kyc.value?.body?.[0]; panel.innerHTML = `
`; $("#card").appendChild(card ? row({ title: card.cardType, sub: `Card: ${card.cardNo}`, side: card.payee }) : row({ title: "No bank cards in use", sub: "Add bank card", tag: "Add", onClick: () => navigate("/bank-card") })); $("#kyc").appendChild(info ? row({ title: `KYC: ${info.status}`, sub: `Contact: ${info.contactNumber || "-"}`, tag: "KYC" }) : row({ title: "Complete KYC", sub: "No KYC information", tag: "KYC", onClick: () => navigate("/KYC") })); $("#submit").addEventListener("click", async () => { const amount = Number($("#amount").value); if (!card?.id || !amount || amount < 50) return toast("Please complete information and enter at least 50"); try { await post("/wallet/bank/withdraw", { amount, acceptBankCardId: card.id, salaryType: cfg.salaryType || (getIdentity() === "HOST" ? "HOST_SALARY" : "BD_SALARY") }); toast("Cash withdrawal submitted"); } catch (error) { toast(error.message); } }); } async function renderItemDistribution() { setLoading(); const permissionEndpoint = cfg.admin ? "/app/h5/own-permission?propsType=NOBLE_VIP" : "/sys/bd/list-permission"; const propsBase = cfg.admin ? "/sys/manager/props" : "/sys/bd/props"; const sendEndpoint = cfg.admin ? "/sys/manager/send" : "/sys/bd/send"; let tabs = cfg.admin ? [{ name: "frames", type: "AVATAR_FRAME" }, { name: "vehicles", type: "RIDE" }, { name: "vip", type: "NOBLE_VIP" }] : []; if (!cfg.admin) { const res = await get(permissionEndpoint); const body = res.body || []; if (body.includes("AVATAR_FRAME")) tabs.push({ name: "frames", type: "AVATAR_FRAME" }); if (body.includes("RIDE")) tabs.push({ name: "vehicles", type: "RIDE" }); if (body.some((x) => String(x).startsWith("NOBLE_VIP"))) tabs.push({ name: "vip", type: "NOBLE_VIP" }); } if (!tabs.length) tabs = [{ name: "frames", type: "AVATAR_FRAME" }]; $("#app").innerHTML = `
${tabs.map((tab, index) => ``).join("")}
`; const load = async (tab) => { const res = await get(`${propsBase}?propsType=${tab.type}¤cyType=GOLD`); const root = $("#props"); root.innerHTML = ""; (res.body || []).forEach((item) => { const tile = document.createElement("button"); tile.type = "button"; tile.className = "tile"; tile.innerHTML = `${item.name || "Item"}Send`; tile.addEventListener("click", () => openSendProps(item, sendEndpoint)); root.appendChild(tile); }); if (!root.children.length) root.innerHTML = `
No data
`; }; document.querySelectorAll("[data-tab]").forEach((btn) => btn.addEventListener("click", () => { document.querySelectorAll("[data-tab]").forEach((b) => b.classList.remove("active")); btn.classList.add("active"); load(tabs[Number(btn.dataset.tab)]); })); await load(tabs[0]); } function openSendProps(item, endpoint) { const body = document.createElement("div"); body.innerHTML = `
`; $("#confirmSend", body).addEventListener("click", async () => { try { const user = await get(`/user/user-profile/open-search?account=${encodeURIComponent($("#targetUser", body).value.trim())}`); await post(endpoint, { propsId: item.id, acceptUserId: user.body.id }); closeModal(); toast("Gift delivery successful"); } catch (error) { toast(error.message); } }); showModal(item.name || "Send", body, true); } function renderPolicy() { $("#app").innerHTML = ""; } async function renderPlatformPolicy() { const teamId = getTeamId(); setLoading(); const res = await get(`/team/release/policy?id=${teamId}`); const policies = res.body?.policy || []; $("#app").innerHTML = `
`; const root = $("#policyList"); policies.forEach((item) => root.appendChild(row({ title: `Lv.${item.level}`, sub: `Time: ${item.onlineTime || 0}h | Target: ${item.target || 0}`, side: `Host: $${money(item.memberSalary || 0)}\nAgent: $${money(item.ownSalary || 0)}` }))); if (!root.children.length) root.innerHTML = `
No policy data available
`; } async function init() { renderShell(); try { await connectApp(); const handlers = { teamHistory: renderTeamHistory, adminTeam: renderAdminTeam, rechargeAgency: renderRechargeAgency, message: renderMessage, teamMembers: renderTeamMembers, teamBill: renderTeamBill, inviteProcess: renderInviteProcess, bankCards: renderBankCards, walletAction: renderWalletAction, itemDistribution: renderItemDistribution, platformPolicy: renderPlatformPolicy, policy: renderPolicy }; await (handlers[cfg.mode] || renderPolicy)(); } catch (error) { console.error(error); $("#app").innerHTML = `
${error.message || "Failed to load data"}
`; } } init();