window.CompaniesPage = (function() {
'use strict';
let currentPage = 1, pageSize = 20;
async function render() {
return buildPage();
}
async function buildPage(keyword, tier, status) {
let params = `?page=${currentPage}&page_size=${pageSize}`;
if (keyword) params += `&keyword=${encodeURIComponent(keyword)}`;
if (tier) params += `&tier=${encodeURIComponent(tier)}`;
if (status) params += `&status=${encodeURIComponent(status)}`;
let html = '
';
try {
const res = await API.get('/companies' + params);
const data = res.data || {};
const items = data.items || [];
if (items.length === 0) {
html += UI.emptyState('暂无客户数据');
} else {
html += '';
html += '| 客户名称 | 行业 | 级别 | 状态 | 地区 | 销售负责人 | 最后联系 | 操作 | ';
html += '
';
items.forEach(c => {
html += `
${esc(c.company_name)}${c.short_name ? ' ' + esc(c.short_name) + '' : ''} |
${esc(c.industry)}${c.industry_detail ? '/' + esc(c.industry_detail) : ''} |
${UI.tierBadge(c.customer_tier)} |
${UI.statusBadge(c.customer_status)} |
${esc(c.province)} ${esc(c.city)} |
${esc(c.sales_owner_name || c.sales_owner_id)} |
${UI.formatDate(c.last_contact_date)} |
|
`;
});
html += '
';
html += UI.renderPagination(data.total, data.page, data.page_size, 'CompaniesPage.goPage');
}
} catch (e) {
html += `加载失败: ${esc(e.message)}
`;
}
bindEvents();
return html;
}
function bindEvents() {
setTimeout(() => {
const searchEl = document.getElementById('company-search');
const tierEl = document.getElementById('company-tier-filter');
const statusEl = document.getElementById('company-status-filter');
const addBtn = document.getElementById('btn-add-company');
const doSearch = () => {
currentPage = 1;
const kw = searchEl ? searchEl.value : '';
const t = tierEl ? tierEl.value : '';
const s = statusEl ? statusEl.value : '';
buildPage(kw, t, s).then(h => { document.getElementById('content-area').innerHTML = h; });
};
if (searchEl) { searchEl.oninput = debounce(doSearch, 400); }
if (tierEl) tierEl.onchange = doSearch;
if (statusEl) statusEl.onchange = doSearch;
if (addBtn) addBtn.onclick = () => showEdit(null);
}, 0);
}
async function goPage(p) {
currentPage = p;
const kw = document.getElementById('company-search')?.value || '';
const t = document.getElementById('company-tier-filter')?.value || '';
const s = document.getElementById('company-status-filter')?.value || '';
const html = await buildPage(kw, t, s);
document.getElementById('content-area').innerHTML = html;
}
function showEdit(id) {
const isNew = !id;
let formHtml = '';
if (isNew) {
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
formHtml += '';
}
UI.showModal(isNew ? '新建客户' : '编辑客户', formHtml, async () => {
if (isNew) {
const body = {
company_name: elVal('f-company_name'),
short_name: elVal('f-short_name') || null,
industry: elVal('f-industry'),
industry_detail: elVal('f-industry_detail') || null,
province: elVal('f-province'),
city: elVal('f-city'),
address: elVal('f-address') || null,
customer_tier: elVal('f-customer_tier'),
customer_status: elVal('f-customer_status'),
customer_source: elVal('f-customer_source') || null,
priority_level: parseInt(elVal('f-priority_level')) || null,
employee_count: parseInt(elVal('f-employee_count')) || null,
annual_revenue: parseFloat(elVal('f-annual_revenue')) || null,
website: elVal('f-website') || null,
stock_code: elVal('f-stock_code') || null,
is_listed: elVal('f-is_listed') === '1' ? true : elVal('f-is_listed') === '0' ? false : null,
sales_owner_id: parseInt(elVal('f-sales_owner_id')),
first_contact_date: elVal('f-first_contact_date') || null,
remark: elVal('f-remark') || null,
};
await API.post('/companies', body);
UI.toast('客户创建成功', 'success');
}
UI.closeModal();
Router.navigate(Router.getCurrentHash());
});
}
async function showSummary(id) {
try {
const res = await API.get(`/companies/${id}/summary`);
const d = res.data;
let html = `客户: ${esc(d.company.company_name)} (${UI.tierBadge(d.company.customer_tier)} ${UI.statusBadge(d.company.customer_status)})
`;
html += `行业: ${esc(d.company.industry)} | ${esc(d.company.province)} ${esc(d.company.city)}
`;
html += `联系人: ${d.contacts.length} 个 | 组织节点: ${d.org_node_count} 个 | 决策关系: ${d.decision_node_count} 个
`;
if (d.recent_follows.length > 0) {
html += '近期沟通
';
d.recent_follows.forEach(f => {
html += `- [${f.record_date}][${f.team_type}] ${f.record_type}: ${esc((f.content||'').slice(0,60))}...
`;
});
html += '
';
}
UI.showModal('客户摘要', html, async () => { UI.closeModal(); });
} catch (e) {
UI.toast(e.message, 'error');
}
}
async function doDelete(id) {
const ok = await UI.confirm('确定删除此客户?');
if (!ok) return;
try {
await API.delete(`/companies/${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, showSummary, doDelete };
})();