(() => { const $ = (sel) => document.querySelector(sel); const rechargeOptionListEl = $('#rechargeOptionList') || $('#planList'); const estimateBoxEl = $('#estimateBox'); const resultBoxEl = $('#orderResultBox'); const holderNameEl = $('#holderName'); const customInitialBalanceEl = $('#customInitialBalance') || $('#initialBalance'); const customRechargeBoxEl = $('#customRechargeBox'); const submitBtn = $('#submitOrderBtn'); const HOLDER_NAME_PATTERN = /^[A-Za-z][A-Za-z .,'()&@/_\-+]*$/; const state = { rechargeOptions: [5, 10, 15, 20], selectedAmount: 5, customMode: false }; if (!rechargeOptionListEl || !estimateBoxEl || !resultBoxEl || !holderNameEl || !customInitialBalanceEl || !submitBtn) { console.error('[ic-card-order] Missing required DOM nodes', { rechargeOptionListEl: !!rechargeOptionListEl, estimateBoxEl: !!estimateBoxEl, resultBoxEl: !!resultBoxEl, holderNameEl: !!holderNameEl, customInitialBalanceEl: !!customInitialBalanceEl, customRechargeBoxEl: !!customRechargeBoxEl, submitBtn: !!submitBtn }); return; } const api = { async request(url, opts = {}) { const res = await fetch(url, opts); const data = await res.json().catch(() => ({})); if (!res.ok || data.ok === false) { throw new Error(data.error || res.statusText || '请求失败'); } return data; }, fetchConfig() { return api.request('/api/public/ic-cards/config'); }, createOrder(payload) { return api.request('/api/public/ic-cards/orders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); } }; const escapeHtml = (value) => String(value == null ? '' : value) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); const getInitialBalance = () => { if (state.customMode) { return Math.max(1, Number(customInitialBalanceEl.value || 0) || 0); } return Math.max(1, Number(state.selectedAmount || 0) || 0); }; const renderRechargeOptions = () => { const options = Array.isArray(state.rechargeOptions) && state.rechargeOptions.length ? state.rechargeOptions : [5, 10, 15, 20]; rechargeOptionListEl.innerHTML = options.map((amount) => ` `).join('') + ` `; if (customRechargeBoxEl) { customRechargeBoxEl.classList.toggle('is-active', !!state.customMode); } rechargeOptionListEl.querySelectorAll('[data-amount]').forEach((button) => { button.addEventListener('click', () => { state.customMode = false; state.selectedAmount = Number(button.getAttribute('data-amount')) || 5; customInitialBalanceEl.disabled = true; renderRechargeOptions(); renderEstimate(); }); }); const customBtn = rechargeOptionListEl.querySelector('[data-custom="true"]'); if (customBtn) { customBtn.addEventListener('click', () => { state.customMode = true; customInitialBalanceEl.disabled = false; customInitialBalanceEl.focus(); if (!customInitialBalanceEl.value) customInitialBalanceEl.value = '25'; renderRechargeOptions(); renderEstimate(); }); } }; const syncLegacyDom = () => { const holderPhoneEl = $('#holderPhone'); const orderNoteEl = $('#orderNote'); if (holderPhoneEl) { holderPhoneEl.disabled = true; holderPhoneEl.value = ''; holderPhoneEl.placeholder = '已停用'; holderPhoneEl.style.display = 'none'; } if (orderNoteEl) { orderNoteEl.disabled = true; orderNoteEl.value = ''; orderNoteEl.placeholder = '已停用'; orderNoteEl.style.display = 'none'; } const createTypeSelect = $('#createType'); if (createTypeSelect) { createTypeSelect.disabled = true; createTypeSelect.style.display = 'none'; } }; const validateHolderName = (value) => { const holderName = String(value || '').trim(); if (!holderName) return '请输入持卡人姓名'; if (holderName.length > 24) return '持卡人姓名不能超过 24 个字符'; if (!HOLDER_NAME_PATTERN.test(holderName)) return '持卡人姓名仅支持英文与常用符号'; return ''; }; const validateInitialBalance = () => { const initialBalance = getInitialBalance(); if (!Number.isFinite(initialBalance) || initialBalance < 1) { return '首次充值金额必须大于 0'; } return ''; }; const renderEstimate = () => { const initialBalance = getInitialBalance(); if (!Number.isFinite(initialBalance) || initialBalance < 1) { estimateBoxEl.innerHTML = '
请选择有效的首次充值金额。
提交后将在此显示卡号、凭证码和领卡提示。
'; return; } const isDomain = location.hostname.includes('fse-media.group'); const voucherCode = data.code || data.voucher_code || data.order_code || '---'; const cardStatus = String(data.card?.status || data.status || '').trim().toLowerCase(); const lookupKey = (cardStatus === 'pending_pickup') ? voucherCode : (data.card?.card_id || data.card_id || voucherCode); const searchHref = isDomain ? `https://ticket.fse-media.group/ic-card/search?q=${encodeURIComponent(lookupKey)}` : `/ic-card-search.html?q=${encodeURIComponent(lookupKey)}`; const detailHref = isDomain ? `https://ticket.fse-media.group/ic/${encodeURIComponent(lookupKey)}` : `/ic/${encodeURIComponent(lookupKey)}`; const shownCardId = data.display_card_id || data.card?.display_card_id || data.card_id || '---'; const amount = Number(data.amount ?? data.card?.purchase_amount ?? data.card?.balance ?? getInitialBalance()) || getInitialBalance(); resultBoxEl.className = ''; resultBoxEl.innerHTML = `购卡信息已生成。请保存卡号与凭证码,前往站内办理领卡或后续状态查询。
${escapeHtml(error.message || String(error))}
配置加载失败。