强制用户输入联系方式
This commit is contained in:
parent
25c5e65f39
commit
909b70e63d
@ -535,6 +535,12 @@ var default_api = 'https://api.global-interaction.com/';
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
updateContact: function (payload) {
|
||||
return request('/api/v1/users/me/contact-info', {
|
||||
method: 'POST',
|
||||
body: payload || {},
|
||||
});
|
||||
},
|
||||
resolveDisplayUserID: function (displayUserID) {
|
||||
return request(
|
||||
'/api/v1/users/by-display-user-id/' +
|
||||
|
||||
@ -670,5 +670,20 @@
|
||||
"lalu_site.contactLead": "أرسل أسئلة المنتج أو الحساب أو التعاون إلى البريد الرسمي.",
|
||||
"lalu_site.emailSupport": "مراسلة الدعم",
|
||||
"lalu_site.footerCompany": "Global Interactive Technology Co., Limited",
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn"
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn",
|
||||
"contact_card.open": "تعديل جهة اتصال WhatsApp",
|
||||
"contact_card.title": "WhatsApp",
|
||||
"contact_card.add_whatsapp": "إضافة WhatsApp",
|
||||
"contact_card.add": "إضافة",
|
||||
"contact_card.edit": "تعديل",
|
||||
"contact_card.close": "إغلاق",
|
||||
"contact_card.sheet_title": "جهة اتصال WhatsApp",
|
||||
"contact_card.field_label": "رقم أو رابط WhatsApp",
|
||||
"contact_card.placeholder": "+6512345678",
|
||||
"contact_card.save": "حفظ",
|
||||
"contact_card.saving": "جار الحفظ...",
|
||||
"contact_card.required": "أدخل جهة اتصال WhatsApp.",
|
||||
"contact_card.api_unavailable": "واجهة جهة الاتصال غير متاحة.",
|
||||
"contact_card.saved": "تم الحفظ.",
|
||||
"contact_card.save_failed": "فشل الحفظ."
|
||||
}
|
||||
|
||||
@ -676,5 +676,20 @@
|
||||
"lalu_site.contactLead": "Send product, account, or cooperation questions to the official email address.",
|
||||
"lalu_site.emailSupport": "Email support",
|
||||
"lalu_site.footerCompany": "Global Interactive Technology Co., Limited",
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn"
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn",
|
||||
"contact_card.open": "Edit WhatsApp contact",
|
||||
"contact_card.title": "WhatsApp",
|
||||
"contact_card.add_whatsapp": "Add WhatsApp",
|
||||
"contact_card.add": "Add",
|
||||
"contact_card.edit": "Edit",
|
||||
"contact_card.close": "Close",
|
||||
"contact_card.sheet_title": "WhatsApp Contact",
|
||||
"contact_card.field_label": "WhatsApp phone or link",
|
||||
"contact_card.placeholder": "+6512345678",
|
||||
"contact_card.save": "Save",
|
||||
"contact_card.saving": "Saving...",
|
||||
"contact_card.required": "Enter WhatsApp contact.",
|
||||
"contact_card.api_unavailable": "Contact API unavailable.",
|
||||
"contact_card.saved": "Saved.",
|
||||
"contact_card.save_failed": "Save failed."
|
||||
}
|
||||
|
||||
@ -670,5 +670,20 @@
|
||||
"lalu_site.contactLead": "Envía preguntas de producto, cuenta o cooperación al email oficial.",
|
||||
"lalu_site.emailSupport": "Enviar email a soporte",
|
||||
"lalu_site.footerCompany": "Global Interactive Technology Co., Limited",
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn"
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn",
|
||||
"contact_card.open": "Editar contacto de WhatsApp",
|
||||
"contact_card.title": "WhatsApp",
|
||||
"contact_card.add_whatsapp": "Agregar WhatsApp",
|
||||
"contact_card.add": "Agregar",
|
||||
"contact_card.edit": "Editar",
|
||||
"contact_card.close": "Cerrar",
|
||||
"contact_card.sheet_title": "Contacto de WhatsApp",
|
||||
"contact_card.field_label": "Teléfono o enlace de WhatsApp",
|
||||
"contact_card.placeholder": "+6512345678",
|
||||
"contact_card.save": "Guardar",
|
||||
"contact_card.saving": "Guardando...",
|
||||
"contact_card.required": "Ingresa el contacto de WhatsApp.",
|
||||
"contact_card.api_unavailable": "API de contacto no disponible.",
|
||||
"contact_card.saved": "Guardado.",
|
||||
"contact_card.save_failed": "No se pudo guardar."
|
||||
}
|
||||
|
||||
@ -598,5 +598,20 @@
|
||||
"achievement.notCollected": "Belum dikoleksi",
|
||||
"achievement.collected": "Dikoleksi",
|
||||
"achievement.collectedWithDate": "Dikoleksi pada {date}",
|
||||
"achievement.ownerCount": "Hanya {count} orang yang memilikinya"
|
||||
"achievement.ownerCount": "Hanya {count} orang yang memilikinya",
|
||||
"contact_card.open": "Ubah kontak WhatsApp",
|
||||
"contact_card.title": "WhatsApp",
|
||||
"contact_card.add_whatsapp": "Tambahkan WhatsApp",
|
||||
"contact_card.add": "Tambah",
|
||||
"contact_card.edit": "Ubah",
|
||||
"contact_card.close": "Tutup",
|
||||
"contact_card.sheet_title": "Kontak WhatsApp",
|
||||
"contact_card.field_label": "Nomor atau link WhatsApp",
|
||||
"contact_card.placeholder": "+6512345678",
|
||||
"contact_card.save": "Simpan",
|
||||
"contact_card.saving": "Menyimpan...",
|
||||
"contact_card.required": "Masukkan kontak WhatsApp.",
|
||||
"contact_card.api_unavailable": "API kontak tidak tersedia.",
|
||||
"contact_card.saved": "Tersimpan.",
|
||||
"contact_card.save_failed": "Gagal menyimpan."
|
||||
}
|
||||
|
||||
@ -637,5 +637,20 @@
|
||||
"lalu_site.contactLead": "Ürün, hesap veya iş birliği sorularını resmi e-posta adresine gönder.",
|
||||
"lalu_site.emailSupport": "Desteğe e-posta gönder",
|
||||
"lalu_site.footerCompany": "Global Interactive Technology Co., Limited",
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn"
|
||||
"lalu_site.footerContact": "postmaster@haiyinet.com.cn",
|
||||
"contact_card.open": "WhatsApp iletişimini düzenle",
|
||||
"contact_card.title": "WhatsApp",
|
||||
"contact_card.add_whatsapp": "WhatsApp ekle",
|
||||
"contact_card.add": "Ekle",
|
||||
"contact_card.edit": "Düzenle",
|
||||
"contact_card.close": "Kapat",
|
||||
"contact_card.sheet_title": "WhatsApp İletişimi",
|
||||
"contact_card.field_label": "WhatsApp telefonu veya bağlantısı",
|
||||
"contact_card.placeholder": "+6512345678",
|
||||
"contact_card.save": "Kaydet",
|
||||
"contact_card.saving": "Kaydediliyor...",
|
||||
"contact_card.required": "WhatsApp iletişimini gir.",
|
||||
"contact_card.api_unavailable": "İletişim API kullanılamıyor.",
|
||||
"contact_card.saved": "Kaydedildi.",
|
||||
"contact_card.save_failed": "Kaydetme başarısız."
|
||||
}
|
||||
|
||||
@ -604,5 +604,20 @@
|
||||
"achievement.notCollected": "未收集",
|
||||
"achievement.collected": "已收集",
|
||||
"achievement.collectedWithDate": "{date} 已收集",
|
||||
"achievement.ownerCount": "仅 {count} 人拥有"
|
||||
"achievement.ownerCount": "仅 {count} 人拥有",
|
||||
"contact_card.open": "修改 WhatsApp 联系方式",
|
||||
"contact_card.title": "WhatsApp",
|
||||
"contact_card.add_whatsapp": "添加 WhatsApp",
|
||||
"contact_card.add": "添加",
|
||||
"contact_card.edit": "修改",
|
||||
"contact_card.close": "关闭",
|
||||
"contact_card.sheet_title": "WhatsApp 联系方式",
|
||||
"contact_card.field_label": "WhatsApp 手机号或链接",
|
||||
"contact_card.placeholder": "+6512345678",
|
||||
"contact_card.save": "保存",
|
||||
"contact_card.saving": "保存中...",
|
||||
"contact_card.required": "请输入 WhatsApp 联系方式。",
|
||||
"contact_card.api_unavailable": "联系方式接口不可用。",
|
||||
"contact_card.saved": "已保存。",
|
||||
"contact_card.save_failed": "保存失败。"
|
||||
}
|
||||
|
||||
@ -113,6 +113,8 @@
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<div data-contact-card></div>
|
||||
|
||||
<section class="card salary-card">
|
||||
<div class="salary-head">
|
||||
<div class="salary-title">
|
||||
@ -450,6 +452,7 @@
|
||||
<script src="../../common/params.js?v=20260603-agency-center"></script>
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/i18n.js"></script>
|
||||
<script src="../common/contact-card.js?v=20260629-user-contact"></script>
|
||||
<script src="./script.js?v=20260605-agency-real-policy"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -77,6 +77,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div data-contact-card></div>
|
||||
|
||||
<section class="card salary-card">
|
||||
<div class="salary-head">
|
||||
<h2 data-i18n="bd_center.salary">Salary</h2>
|
||||
@ -357,6 +359,7 @@
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/i18n.js"></script>
|
||||
<script src="../../common/api.js?v=20260604-bd-center"></script>
|
||||
<script src="../common/contact-card.js?v=20260629-user-contact"></script>
|
||||
<script src="./script.js?v=20260604-bd-center-real-skeleton"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -74,6 +74,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div data-contact-card></div>
|
||||
|
||||
<section class="card balance-card">
|
||||
<div class="balance-head">
|
||||
<div>
|
||||
@ -434,6 +436,7 @@
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/api.js?v=20260604-coinseller-records"></script>
|
||||
<script src="../../common/i18n.js?v=20260604-coinseller"></script>
|
||||
<script src="../common/contact-card.js?v=20260629-user-contact"></script>
|
||||
<script src="./script.js?v=20260604-record-user-profile"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -218,6 +218,129 @@ input:focus-visible {
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.contact-card {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.contact-card .contact-row {
|
||||
display: grid;
|
||||
grid-template-columns: 46px minmax(0, 1fr) auto;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 70px;
|
||||
padding: 14px 18px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.contact-card .contact-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background: rgba(49, 198, 168, 0.14);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.contact-card .contact-icon svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.contact-card .contact-icon path,
|
||||
.contact-card .contact-icon circle {
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2.2;
|
||||
}
|
||||
|
||||
.contact-card .contact-copy {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.contact-card .contact-title {
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
font-weight: 900;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.contact-card .contact-value {
|
||||
overflow: hidden;
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
line-height: 1.25;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.contact-card .contact-action {
|
||||
color: var(--primary-deep);
|
||||
font-size: 13px;
|
||||
font-weight: 950;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.contact-sheet .contact-field {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.contact-sheet .contact-field span {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.contact-sheet .contact-input {
|
||||
width: 100%;
|
||||
height: 52px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 0 14px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.contact-sheet .contact-input::placeholder {
|
||||
color: rgba(141, 135, 154, 0.72);
|
||||
}
|
||||
|
||||
.contact-sheet .contact-save {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 52px;
|
||||
margin-top: 14px;
|
||||
border-radius: 8px;
|
||||
background: var(--button);
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.contact-sheet .contact-save:disabled {
|
||||
background: var(--button-disabled);
|
||||
}
|
||||
|
||||
.contact-sheet .contact-status {
|
||||
margin-top: 10px;
|
||||
color: var(--danger);
|
||||
font-size: 13px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.profile-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
215
gonghui/common/contact-card.js
Normal file
215
gonghui/common/contact-card.js
Normal file
@ -0,0 +1,215 @@
|
||||
(function () {
|
||||
var mounted = false;
|
||||
|
||||
function t(key, fallback) {
|
||||
return window.HyAppI18n && window.HyAppI18n.t
|
||||
? window.HyAppI18n.t(key, fallback)
|
||||
: fallback;
|
||||
}
|
||||
|
||||
function toast(message) {
|
||||
if (window.HyAppToast && window.HyAppToast.show) {
|
||||
window.HyAppToast.show(message);
|
||||
}
|
||||
}
|
||||
|
||||
function contactFrom(value) {
|
||||
if (!value || typeof value !== 'object') return '';
|
||||
var source = value.profile || value.user || value;
|
||||
var keys = [
|
||||
'contact_info',
|
||||
'contactInfo',
|
||||
'whatsapp_phone',
|
||||
'whatsappPhone',
|
||||
'contact',
|
||||
];
|
||||
for (var i = 0; i < keys.length; i += 1) {
|
||||
var text = String(source[keys[i]] || '').trim();
|
||||
if (text) return text;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function render(mount) {
|
||||
mount.innerHTML =
|
||||
'<section class="card contact-card">' +
|
||||
' <button class="contact-row" type="button" data-contact-open data-i18n-aria="contact_card.open" aria-label="Edit WhatsApp contact">' +
|
||||
' <span class="contact-icon" aria-hidden="true">' +
|
||||
' <svg viewBox="0 0 24 24"><path d="M7 18.5 4 20l.8-3.5A8 8 0 1 1 12 20a8.8 8.8 0 0 1-5-1.5Z"/><path d="M9 8.8c.2 3 2.2 5 5.2 5.4l1-1.6c.2-.3.6-.4.9-.2l1.3.7"/><path d="M8.4 7.4 9 8.8"/></svg>' +
|
||||
' </span>' +
|
||||
' <span class="contact-copy">' +
|
||||
' <span class="contact-title" data-i18n="contact_card.title">WhatsApp</span>' +
|
||||
' <span class="contact-value" data-contact-value data-i18n="contact_card.add_whatsapp">Add WhatsApp</span>' +
|
||||
' </span>' +
|
||||
' <span class="contact-action" data-contact-action data-i18n="contact_card.add">Add</span>' +
|
||||
' </button>' +
|
||||
'</section>' +
|
||||
'<div class="sheet-modal contact-modal" data-contact-modal hidden aria-hidden="true">' +
|
||||
' <button class="modal-backdrop" type="button" data-contact-close data-i18n-aria="contact_card.close" aria-label="Close"></button>' +
|
||||
' <section class="bottom-sheet contact-sheet" role="dialog" aria-modal="true" aria-labelledby="contactSheetTitle">' +
|
||||
' <div class="sheet-head">' +
|
||||
' <h2 id="contactSheetTitle" data-i18n="contact_card.sheet_title">WhatsApp Contact</h2>' +
|
||||
' <button class="sheet-close" type="button" data-contact-close data-i18n-aria="contact_card.close" aria-label="Close">×</button>' +
|
||||
' </div>' +
|
||||
' <form data-contact-form>' +
|
||||
' <label class="contact-field">' +
|
||||
' <span data-i18n="contact_card.field_label">WhatsApp phone or link</span>' +
|
||||
' <input class="contact-input" data-contact-input type="text" inputmode="text" autocomplete="off" placeholder="+6512345678" data-i18n-placeholder="contact_card.placeholder" />' +
|
||||
' </label>' +
|
||||
' <button class="contact-save" type="submit" data-contact-save data-i18n="contact_card.save">Save</button>' +
|
||||
' <div class="contact-status" data-contact-status hidden></div>' +
|
||||
' </form>' +
|
||||
' </section>' +
|
||||
'</div>';
|
||||
if (window.HyAppI18n && window.HyAppI18n.apply) {
|
||||
window.HyAppI18n.apply(mount);
|
||||
}
|
||||
}
|
||||
|
||||
function setModalOpen(root, open) {
|
||||
var modal = root.querySelector('[data-contact-modal]');
|
||||
if (!modal) return;
|
||||
modal.hidden = !open;
|
||||
modal.setAttribute('aria-hidden', open ? 'false' : 'true');
|
||||
document.body.classList.toggle('modal-open', open);
|
||||
if (open) {
|
||||
var input = root.querySelector('[data-contact-input]');
|
||||
if (input) input.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function setContact(root, value) {
|
||||
var contact = String(value || '').trim();
|
||||
var valueNode = root.querySelector('[data-contact-value]');
|
||||
var actionNode = root.querySelector('[data-contact-action]');
|
||||
if (valueNode) {
|
||||
valueNode.textContent =
|
||||
contact || t('contact_card.add_whatsapp', 'Add WhatsApp');
|
||||
if (contact) {
|
||||
valueNode.removeAttribute('data-i18n');
|
||||
} else {
|
||||
valueNode.setAttribute('data-i18n', 'contact_card.add_whatsapp');
|
||||
}
|
||||
}
|
||||
if (actionNode) {
|
||||
actionNode.textContent = contact
|
||||
? t('contact_card.edit', 'Edit')
|
||||
: t('contact_card.add', 'Add');
|
||||
if (contact) {
|
||||
actionNode.removeAttribute('data-i18n');
|
||||
} else {
|
||||
actionNode.setAttribute('data-i18n', 'contact_card.add');
|
||||
}
|
||||
}
|
||||
root.dataset.contactValue = contact;
|
||||
}
|
||||
|
||||
function setStatus(root, message) {
|
||||
var status = root.querySelector('[data-contact-status]');
|
||||
if (!status) return;
|
||||
status.textContent = message || '';
|
||||
status.hidden = !message;
|
||||
}
|
||||
|
||||
function setSaving(root, saving) {
|
||||
var button = root.querySelector('[data-contact-save]');
|
||||
if (!button) return;
|
||||
button.disabled = saving;
|
||||
button.textContent = saving
|
||||
? t('contact_card.saving', 'Saving...')
|
||||
: t('contact_card.save', 'Save');
|
||||
}
|
||||
|
||||
function loadCurrentContact(root) {
|
||||
var api = window.HyAppAPI && window.HyAppAPI.user;
|
||||
if (!api || !api.me) return;
|
||||
api.me()
|
||||
.then(function (profile) {
|
||||
setContact(root, contactFrom(profile));
|
||||
})
|
||||
.catch(function () {
|
||||
setContact(root, '');
|
||||
});
|
||||
}
|
||||
|
||||
function bind(root) {
|
||||
root.addEventListener('click', function (event) {
|
||||
if (event.target.closest('[data-contact-open]')) {
|
||||
var input = root.querySelector('[data-contact-input]');
|
||||
if (input) input.value = root.dataset.contactValue || '';
|
||||
setStatus(root, '');
|
||||
setModalOpen(root, true);
|
||||
return;
|
||||
}
|
||||
if (event.target.closest('[data-contact-close]')) {
|
||||
setModalOpen(root, false);
|
||||
}
|
||||
});
|
||||
|
||||
var form = root.querySelector('[data-contact-form]');
|
||||
if (!form) return;
|
||||
form.addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
var api = window.HyAppAPI && window.HyAppAPI.user;
|
||||
var input = root.querySelector('[data-contact-input]');
|
||||
var contact = input ? String(input.value || '').trim() : '';
|
||||
if (!contact) {
|
||||
setStatus(
|
||||
root,
|
||||
t('contact_card.required', 'Enter WhatsApp contact.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!api || !api.updateContact) {
|
||||
setStatus(
|
||||
root,
|
||||
t('contact_card.api_unavailable', 'Contact API unavailable.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 联系方式是用户主资料,不依赖当前中心页身份;保存成功后用后端返回值刷新展示,避免本地输入和服务端裁剪值不一致。
|
||||
setSaving(root, true);
|
||||
setStatus(root, '');
|
||||
api.updateContact({ contact_info: contact })
|
||||
.then(function (response) {
|
||||
setContact(root, contactFrom(response) || contact);
|
||||
setModalOpen(root, false);
|
||||
toast(t('contact_card.saved', 'Saved.'));
|
||||
})
|
||||
.catch(function () {
|
||||
setStatus(
|
||||
root,
|
||||
t('contact_card.save_failed', 'Save failed.')
|
||||
);
|
||||
})
|
||||
.finally(function () {
|
||||
setSaving(root, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (mounted) return;
|
||||
var mounts = document.querySelectorAll('[data-contact-card]');
|
||||
if (!mounts.length) return;
|
||||
mounted = true;
|
||||
mounts.forEach(function (mount) {
|
||||
render(mount);
|
||||
bind(mount);
|
||||
loadCurrentContact(mount);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('hyapp:i18n-ready', function () {
|
||||
document.querySelectorAll('[data-contact-card]').forEach(function (root) {
|
||||
setContact(root, root.dataset.contactValue || '');
|
||||
});
|
||||
});
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@ -75,6 +75,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div data-contact-card></div>
|
||||
|
||||
<section class="card income-card">
|
||||
<div class="income-head">
|
||||
<h2 data-i18n="host_center.available_salary">
|
||||
@ -270,6 +272,7 @@
|
||||
<script src="../../common/params.js?v=20260602-api"></script>
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/i18n.js?v=20260604-diamonds-label"></script>
|
||||
<script src="../common/contact-card.js?v=20260629-user-contact"></script>
|
||||
<script src="./script.js?v=20260604-no-zero-scroll"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -80,6 +80,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div data-contact-card></div>
|
||||
|
||||
<section class="card salary-card">
|
||||
<div class="salary-head">
|
||||
<h2 data-i18n="superadmin_center.salary">Salary</h2>
|
||||
@ -310,6 +312,7 @@
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/api.js?v=20260604-superadmin-api"></script>
|
||||
<script src="../../common/i18n.js?v=20260604"></script>
|
||||
<script src="../common/contact-card.js?v=20260629-user-contact"></script>
|
||||
<script src="./script.js?v=20260604-api"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -368,6 +368,70 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="contact-modal"
|
||||
id="contactModal"
|
||||
hidden
|
||||
aria-hidden="true"
|
||||
>
|
||||
<button
|
||||
class="contact-backdrop"
|
||||
id="contactBackdrop"
|
||||
type="button"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="contact_card.close"
|
||||
></button>
|
||||
<section
|
||||
class="contact-dialog"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="contactTitle"
|
||||
>
|
||||
<div class="contact-head">
|
||||
<h2 id="contactTitle" data-i18n="contact_card.sheet_title">
|
||||
WhatsApp Contact
|
||||
</h2>
|
||||
<button
|
||||
class="contact-close"
|
||||
id="contactCloseButton"
|
||||
type="button"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="contact_card.close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<form class="contact-form" id="contactForm">
|
||||
<label class="field contact-field">
|
||||
<span data-i18n="contact_card.field_label"
|
||||
>WhatsApp phone or link</span
|
||||
>
|
||||
<input
|
||||
id="contactInput"
|
||||
type="text"
|
||||
inputmode="text"
|
||||
autocomplete="off"
|
||||
placeholder="+6512345678"
|
||||
data-i18n-placeholder="contact_card.placeholder"
|
||||
/>
|
||||
</label>
|
||||
<div
|
||||
class="contact-status"
|
||||
id="contactStatus"
|
||||
hidden
|
||||
></div>
|
||||
<button
|
||||
class="primary-button contact-save-button"
|
||||
id="saveContactButton"
|
||||
type="submit"
|
||||
data-i18n="contact_card.save"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="home-indicator" aria-hidden="true"></div>
|
||||
</div>
|
||||
|
||||
@ -376,6 +440,6 @@
|
||||
<script src="../../common/i18n.js?v=20260602"></script>
|
||||
<script src="../../common/params.js?v=20260604"></script>
|
||||
<script src="../../common/api.js?v=20260604-salary-wallet"></script>
|
||||
<script src="./script.js?v=20260604-bd-wallet"></script>
|
||||
<script src="./script.js?v=20260629-contact-required"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -14,7 +14,9 @@
|
||||
selectedPayee: null,
|
||||
isSearching: false,
|
||||
isSaving: false,
|
||||
isSavingContact: false,
|
||||
isSubmitting: false,
|
||||
contactInfo: '',
|
||||
historyItems: [],
|
||||
transferRateTiers: [],
|
||||
};
|
||||
@ -123,6 +125,12 @@
|
||||
: null;
|
||||
}
|
||||
|
||||
function userApi() {
|
||||
if (window.HyAppAPI && window.HyAppAPI.user)
|
||||
return window.HyAppAPI.user;
|
||||
return window.HyApp && window.HyApp.api ? window.HyApp.api.user : null;
|
||||
}
|
||||
|
||||
function commandId(prefix) {
|
||||
return prefix + '-' + Date.now() + '-' + Math.random().toString(16).slice(2);
|
||||
}
|
||||
@ -246,6 +254,20 @@
|
||||
return '';
|
||||
}
|
||||
|
||||
function contactFrom(value) {
|
||||
if (!value || typeof value !== 'object') return '';
|
||||
var source = value.profile || value.user || value;
|
||||
return String(
|
||||
firstValue(source, [
|
||||
'contact_info',
|
||||
'contactInfo',
|
||||
'whatsapp_phone',
|
||||
'whatsappPhone',
|
||||
'contact',
|
||||
]) || ''
|
||||
).trim();
|
||||
}
|
||||
|
||||
function timeLabelFromMS(value) {
|
||||
var number = Number(value || 0);
|
||||
if (!Number.isFinite(number) || number <= 0) return '';
|
||||
@ -498,6 +520,10 @@
|
||||
button.disabled = disabled;
|
||||
}
|
||||
|
||||
function needsContactForSubmit() {
|
||||
return currentMode === 'exchange' || currentMode === 'transfer';
|
||||
}
|
||||
|
||||
function normalizeAmount(event) {
|
||||
var input = event.target;
|
||||
var raw = String(input.value || '').replace(/[^\d.]/g, '');
|
||||
@ -543,6 +569,75 @@
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
|
||||
function setContactStatus(message) {
|
||||
var node = $('contactStatus');
|
||||
node.textContent = message || '';
|
||||
node.hidden = !message;
|
||||
}
|
||||
|
||||
function setContactSaving(saving) {
|
||||
state.isSavingContact = saving;
|
||||
$('saveContactButton').disabled = saving;
|
||||
$('saveContactButton').textContent = saving
|
||||
? t('contact_card.saving', 'Saving...')
|
||||
: t('contact_card.save', 'Save');
|
||||
}
|
||||
|
||||
function openContactModal() {
|
||||
$('contactInput').value = state.contactInfo || '';
|
||||
setContactStatus('');
|
||||
$('contactModal').hidden = false;
|
||||
$('contactModal').setAttribute('aria-hidden', 'false');
|
||||
document.body.classList.add('modal-open');
|
||||
window.setTimeout(function () {
|
||||
$('contactInput').focus();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function closeContactModal() {
|
||||
$('contactModal').hidden = true;
|
||||
$('contactModal').setAttribute('aria-hidden', 'true');
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
|
||||
function saveContact(event) {
|
||||
if (event) event.preventDefault();
|
||||
var contact = String($('contactInput').value || '').trim();
|
||||
if (!contact) {
|
||||
setContactStatus(
|
||||
t('contact_card.required', 'Enter WhatsApp contact.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
var apiClient = userApi();
|
||||
if (!apiClient || !apiClient.updateContact) {
|
||||
setContactStatus(
|
||||
t('contact_card.api_unavailable', 'Contact API unavailable.')
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Exchange/Transfer 需要运营联系方式用于后台跟进;联系方式是用户主资料,保存成功后才允许继续提交工资兑换或转账请求。
|
||||
setContactSaving(true);
|
||||
setContactStatus('');
|
||||
apiClient
|
||||
.updateContact({ contact_info: contact })
|
||||
.then(function (response) {
|
||||
state.contactInfo = contactFrom(response) || contact;
|
||||
closeContactModal();
|
||||
updateSubmit();
|
||||
toast(t('contact_card.saved', 'Saved.'));
|
||||
})
|
||||
.catch(function () {
|
||||
setContactStatus(
|
||||
t('contact_card.save_failed', 'Save failed.')
|
||||
);
|
||||
})
|
||||
.finally(function () {
|
||||
setContactSaving(false);
|
||||
});
|
||||
}
|
||||
|
||||
function saveAddress() {
|
||||
var address = String($('trc20Address').value || '').trim();
|
||||
if (!isValidTrc20(address)) {
|
||||
@ -681,6 +776,10 @@
|
||||
toast(error);
|
||||
return;
|
||||
}
|
||||
if (needsContactForSubmit() && !state.contactInfo) {
|
||||
openContactModal();
|
||||
return;
|
||||
}
|
||||
if (!isMock && currentMode === 'withdraw') {
|
||||
toast(
|
||||
t(
|
||||
@ -824,6 +923,9 @@
|
||||
bindTap('salaryHistoryButton', openHistory);
|
||||
bindTap('salaryHistoryBackdrop', closeHistory);
|
||||
bindTap('salaryHistoryCloseButton', closeHistory);
|
||||
bindTap('contactBackdrop', closeContactModal);
|
||||
bindTap('contactCloseButton', closeContactModal);
|
||||
$('contactForm').addEventListener('submit', saveContact);
|
||||
}
|
||||
|
||||
function renderStaticDynamicText() {
|
||||
@ -832,6 +934,9 @@
|
||||
'1$ = {amount} golds'
|
||||
).replace('{amount}', EXCHANGE_RATE.toLocaleString('en-US'));
|
||||
if (!$('salaryHistoryModal').hidden) renderHistory();
|
||||
if (!$('contactModal').hidden && !state.isSavingContact) {
|
||||
$('saveContactButton').textContent = t('contact_card.save', 'Save');
|
||||
}
|
||||
updateSubmit();
|
||||
renderPayee();
|
||||
}
|
||||
@ -843,6 +948,7 @@
|
||||
renderStaticDynamicText();
|
||||
loadOverview();
|
||||
loadPaymentInfo();
|
||||
loadContactInfo();
|
||||
if (window.HyAppBridge) {
|
||||
window.HyAppBridge.ready({
|
||||
page: 'withdraw-exchange',
|
||||
@ -909,6 +1015,30 @@
|
||||
renderPaymentInfo();
|
||||
}
|
||||
|
||||
function loadContactInfo() {
|
||||
if (isMock) {
|
||||
state.contactInfo = String(params.get('contact') || '').trim();
|
||||
updateSubmit();
|
||||
return;
|
||||
}
|
||||
var apiClient = userApi();
|
||||
if (!apiClient || !apiClient.me) {
|
||||
state.contactInfo = '';
|
||||
updateSubmit();
|
||||
return;
|
||||
}
|
||||
apiClient
|
||||
.me()
|
||||
.then(function (profile) {
|
||||
state.contactInfo = contactFrom(profile);
|
||||
updateSubmit();
|
||||
})
|
||||
.catch(function () {
|
||||
state.contactInfo = '';
|
||||
updateSubmit();
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
window.addEventListener('hyapp:i18n-ready', renderStaticDynamicText);
|
||||
})();
|
||||
|
||||
@ -655,6 +655,21 @@ input {
|
||||
background: rgba(14, 19, 24, 0.44);
|
||||
}
|
||||
|
||||
.contact-modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 70;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.contact-backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(14, 19, 24, 0.44);
|
||||
}
|
||||
|
||||
.salary-history-dialog {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@ -669,6 +684,16 @@ input {
|
||||
box-shadow: 0 -14px 36px rgba(26, 35, 44, 0.16);
|
||||
}
|
||||
|
||||
.contact-dialog {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: min(100%, 430px);
|
||||
padding: 18px 18px calc(20px + env(safe-area-inset-bottom));
|
||||
border-radius: 18px 18px 0 0;
|
||||
background: #fff;
|
||||
box-shadow: 0 -14px 36px rgba(26, 35, 44, 0.16);
|
||||
}
|
||||
|
||||
.salary-history-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -677,6 +702,14 @@ input {
|
||||
padding: 18px 18px 12px;
|
||||
}
|
||||
|
||||
.contact-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.salary-history-head h2 {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
@ -689,6 +722,18 @@ input {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.contact-head h2 {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
color: #24282e;
|
||||
font-size: 18px;
|
||||
font-weight: 950;
|
||||
line-height: 1.2;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.salary-history-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -703,6 +748,44 @@ input {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.contact-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
flex: 0 0 34px;
|
||||
border-radius: 50%;
|
||||
background: #f3f5f5;
|
||||
color: #676b72;
|
||||
font-size: 28px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.contact-form {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.contact-field input {
|
||||
min-height: 52px;
|
||||
padding: 0 14px;
|
||||
border-radius: 8px;
|
||||
background: var(--hy-theme-surface-soft, #fdfaff);
|
||||
font-size: 15px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.contact-status {
|
||||
color: var(--hy-theme-danger, #d95d72);
|
||||
font-size: 13px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.contact-save-button {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.salary-history-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user