window.ContactsPage = (function() { 'use strict'; let currentPage = 1, pageSize = 20; let companyMap = {}; async function render() { await loadCompanies(); return buildPage(); } async function loadCompanies() { try { const res = await API.get('/companies?page=1&page_size=500'); const items = (res.data && res.data.items) || []; companyMap = {}; items.forEach(c => { companyMap[c.id] = c.company_name; }); } catch (e) { /* ignore */ } } async function buildPage(companyId, keyword) { let params = `?page=${currentPage}&page_size=${pageSize}`; if (companyId) params += `&company_id=${encodeURIComponent(companyId)}`; if (keyword) params += `&keyword=${encodeURIComponent(keyword)}`; let html = ''; try { const res = await API.get('/contacts' + params); const data = res.data || {}; const items = data.items || []; if (items.length === 0) { html += UI.emptyState('暂无联系人数据'); } else { html += '
'; html += ''; html += ''; items.forEach(c => { html += ``; }); html += '
姓名职位部门客户手机权力态度关键人操作
${esc(c.name)} ${esc(c.title)} ${esc(c.department)} ${esc(c.company_name || companyMap[c.company_id] || c.company_id)} ${esc(c.mobile)} ${UI.badge(UI.POWER_MAP[c.power_level] || c.power_level, c.power_level==='A'?'decision':c.power_level==='B'?'warning':'normal')} ${UI.badge(UI.ATTITUDE_MAP[c.attitude] || c.attitude, c.attitude==='supporter'?'success':c.attitude==='opponent'?'danger':'normal')} ${c.is_key_person ? UI.badge('关键', 'key') : '-'}
'; html += UI.renderPagination(data.total, data.page, data.page_size, 'ContactsPage.goPage'); } } catch (e) { html += `
加载失败: ${esc(e.message)}
`; } bindEvents(); return html; } function bindEvents() { setTimeout(() => { const cf = document.getElementById('contact-company-filter'); const ks = document.getElementById('contact-search'); if (cf) cf.onchange = () => { currentPage = 1; refresh(); }; if (ks) ks.oninput = debounce(() => { currentPage = 1; refresh(); }, 400); const addBtn = document.getElementById('btn-add-contact'); if (addBtn) addBtn.onclick = () => showEdit(null); }, 0); } async function refresh() { const cf = document.getElementById('contact-company-filter'); const ks = document.getElementById('contact-search'); const html = await buildPage(cf ? cf.value : '', ks ? ks.value : ''); document.getElementById('content-area').innerHTML = html; } async function goPage(p) { currentPage = p; await refresh(); } function showEdit(id) { const isNew = !id; let formHtml = '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; formHtml += '
'; UI.showModal(isNew ? '新建联系人' : '编辑联系人', formHtml, async () => { if (isNew) { await API.post('/contacts', { company_id: elVal('f-company_id'), name: elVal('f-name'), title: elVal('f-title'), department: elVal('f-department'), mobile: elVal('f-mobile') || null, mobile_2: elVal('f-mobile_2') || null, email: elVal('f-email') || null, wechat: elVal('f-wechat') || null, gender: elVal('f-gender') || null, birthday: elVal('f-birthday') || null, power_level: elVal('f-power_level'), attitude: elVal('f-attitude'), is_key_person: elVal('f-is_key_person') === '1', contact_frequency: elVal('f-contact_frequency') || null, personal_interests: elVal('f-personal_interests') || null, family_info: elVal('f-family_info') || null, remark: elVal('f-remark') || null, }); UI.toast('联系人创建成功', 'success'); } UI.closeModal(); Router.navigate(Router.getCurrentHash()); }); } async function doDelete(id) { if (!await UI.confirm('确定删除此联系人?')) return; try { await API.delete(`/contacts/${id}`); UI.toast('联系人已删除', 'success'); Router.navigate(Router.getCurrentHash()); } catch (e) { UI.toast(e.message, 'error'); } } function elVal(id) { const el = document.getElementById(id); return el ? el.value : ''; } function esc(s) { return (s || '').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } function escAttr(s) { return (s || '').replace(/&/g,'&').replace(/"/g,'"'); } function debounce(fn, ms) { let t; return (...args) => { clearTimeout(t); t = setTimeout(() => fn(...args), ms); }; } return { render, goPage, showEdit, doDelete }; })();