月度工资查看
This commit is contained in:
parent
d33cbbcdac
commit
4bae0aca72
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||||
<title>BD Center</title>
|
<title>BD Center</title>
|
||||||
<link rel="stylesheet" href="./style.css?v=20260429-0300" />
|
<link rel="stylesheet" href="./style.css?v=20260601-1900" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="bd-center" aria-label="BD Center" data-i18n-aria="page_label" data-loading="true">
|
<div class="bd-center" aria-label="BD Center" data-i18n-aria="page_label" data-loading="true">
|
||||||
@ -69,6 +69,13 @@
|
|||||||
<div class="team-list-tabs is-single" role="tablist" aria-label="Team lists">
|
<div class="team-list-tabs is-single" role="tablist" aria-label="Team lists">
|
||||||
<button class="team-list-tab is-active" type="button" role="tab" aria-selected="true" data-list-tab="agency" data-i18n="agency_list_link">Agency List</button>
|
<button class="team-list-tab is-active" type="button" role="tab" aria-selected="true" data-list-tab="agency" data-i18n="agency_list_link">Agency List</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="team-list-period">
|
||||||
|
<label class="month-filter">
|
||||||
|
<span data-i18n="month_label">Month</span>
|
||||||
|
<input id="billMonthInput" type="month" data-i18n-aria="month_label" aria-label="Month" />
|
||||||
|
</label>
|
||||||
|
<div class="bill-range" id="billRange"></div>
|
||||||
|
</div>
|
||||||
<div class="team-list-summary" id="teamListSummary"></div>
|
<div class="team-list-summary" id="teamListSummary"></div>
|
||||||
<div class="team-list-content" id="teamListContent">
|
<div class="team-list-content" id="teamListContent">
|
||||||
<div class="empty-state" data-i18n="loading_data">Loading...</div>
|
<div class="empty-state" data-i18n="loading_data">Loading...</div>
|
||||||
@ -116,6 +123,6 @@
|
|||||||
|
|
||||||
<div class="toast" id="toast" role="status" aria-live="polite" hidden></div>
|
<div class="toast" id="toast" role="status" aria-live="polite" hidden></div>
|
||||||
</div>
|
</div>
|
||||||
<script src="./script.js?v=20260529-1300" defer></script>
|
<script src="./script.js?v=20260601-1900" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
bd_number: "BD number",
|
bd_number: "BD number",
|
||||||
team_salary: "Team salary",
|
team_salary: "Team salary",
|
||||||
agency_list_link: "Agency List",
|
agency_list_link: "Agency List",
|
||||||
|
month_label: "Month",
|
||||||
invite_become_agent: "Invite Agent",
|
invite_become_agent: "Invite Agent",
|
||||||
invite_agent_title: "Invite Agent",
|
invite_agent_title: "Invite Agent",
|
||||||
enter_user_id: "Enter User ID",
|
enter_user_id: "Enter User ID",
|
||||||
@ -65,6 +66,7 @@
|
|||||||
bd_number: "عدد BD",
|
bd_number: "عدد BD",
|
||||||
team_salary: "راتب الفريق",
|
team_salary: "راتب الفريق",
|
||||||
agency_list_link: "قائمة الوكالات",
|
agency_list_link: "قائمة الوكالات",
|
||||||
|
month_label: "الشهر",
|
||||||
invite_become_agent: "دعوة وكيل",
|
invite_become_agent: "دعوة وكيل",
|
||||||
invite_agent_title: "دعوة وكيل",
|
invite_agent_title: "دعوة وكيل",
|
||||||
enter_user_id: "أدخل معرف المستخدم",
|
enter_user_id: "أدخل معرف المستخدم",
|
||||||
@ -104,6 +106,7 @@
|
|||||||
bd_number: "BD sayısı",
|
bd_number: "BD sayısı",
|
||||||
team_salary: "Takım maaşı",
|
team_salary: "Takım maaşı",
|
||||||
agency_list_link: "Ajans listesi",
|
agency_list_link: "Ajans listesi",
|
||||||
|
month_label: "Ay",
|
||||||
invite_become_agent: "Ajans Davet Et",
|
invite_become_agent: "Ajans Davet Et",
|
||||||
invite_agent_title: "Ajans Davet Et",
|
invite_agent_title: "Ajans Davet Et",
|
||||||
enter_user_id: "Kullanıcı ID gir",
|
enter_user_id: "Kullanıcı ID gir",
|
||||||
@ -143,6 +146,7 @@
|
|||||||
bd_number: "Jumlah BD",
|
bd_number: "Jumlah BD",
|
||||||
team_salary: "Gaji tim",
|
team_salary: "Gaji tim",
|
||||||
agency_list_link: "Daftar agensi",
|
agency_list_link: "Daftar agensi",
|
||||||
|
month_label: "Bulan",
|
||||||
invite_become_agent: "Invite Agent",
|
invite_become_agent: "Invite Agent",
|
||||||
invite_agent_title: "Invite Agent",
|
invite_agent_title: "Invite Agent",
|
||||||
enter_user_id: "Masukkan ID Pengguna",
|
enter_user_id: "Masukkan ID Pengguna",
|
||||||
@ -176,7 +180,7 @@
|
|||||||
profile: "/team/member/profile",
|
profile: "/team/member/profile",
|
||||||
identity: "/app/h5/identity",
|
identity: "/app/h5/identity",
|
||||||
balance: "/wallet/salary-account/balance?salaryType=BD_SALARY",
|
balance: "/wallet/salary-account/balance?salaryType=BD_SALARY",
|
||||||
agencyBill: "/team/bd/member-bill/list?type=BD",
|
agencyBill: (billBelong) => `/team/bd/member-bill/list?type=BD&billBelong=${encodeURIComponent(billBelong)}`,
|
||||||
inviteList: "/team/bd/invite-message-own",
|
inviteList: "/team/bd/invite-message-own",
|
||||||
inviteSearch: (account) => `/user/user-profile/open-search?account=${encodeURIComponent(account)}`,
|
inviteSearch: (account) => `/user/user-profile/open-search?account=${encodeURIComponent(account)}`,
|
||||||
inviteAgent: "/team/bd/invite-agent",
|
inviteAgent: "/team/bd/invite-agent",
|
||||||
@ -190,6 +194,7 @@
|
|||||||
balanceTotal: {},
|
balanceTotal: {},
|
||||||
bill: {},
|
bill: {},
|
||||||
agencyBill: null,
|
agencyBill: null,
|
||||||
|
billMonth: normalizeMonthValue(params.get("month") || params.get("billBelong")) || getCurrentMonthValue(),
|
||||||
teamList: {
|
teamList: {
|
||||||
type: "agency",
|
type: "agency",
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -253,6 +258,52 @@
|
|||||||
return supportedLanguages.includes(value) ? value : "en";
|
return supportedLanguages.includes(value) ? value : "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentMonthValue() {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
||||||
|
return `${year}-${month}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeMonthValue(value) {
|
||||||
|
const raw = String(value || "").trim();
|
||||||
|
let year = "";
|
||||||
|
let month = "";
|
||||||
|
|
||||||
|
if (/^\d{4}-\d{2}$/.test(raw)) {
|
||||||
|
[year, month] = raw.split("-");
|
||||||
|
} else if (/^\d{6}$/.test(raw)) {
|
||||||
|
year = raw.slice(0, 4);
|
||||||
|
month = raw.slice(4, 6);
|
||||||
|
} else if (/^\d{8}$/.test(raw)) {
|
||||||
|
year = raw.slice(0, 4);
|
||||||
|
month = raw.slice(4, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
const numericYear = Number(year);
|
||||||
|
const numericMonth = Number(month);
|
||||||
|
if (!Number.isInteger(numericYear) || !Number.isInteger(numericMonth)) return "";
|
||||||
|
if (numericYear < 2000 || numericYear > 2099 || numericMonth < 1 || numericMonth > 12) return "";
|
||||||
|
return `${year}-${String(numericMonth).padStart(2, "0")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function monthValueToBillBelong(value) {
|
||||||
|
return normalizeMonthValue(value).replace("-", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncMonthControl() {
|
||||||
|
const input = document.querySelector("#billMonthInput");
|
||||||
|
if (!input) return;
|
||||||
|
input.max = getCurrentMonthValue();
|
||||||
|
input.value = state.billMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBillRange(data = teamListBill()) {
|
||||||
|
const range = document.querySelector("#billRange");
|
||||||
|
if (!range) return;
|
||||||
|
range.textContent = data?.billTitle || state.billMonth.replace("-", ".");
|
||||||
|
}
|
||||||
|
|
||||||
function message(key, fallback = "") {
|
function message(key, fallback = "") {
|
||||||
return currentMessages[key] || fallbackMessages.en[key] || fallback || key;
|
return currentMessages[key] || fallbackMessages.en[key] || fallback || key;
|
||||||
}
|
}
|
||||||
@ -577,6 +628,8 @@
|
|||||||
const members = Array.isArray(data.memberBillList) ? data.memberBillList : [];
|
const members = Array.isArray(data.memberBillList) ? data.memberBillList : [];
|
||||||
const summary = document.querySelector("#teamListSummary");
|
const summary = document.querySelector("#teamListSummary");
|
||||||
const content = document.querySelector("#teamListContent");
|
const content = document.querySelector("#teamListContent");
|
||||||
|
syncMonthControl();
|
||||||
|
renderBillRange(data);
|
||||||
document.querySelectorAll("[data-list-tab]").forEach((button) => {
|
document.querySelectorAll("[data-list-tab]").forEach((button) => {
|
||||||
const active = normalizeTeamListType(button.dataset.listTab) === type;
|
const active = normalizeTeamListType(button.dataset.listTab) === type;
|
||||||
button.classList.toggle("is-active", active);
|
button.classList.toggle("is-active", active);
|
||||||
@ -933,11 +986,37 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAgencyBill() {
|
async function fetchAgencyBill() {
|
||||||
state.agencyBill = await requestJSON(bdCenterEndpoints.agencyBill) || {};
|
state.agencyBill = await requestJSON(bdCenterEndpoints.agencyBill(monthValueToBillBelong(state.billMonth))) || {};
|
||||||
renderBill();
|
renderBill();
|
||||||
renderTeamListCard();
|
renderTeamListCard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleBillMonthChange(event) {
|
||||||
|
const nextMonth = normalizeMonthValue(event.target.value);
|
||||||
|
if (!nextMonth) {
|
||||||
|
syncMonthControl();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nextMonth === state.billMonth) return;
|
||||||
|
|
||||||
|
state.billMonth = nextMonth;
|
||||||
|
state.agencyBill = null;
|
||||||
|
state.teamList.error = "";
|
||||||
|
state.teamList.loading = true;
|
||||||
|
renderTeamListCard();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetchAgencyBill();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to load selected bill month:", error);
|
||||||
|
state.teamList.error = error.response?.errorMsg || error.message || message("failed_to_load");
|
||||||
|
showToast(state.teamList.error);
|
||||||
|
} finally {
|
||||||
|
state.teamList.loading = false;
|
||||||
|
renderTeamListCard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function ensureTeamListData(type) {
|
async function ensureTeamListData(type) {
|
||||||
const normalizedType = normalizeTeamListType(type);
|
const normalizedType = normalizeTeamListType(type);
|
||||||
if (hasTeamListData(teamListBill(normalizedType))) return;
|
if (hasTeamListData(teamListBill(normalizedType))) return;
|
||||||
@ -1083,6 +1162,7 @@
|
|||||||
document.querySelectorAll("[data-list-tab]").forEach((button) => {
|
document.querySelectorAll("[data-list-tab]").forEach((button) => {
|
||||||
button.addEventListener("click", () => switchTeamList(button.dataset.listTab));
|
button.addEventListener("click", () => switchTeamList(button.dataset.listTab));
|
||||||
});
|
});
|
||||||
|
document.querySelector("#billMonthInput")?.addEventListener("change", handleBillMonthChange);
|
||||||
document.querySelector("[data-action='invite-agent']")?.addEventListener("click", () => showInviteModal("agent"));
|
document.querySelector("[data-action='invite-agent']")?.addEventListener("click", () => showInviteModal("agent"));
|
||||||
document.querySelector("#inviteSearchInput")?.addEventListener("input", handleInviteInput);
|
document.querySelector("#inviteSearchInput")?.addEventListener("input", handleInviteInput);
|
||||||
document.querySelector("#inviteSearchForm")?.addEventListener("submit", searchInviteUser);
|
document.querySelector("#inviteSearchForm")?.addEventListener("submit", searchInviteUser);
|
||||||
|
|||||||
@ -412,6 +412,55 @@ button {
|
|||||||
box-shadow: 0 8px 18px rgba(21, 189, 169, 0.24);
|
box-shadow: 0 8px 18px rgba(21, 189, 169, 0.24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.team-list-period {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-filter {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-filter span {
|
||||||
|
color: #8b8d92;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 850;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-filter input {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
height: 38px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border: 1px solid #e4e8eb;
|
||||||
|
border-radius: 8px;
|
||||||
|
outline: none;
|
||||||
|
background: #fbfcfc;
|
||||||
|
color: #24282e;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-filter input:focus {
|
||||||
|
border-color: rgba(16, 188, 176, 0.72);
|
||||||
|
box-shadow: 0 0 0 3px rgba(67, 231, 216, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill-range {
|
||||||
|
min-width: 0;
|
||||||
|
color: #8b8d92;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 850;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
.team-list-summary {
|
.team-list-summary {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||||
<title>Withdraw/Exchange</title>
|
<title>Withdraw/Exchange</title>
|
||||||
<link rel="stylesheet" href="./style.css?v=20260529-0100" />
|
<link rel="stylesheet" href="./style.css?v=20260601-0110" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wallet-page" aria-label="Withdraw and exchange" data-i18n-aria="page_label">
|
<div class="wallet-page" aria-label="Withdraw and exchange" data-i18n-aria="page_label">
|
||||||
@ -165,6 +165,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="home-indicator" aria-hidden="true"></div>
|
<div class="home-indicator" aria-hidden="true"></div>
|
||||||
</div>
|
</div>
|
||||||
<script src="./script.js?v=20260601-0100" defer></script>
|
<script src="./script.js?v=20260601-0110" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -694,7 +694,190 @@
|
|||||||
return message("available_income", "salary");
|
return message("available_income", "salary");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function salaryHistoryCode(item) {
|
||||||
|
const candidates = [
|
||||||
|
item?.salaryEvent,
|
||||||
|
item?.event,
|
||||||
|
item?.status,
|
||||||
|
item?.title,
|
||||||
|
item?.eventDesc,
|
||||||
|
item?.eventDescribe,
|
||||||
|
item?.salaryTypeName
|
||||||
|
];
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
const value = String(candidate || "").trim().toUpperCase();
|
||||||
|
if (value) return value;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAgencySalaryHistoryItem(item) {
|
||||||
|
const code = salaryHistoryCode(item);
|
||||||
|
const salaryType = normalizeSalaryType(item?.salaryType);
|
||||||
|
if (
|
||||||
|
code.includes("SETTLEMENT_WAGES_AGENT") ||
|
||||||
|
code.includes("SETTLEMENT_WAGES_MEMBER") ||
|
||||||
|
code.includes("BD_SALARY_SETTLEMENT") ||
|
||||||
|
code.includes("BD_LEADER_SALARY_SETTLEMENT") ||
|
||||||
|
code.includes("ADMIN_SALARY_SETTLEMENT")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return code === "ISSUE" && salaryType && salaryType !== "HOST_SALARY";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHostSalaryHistoryItem(item) {
|
||||||
|
if (isAgencySalaryHistoryItem(item)) return false;
|
||||||
|
const code = salaryHistoryCode(item);
|
||||||
|
const salaryType = normalizeSalaryType(item?.salaryType);
|
||||||
|
if (code === "SYSTEM_SETTLEMENT_WAGES" || code === "SYSTEM_AUTOMATIC_SETTLEMENT_WAGES" || code === "SEND_SALARY") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (code === "ISSUE" && salaryType === "HOST_SALARY") return true;
|
||||||
|
return code.includes("SETTLEMENT_WAGES") || code.includes("SETTLEMENT WAGES");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHistoryObject(value) {
|
||||||
|
if (!value) return null;
|
||||||
|
if (typeof value === "object") return value;
|
||||||
|
if (typeof value !== "string") return null;
|
||||||
|
const text = value.trim();
|
||||||
|
if (!text || !text.startsWith("{")) return null;
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanHistoryName(value) {
|
||||||
|
const text = String(value || "").trim();
|
||||||
|
if (!text || text === "null" || text === "undefined" || /^\d+$/.test(text)) return "";
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanHistoryAvatar(value) {
|
||||||
|
const text = String(value || "").trim();
|
||||||
|
if (!text || text === "null" || text === "undefined" || /^\d+$/.test(text)) return "";
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function historyNameFromObject(source) {
|
||||||
|
const object = parseHistoryObject(source);
|
||||||
|
if (!object) return "";
|
||||||
|
|
||||||
|
const keys = [
|
||||||
|
"providerName",
|
||||||
|
"agencyName",
|
||||||
|
"agentName",
|
||||||
|
"fromUserName",
|
||||||
|
"sourceName",
|
||||||
|
"senderName",
|
||||||
|
"userNickname",
|
||||||
|
"userNickName",
|
||||||
|
"nickName",
|
||||||
|
"nickname",
|
||||||
|
"name",
|
||||||
|
"account"
|
||||||
|
];
|
||||||
|
for (const key of keys) {
|
||||||
|
const name = cleanHistoryName(object[key]);
|
||||||
|
if (name) return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedKeys = ["provider", "agency", "agent", "fromUser", "sourceUser", "sender", "user", "acceptUser", "acceptUserAccount", "profile"];
|
||||||
|
for (const key of nestedKeys) {
|
||||||
|
const name = historyNameFromObject(object[key]);
|
||||||
|
if (name) return name;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function historyAvatarFromObject(source) {
|
||||||
|
const object = parseHistoryObject(source);
|
||||||
|
if (!object) return "";
|
||||||
|
|
||||||
|
const keys = [
|
||||||
|
"userAvatar",
|
||||||
|
"avatar",
|
||||||
|
"avatarUrl",
|
||||||
|
"avatarURL",
|
||||||
|
"headPic",
|
||||||
|
"headImg",
|
||||||
|
"portrait",
|
||||||
|
"photo",
|
||||||
|
"profileImage",
|
||||||
|
"image"
|
||||||
|
];
|
||||||
|
for (const key of keys) {
|
||||||
|
const avatar = cleanHistoryAvatar(object[key]);
|
||||||
|
if (avatar) return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedKeys = ["provider", "agency", "agent", "fromUser", "sourceUser", "sender", "user", "acceptUser", "acceptUserAccount", "profile"];
|
||||||
|
for (const key of nestedKeys) {
|
||||||
|
const avatar = historyAvatarFromObject(object[key]);
|
||||||
|
if (avatar) return avatar;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencySalaryProviderName(item) {
|
||||||
|
return historyNameFromObject(item) ||
|
||||||
|
historyNameFromObject(item?.details) ||
|
||||||
|
historyNameFromObject(item?.detail) ||
|
||||||
|
historyNameFromObject(item?.raw) ||
|
||||||
|
"Agency";
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencySalaryProviderAvatar(item) {
|
||||||
|
return historyAvatarFromObject(item) ||
|
||||||
|
historyAvatarFromObject(item?.details) ||
|
||||||
|
historyAvatarFromObject(item?.detail) ||
|
||||||
|
historyAvatarFromObject(item?.raw) ||
|
||||||
|
"";
|
||||||
|
}
|
||||||
|
|
||||||
|
function agencySalaryDescription(item) {
|
||||||
|
if (!isAgencySalaryHistoryItem(item)) return "";
|
||||||
|
return `${agencySalaryProviderName(item)} provided you $${formatMoney(item.amount)} salary`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAgencySalaryDescription(item) {
|
||||||
|
const text = agencySalaryDescription(item);
|
||||||
|
if (!text) return null;
|
||||||
|
|
||||||
|
const name = agencySalaryProviderName(item);
|
||||||
|
const avatarURL = agencySalaryProviderAvatar(item);
|
||||||
|
const description = document.createElement("div");
|
||||||
|
description.className = "salary-history-item-desc";
|
||||||
|
|
||||||
|
const avatar = document.createElement("span");
|
||||||
|
avatar.className = "salary-history-desc-avatar";
|
||||||
|
if (avatarURL) {
|
||||||
|
const image = document.createElement("img");
|
||||||
|
image.src = avatarURL;
|
||||||
|
image.alt = "";
|
||||||
|
avatar.appendChild(image);
|
||||||
|
} else {
|
||||||
|
avatar.textContent = (name.slice(0, 1) || "A").toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
const copy = document.createElement("span");
|
||||||
|
copy.className = "salary-history-item-desc-text";
|
||||||
|
copy.textContent = text;
|
||||||
|
|
||||||
|
description.append(avatar, copy);
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldShowHistoryStatus(item) {
|
||||||
|
return Boolean(item.status && !isAgencySalaryHistoryItem(item) && !isHostSalaryHistoryItem(item));
|
||||||
|
}
|
||||||
|
|
||||||
function historyItemTitle(item) {
|
function historyItemTitle(item) {
|
||||||
|
if (isAgencySalaryHistoryItem(item)) return "Agency salary";
|
||||||
|
if (isHostSalaryHistoryItem(item)) return "Host salary";
|
||||||
return item.title ||
|
return item.title ||
|
||||||
item.eventDesc ||
|
item.eventDesc ||
|
||||||
item.eventDescribe ||
|
item.eventDescribe ||
|
||||||
@ -715,6 +898,8 @@
|
|||||||
title.className = "salary-history-item-title";
|
title.className = "salary-history-item-title";
|
||||||
title.textContent = historyItemTitle(item);
|
title.textContent = historyItemTitle(item);
|
||||||
|
|
||||||
|
const description = createAgencySalaryDescription(item);
|
||||||
|
|
||||||
const meta = document.createElement("div");
|
const meta = document.createElement("div");
|
||||||
meta.className = "salary-history-item-meta";
|
meta.className = "salary-history-item-meta";
|
||||||
const metaItems = [];
|
const metaItems = [];
|
||||||
@ -727,7 +912,9 @@
|
|||||||
}
|
}
|
||||||
meta.textContent = metaItems.join(" ");
|
meta.textContent = metaItems.join(" ");
|
||||||
|
|
||||||
main.append(title, meta);
|
main.append(title);
|
||||||
|
if (description) main.appendChild(description);
|
||||||
|
main.appendChild(meta);
|
||||||
|
|
||||||
const isOut = Number(item.type) === 1;
|
const isOut = Number(item.type) === 1;
|
||||||
const amount = document.createElement("div");
|
const amount = document.createElement("div");
|
||||||
@ -735,7 +922,7 @@
|
|||||||
amount.textContent = `${isOut ? "-" : "+"}$${formatMoney(item.amount)}`;
|
amount.textContent = `${isOut ? "-" : "+"}$${formatMoney(item.amount)}`;
|
||||||
|
|
||||||
row.append(main, amount);
|
row.append(main, amount);
|
||||||
if (item.status) {
|
if (shouldShowHistoryStatus(item)) {
|
||||||
const status = document.createElement("div");
|
const status = document.createElement("div");
|
||||||
status.className = "salary-history-status";
|
status.className = "salary-history-status";
|
||||||
status.textContent = item.status;
|
status.textContent = item.status;
|
||||||
@ -866,6 +1053,15 @@
|
|||||||
items: records.map((item) => ({
|
items: records.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
title: item.eventDesc || item.salaryTypeName || salaryTypeLabel(item.salaryType),
|
title: item.eventDesc || item.salaryTypeName || salaryTypeLabel(item.salaryType),
|
||||||
|
eventDesc: item.eventDesc,
|
||||||
|
eventDescribe: item.eventDescribe,
|
||||||
|
salaryEvent: item.salaryEvent,
|
||||||
|
event: item.event || item.salaryEvent,
|
||||||
|
salaryType: item.salaryType || activeSalaryType(),
|
||||||
|
salaryTypeName: item.salaryTypeName,
|
||||||
|
details: item.details || item.detail,
|
||||||
|
detail: item.detail,
|
||||||
|
raw: item,
|
||||||
amount: item.amount,
|
amount: item.amount,
|
||||||
balance: item.availableBalance ?? item.balance,
|
balance: item.availableBalance ?? item.balance,
|
||||||
type: item.type,
|
type: item.type,
|
||||||
@ -884,6 +1080,11 @@
|
|||||||
items: records.map((item) => ({
|
items: records.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
title: item.eventDescribe || item.event || message("salary_history", "Salary history"),
|
title: item.eventDescribe || item.event || message("salary_history", "Salary history"),
|
||||||
|
event: item.event,
|
||||||
|
eventDescribe: item.eventDescribe,
|
||||||
|
details: item.details || item.detail,
|
||||||
|
detail: item.detail,
|
||||||
|
raw: item,
|
||||||
amount: item.amount,
|
amount: item.amount,
|
||||||
balance: item.balance,
|
balance: item.balance,
|
||||||
type: item.type,
|
type: item.type,
|
||||||
|
|||||||
@ -783,6 +783,48 @@ select {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.salary-history-item-desc {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
margin-top: 5px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.salary-history-desc-avatar {
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 18px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #e5f7f5;
|
||||||
|
color: #0d8f83;
|
||||||
|
font-size: 9px;
|
||||||
|
font-weight: 950;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.salary-history-desc-avatar img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.salary-history-item-desc-text {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.salary-history-item-meta {
|
.salary-history-item-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
/>
|
/>
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<title>Recharge Center</title>
|
<title>Recharge Center</title>
|
||||||
<link rel="stylesheet" href="./style.css?v=20260601-0400" />
|
<link rel="stylesheet" href="./style.css?v=20260601-0600" />
|
||||||
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -219,6 +219,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="./script.js?v=20260601-0400"></script>
|
<script src="./script.js?v=20260601-0600"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -141,7 +141,7 @@
|
|||||||
if (window.location.protocol === "file:") return fallbackMessages[normalizedLang] || fallbackMessages.en;
|
if (window.location.protocol === "file:") return fallbackMessages[normalizedLang] || fallbackMessages.en;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`./locales/${normalizedLang}.json?v=20260601-0400`, { cache: "no-store" });
|
const response = await fetch(`./locales/${normalizedLang}.json?v=20260601-0600`, { cache: "no-store" });
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return { ...fallbackMessages.en, ...data };
|
return { ...fallbackMessages.en, ...data };
|
||||||
@ -526,6 +526,12 @@
|
|||||||
return value.includes("TRC20") && (value.includes("USDT") || value.includes("UDST"));
|
return value.includes("TRC20") && (value.includes("USDT") || value.includes("UDST"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isBankTransferChannel(item) {
|
||||||
|
const code = String(channelCode(item) || "").trim().toUpperCase();
|
||||||
|
const value = `${code} ${channelName(item)} ${item?.details?.factoryChannel || ""}`.toUpperCase();
|
||||||
|
return code === "BANK" || value.includes("BANK TRANSFER") || value.includes("BANKTRANSFER") || value.includes("BANK_TRANSFER");
|
||||||
|
}
|
||||||
|
|
||||||
function isSuccessfulPaymentStatus(data) {
|
function isSuccessfulPaymentStatus(data) {
|
||||||
if (data?.success === true || data?.paid === true || data?.paySuccess === true || data?.orderPaid === true) return true;
|
if (data?.success === true || data?.paid === true || data?.paySuccess === true || data?.orderPaid === true) return true;
|
||||||
const status = String(data?.status || data?.orderStatus || data?.payStatus || data?.tradeStatus || "").trim().toUpperCase();
|
const status = String(data?.status || data?.orderStatus || data?.payStatus || data?.tradeStatus || "").trim().toUpperCase();
|
||||||
@ -675,8 +681,12 @@
|
|||||||
{ id: "g3", content: "100,000 coins", amountUsd: 10, awardContent: "+12,000 bonus" }
|
{ id: "g3", content: "100,000 coins", amountUsd: 10, awardContent: "+12,000 bonus" }
|
||||||
],
|
],
|
||||||
channels: [
|
channels: [
|
||||||
{ channel: { channelCode: "UPI", channelName: "UPI" } },
|
{ channel: { channelCode: "UPI_BHIM", channelName: "BHIM UPI", channelIcon: "../mifa-pay/logos/bhim.png" } },
|
||||||
{ channel: { channelCode: "BANK", channelName: "Bank Transfer" } },
|
{ channel: { channelCode: "UPI_PHONEPE", channelName: "PhonePe", channelIcon: "../mifa-pay/logos/phonepe.png" } },
|
||||||
|
{ channel: { channelCode: "UPI_GOOGLEPAY", channelName: "Google Pay", channelIcon: "../mifa-pay/logos/googlepay.png" } },
|
||||||
|
{ channel: { channelCode: "UPI_PAYTM", channelName: "Paytm", channelIcon: "../mifa-pay/logos/paytm.png" } },
|
||||||
|
{ channel: { channelCode: "UPI_MOBIKWIK", channelName: "Mobikwik", channelIcon: "../mifa-pay/logos/mobikwik.png" } },
|
||||||
|
{ channel: { channelCode: "UPI", channelName: "UPI", channelIcon: "../mifa-pay/logos/upi.png" } },
|
||||||
{
|
{
|
||||||
channel: { channelCode: "USDT_TRC20", channelName: "USDT TRC20" },
|
channel: { channelCode: "USDT_TRC20", channelName: "USDT TRC20" },
|
||||||
details: { trc20Address: "TMockTrc20RechargeAddress000000000001" }
|
details: { trc20Address: "TMockTrc20RechargeAddress000000000001" }
|
||||||
@ -775,8 +785,7 @@
|
|||||||
},
|
},
|
||||||
visibleChannels() {
|
visibleChannels() {
|
||||||
const usdtTrc20 = this.channels.filter(isUsdtTrc20Channel);
|
const usdtTrc20 = this.channels.filter(isUsdtTrc20Channel);
|
||||||
if (this.isDealer) return usdtTrc20;
|
const thirdParty = this.channels.filter((channel) => !isUsdtChannel(channel) && !isBankTransferChannel(channel));
|
||||||
const thirdParty = this.channels.filter((channel) => !isUsdtChannel(channel));
|
|
||||||
return [...thirdParty, ...usdtTrc20];
|
return [...thirdParty, ...usdtTrc20];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -381,8 +381,8 @@ button:disabled {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 42px;
|
width: 36px;
|
||||||
height: 42px;
|
height: 36px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #eaf7f5;
|
background: #eaf7f5;
|
||||||
@ -408,11 +408,12 @@ button:disabled {
|
|||||||
.method-badge {
|
.method-badge {
|
||||||
min-height: 22px;
|
min-height: 22px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
padding: 3px 8px;
|
padding: 3px 6px;
|
||||||
background: #fff0c2;
|
background: #fff0c2;
|
||||||
color: #8a5c00;
|
color: #8a5c00;
|
||||||
font-size: 11px;
|
font-size: 10px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.payment-head {
|
.payment-head {
|
||||||
@ -421,18 +422,20 @@ button:disabled {
|
|||||||
|
|
||||||
.package-grid {
|
.package-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.package-button {
|
.package-button {
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
gap: 4px;
|
align-content: center;
|
||||||
min-height: 106px;
|
gap: 5px;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 94px;
|
||||||
border: 1px solid var(--line);
|
border: 1px solid var(--line);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 10px 8px;
|
padding: 9px 6px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
@ -444,22 +447,20 @@ button:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.coin-mark {
|
.coin-mark {
|
||||||
width: 26px;
|
display: block;
|
||||||
height: 26px;
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background:
|
background: url("../smash-golden-egg/assets/common/yumi_coin.png") center / contain no-repeat;
|
||||||
radial-gradient(circle at 35% 26%, #fff8d8 0 18%, transparent 20%),
|
filter: drop-shadow(0 2px 3px rgba(145, 91, 0, 0.18));
|
||||||
linear-gradient(145deg, #ffd963, #f0a516);
|
|
||||||
box-shadow: inset 0 -2px 0 rgba(133, 85, 0, 0.16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.package-button strong {
|
.package-button strong {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow-wrap: anywhere;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
text-overflow: ellipsis;
|
text-align: center;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.package-button span {
|
.package-button span {
|
||||||
@ -470,9 +471,10 @@ button:disabled {
|
|||||||
|
|
||||||
.package-button small {
|
.package-button small {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
min-height: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #b7791f;
|
color: #b7791f;
|
||||||
font-size: 11px;
|
font-size: 10px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -480,27 +482,35 @@ button:disabled {
|
|||||||
|
|
||||||
.channel-list {
|
.channel-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-button {
|
.channel-button {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 42px minmax(0, 1fr) auto;
|
grid-template-columns: minmax(0, 1fr);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
justify-items: center;
|
||||||
|
gap: 6px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 62px;
|
min-height: 104px;
|
||||||
border: 1px solid var(--line);
|
border: 1px solid var(--line);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 10px;
|
padding: 10px 6px;
|
||||||
background: var(--surface-soft);
|
background: var(--surface-soft);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-button.usdt {
|
.channel-button.usdt {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
grid-template-columns: 36px minmax(0, 1fr) auto;
|
||||||
|
justify-items: stretch;
|
||||||
|
min-height: 68px;
|
||||||
|
padding: 10px 12px;
|
||||||
border-color: rgba(245, 189, 65, 0.7);
|
border-color: rgba(245, 189, 65, 0.7);
|
||||||
background: linear-gradient(180deg, #fffaf0, #fff);
|
background: linear-gradient(180deg, #fffaf0, #fff);
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-button.active {
|
.channel-button.active {
|
||||||
@ -520,11 +530,20 @@ button:disabled {
|
|||||||
|
|
||||||
.channel-copy h4 {
|
.channel-copy h4 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow-wrap: anywhere;
|
||||||
font-size: 15px;
|
font-size: 12px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
text-overflow: ellipsis;
|
line-height: 1.15;
|
||||||
white-space: nowrap;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-button.usdt .channel-copy {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-button.usdt .channel-copy h4 {
|
||||||
|
font-size: 15px;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-copy p {
|
.channel-copy p {
|
||||||
@ -550,6 +569,14 @@ button:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[dir="rtl"] .channel-button {
|
[dir="rtl"] .channel-button {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .channel-button.usdt {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .channel-button.usdt .channel-copy h4 {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -765,7 +792,23 @@ button:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 360px) {
|
@media (max-width: 360px) {
|
||||||
.package-grid {
|
.package-grid,
|
||||||
grid-template-columns: 1fr;
|
.channel-list {
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-button {
|
||||||
|
min-height: 90px;
|
||||||
|
padding: 8px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-button strong,
|
||||||
|
.channel-copy h4 {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-badge {
|
||||||
|
padding-inline: 5px;
|
||||||
|
font-size: 9px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user