/** * 门户客户服务(若依公开接口)- 在线留言、联系信息 */ import { nextTick } from 'vue' import i18n from '../i18n' function ui(key, fallback = '') { const v = i18n.global.t(key) return v && v !== key ? v : fallback } function escapeHtml(text) { if (text == null || text === '') { return '' } return String(text) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, ''') } /** * 获取联系信息列表 * @returns {Promise} */ export async function fetchContactList() { const base = (import.meta.env.VITE_SITE_API_BASE || '/site').replace(/\/$/, '') const res = await fetch(`${base}/contact/list`, { credentials: 'omit', cache: 'no-store' }) if (!res.ok) { throw new Error(`HTTP ${res.status}`) } const body = await res.json() if (body.code !== 200) { throw new Error(body.msg || '接口返回异常') } return Array.isArray(body.data) ? body.data : [] } /** * 提交在线留言 * @param {Object} data { messageName, messagePhone, messageEmail, messageContent } * @returns {Promise} */ export async function submitMessage(data) { const base = (import.meta.env.VITE_SITE_API_BASE || '/site').replace(/\/$/, '') const inquiryPayload = { inquiryName: data?.messageName || '', inquiryPhone: data?.messagePhone || '', inquiryProduct: data?.messageEmail || '', inquiryMessage: data?.messageContent || '' } const res = await fetch(`${base}/product/inquiry`, { method: 'POST', credentials: 'omit', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(inquiryPayload) }) if (!res.ok) { throw new Error(`HTTP ${res.status}`) } return await res.json() } /** * 注入联系信息并初始化留言表单 */ export async function injectContactAndInitForms() { await injectContactInfo() initMessageForm() } * 注入目标:联系我们页面的联系信息展示区域 */ export async function injectContactInfo() { const contactHost = document.querySelector( '.contact-info-container, .info-list, .contact-list, .contact-way-list' ) if (!contactHost) { return } contactHost.innerHTML = '' const contacts = await fetchContactList() if (!contacts || !contacts.length) { return } const contactHtml = contacts.map(contact => { const iconHtml = contact.contactIcon ? `` : '' const value = escapeHtml(contact.contactValue || '') // 电话类型可点击 const isPhone = contact.contactType === 'phone' const displayValue = isPhone ? `${value}` : value return `
${iconHtml ? `
${iconHtml}
` : ''}
${escapeHtml(contact.contactLabel || '')}: ${displayValue}
` }).join('') contactHost.innerHTML = contactHtml } /** * 初始化留言表单 * 给留言表单绑定提交事件 */ export function initMessageForm() { const form = resolveMessageForm() if (!form) { return } if (form.dataset.huayangBoundMessage === '1') { return } form.dataset.huayangBoundMessage = '1' const submitHandler = async (event) => { event.preventDefault() const data = { messageName: pickFormValue(form, ['name', 'messageName'], ['姓名', '联系人']), messagePhone: pickFormValue(form, ['phone', 'messagePhone'], ['电话', '手机', '联系方式']), messageEmail: pickFormValue(form, ['email', 'messageEmail'], ['邮箱', 'email']), messageContent: pickFormValue(form, ['message', 'messageContent'], ['留言', '内容', '需求']) } if (!data.messageName || !data.messagePhone || !data.messageContent) { alert(ui('ui.form.contact_required')) return } try { const result = await submitMessage(data) if (result.code === 200) { alert(ui('ui.status.submit_ok_message')) form.reset() } else { alert(result.msg || ui('ui.status.submit_fail_retry')) } } catch (error) { alert(ui('ui.status.submit_fail_retry')) } } form.addEventListener('submit', submitHandler) const submitBtn = form.querySelector('.e_formBtn-16, .e_formBtn-96, .btn-primary') submitBtn?.addEventListener('click', submitHandler) } function resolveMessageForm() { const explicit = document.querySelector('.message-form, #messageForm') if (explicit) return explicit const isContactPage = window.location.search.includes('page=contact') || window.location.pathname.toLowerCase().includes('contact') if (!isContactPage) return null return document.querySelector('.e_form-10, form.e_form-10, form.e_form-94') } function pickFormValue(form, nameCandidates, placeholderCandidates) { const byName = nameCandidates .map((name) => form.querySelector(`[name="${name}"]`)) .find(Boolean) if (byName?.value) return String(byName.value).trim() const controls = Array.from(form.querySelectorAll('input, textarea, select')) for (const control of controls) { const hint = `${control.placeholder || ''}${control.getAttribute('name') || ''}`.toLowerCase() if (placeholderCandidates.some((keyword) => hint.includes(String(keyword).toLowerCase()))) { return String(control.value || '').trim() } } return '' }