You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

50 lines
4.0 KiB

/* ---------- 添加关联客户(票04 客户信息区联调:类型筛选/搜索/联系人级联/角色/主要) ---------- */
let _custPicked = null;
async function dlgAddCustomer() {
_custPicked = null;
openDlg('添加关联客户', `
${fld('客户类型(筛选)', `<select name="customerType"><option value="">全部客户类型</option>${dictOpts('customer_type')}</select>`)}
${fld('关联客户 *', `<div style="display:flex;gap:6px"><input name="custKw" placeholder="输入客户名关键字" style="flex:1"><button type="button" onclick="doCustSearch()">搜索</button></div>
<div id="custResult" style="max-height:160px;overflow:auto;margin-top:6px"></div>
<div id="custPicked" class="hint">未选择客户</div>`)}
${fld('客户联系人(选客户后级联)', `<select name="customerContactId" id="custContactSel"><option value="">—先选客户—</option></select>`)}
${fld('客户角色 *', `<select name="customerRole"><option value="">—必选—</option>${dictOpts('customer_role')}</select>`)}
${fld('是否主要客户 *', '<select name="isPrimaryIntended"><option value="0">否</option><option value="1">是</option></select>')}
<div id="addCustErr"></div>
<div class="hint">类型/角色下拉取自 dict enabled-list(customer_type/customer_role);搜索走 POST /api/opportunity/customer/search;联系人级联走 GET /api/opportunity/customer/contacts?customerId=(A4 前为降级 stub,返回空属正常);提交走 POST /api/opportunity/customer/add</div>`,
[{ t: '确定关联', cls: 'ok', fn: doAddCustomer }]);
}
async function doCustSearch() {
const box = document.getElementById('custResult');
box.innerHTML = '搜索中…';
const d = await tryApi('customer/search', () => api('POST', '/api/opportunity/customer/search',
{ form: { oppId: S.oppId, keyword: v('custKw') || '', pageNum: 1, pageSize: 10 } }));
const rows = (d && (d.content || d.records)) || [];
box.innerHTML = rows.map(c =>
`<div class="kv" style="cursor:pointer;padding:4px 6px" onclick='pickCust(${JSON.stringify(String(c.customerId))},${JSON.stringify(String(c.customerName || ''))})'>· ${esc(c.customerName || c.customerId)} <span class="hint">id=${esc(c.customerId)}</span></div>`).join('')
|| '<div class="empty">无匹配客户</div>';
}
async function pickCust(cid, cname) {
_custPicked = { customerId: cid, customerName: cname };
document.getElementById('custPicked').innerHTML = `已选:<b>${esc(cname)}</b>(id=${esc(cid)}`;
// 级联刷新客户联系人(切换客户 → 重新拉取 → 清空重选)
const sel = document.getElementById('custContactSel');
sel.innerHTML = '<option value="">加载中…</option>';
const contacts = await tryApi('customer/contacts', () => api('GET', '/api/opportunity/customer/contacts', { params: { customerId: cid } }), true) || [];
sel.innerHTML = '<option value="">(可空)</option>' + contacts.map(ct =>
`<option value="${esc(ct.contactId)}">${esc(ct.name)}${ct.company ? '(' + esc(ct.company) + ')' : ''}</option>`).join('')
+ (contacts.length ? '' : '<!-- stub 空 -->');
if (!contacts.length) sel.insertAdjacentHTML('beforeend', '<option value="" disabled>(A4 前 stub 无联系人,级联已触发)</option>');
}
async function doAddCustomer() {
const err = document.getElementById('addCustErr');
if (!_custPicked) { err.innerHTML = '<div class="errbox">请先搜索并选择关联客户</div>'; return; }
if (!v('customerRole')) { err.innerHTML = '<div class="errbox">客户角色必选</div>'; return; }
const form = { oppId: S.oppId, customerId: _custPicked.customerId,
customerNameSnapshot: _custPicked.customerName, customerRole: v('customerRole'),
isPrimaryIntended: v('isPrimaryIntended') };
const ok = await okApi('customer/add', () => api('POST', '/api/opportunity/customer/add', { form }));
if (ok) { toast('关联客户成功', 'ok'); closeDlg(); loadSub('customer'); }
}
/* ---------- 新建商机(flat create;D-14 后六必填=名称/来源/招标形式/省/市/属地) ---------- */