Files
superlink/static/js/person.js
T

649 lines
34 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* person.js - 人员数据管理逻辑(列表+筛选+分页 / 新增编辑弹窗 / 人脉 / 导入导出 / 详情)
* v1.0.18:
* - 新增「人脉」入口:与本人有交集(同事/老乡/校友)的人员列表,含亲密度百分比;点姓名反查详情
* - 新增/编辑表单分两个 Tab:基本信息 | 工作履历
* - 家乡/工作所在地:省-市两级联动(不细化区县),存储为「省-市」短结构(如 湖南衡阳 / 新疆乌鲁木齐)
* - 国籍为中国/中国香港/中国澳门/中国台湾时,家乡置灰不可填写
*/
$(function () {
renderShell('人员数据', '数据管理 / 人员数据');
renderPage();
initPage('person', function (user) {
if (!checkPagePermission('person')) return;
loadList(1);
});
var currentPage = 1;
/** 渲染页面内容(工具栏+表格+分页) */
function renderPage() {
$('#page-content').html(
'<div class="card">' +
' <div class="toolbar">' +
' <input type="text" data-filter="keyword" placeholder="姓名/证件号/手机/邮箱关键词">' +
' <select data-filter="gender"><option value="">全部性别</option>' +
' <option value="男">男</option><option value="女">女</option>' +
' <option value="其他">其他</option><option value="保密">保密</option></select>' +
' <input type="text" data-filter="nationality" placeholder="国籍">' +
' <input type="text" data-filter="work_location" placeholder="工作所在地">' +
' <button class="btn btn-primary" id="btn-search">搜索</button>' +
' <button class="btn" id="btn-reset">重置</button>' +
' <span class="spacer"></span>' +
' <button class="btn btn-success" id="btn-add">+ 新增</button>' +
' <button class="btn btn-warning" id="btn-import">导入CSV</button>' +
' <button class="btn" id="btn-export">导出</button>' +
' </div>' +
' <div class="table-wrap"><table class="grid">' +
' <thead><tr><th><input type="checkbox" id="check-all"></th><th>ID</th><th>姓名</th><th>性别</th><th>国籍</th><th>工作所在地</th><th>家乡</th><th>学历</th><th>手机</th><th>邮箱</th><th>创建时间</th><th>操作</th></tr></thead>' +
' <tbody id="person-tbody"></tbody>' +
' </table></div>' +
' <div class="pagination" id="pagination"></div>' +
'</div>'
);
$('#check-all').on('change', function () { $('.row-check').prop('checked', this.checked); });
}
function loadList(page) {
currentPage = page;
var params = buildFilterParam();
params.page = page;
params.limit = PAGE_SIZE;
httpGet('person/list.php', params).then(function (data) {
var rows = data.list || [];
var html = '';
rows.forEach(function (r) {
html += '<tr>' +
'<td><input type="checkbox" class="row-check" value="' + r.id + '"></td>' +
'<td>' + r.id + '</td>' +
'<td>' + escHtml(r.full_name) + '</td>' +
'<td>' + escHtml(r.gender || '-') + '</td>' +
'<td>' + escHtml(r.nationality || '-') + '</td>' +
'<td>' + escHtml(r.work_location || '-') + '</td>' +
'<td>' + escHtml(r.hometown || '-') + '</td>' +
'<td>' + escHtml(r.education || '-') + '</td>' +
'<td>' + escHtml(r.phone || '-') + '</td>' +
'<td title="' + escHtml(r.email || '') + '">' + escHtml((r.email || '-').substring(0, 30)) + '</td>' +
'<td>' + fmtDate(r.created_at) + '</td>' +
'<td class="ops">' +
' <a onclick="viewPerson(' + r.id + ')">详情</a>' +
' <a onclick="viewResume(' + r.id + ')">履历</a>' +
' <a onclick="viewConnections(' + r.id + ')">人脉</a>' +
' <a onclick="editPerson(' + r.id + ')">编辑</a>' +
'</td></tr>';
});
if (!rows.length) {
html = '<tr><td colspan="12" class="empty-tip" style="padding:40px 0;">暂无数据</td></tr>';
}
$('#person-tbody').html(html);
renderPagination($('#pagination'), data, loadList);
});
}
$('#btn-search').on('click', function () { loadList(1); });
$('#btn-reset').on('click', function () {
$('.toolbar [data-filter]').val('');
loadList(1);
});
/* ============================================================
* 新增/编辑弹窗:Tab = 基本信息 | 工作履历
* ============================================================ */
var companyOptions = []; // 任职公司下拉选项
function loadCompanyOptions() {
if (companyOptions.length) return $.Deferred().resolve(companyOptions).promise();
return httpGet('person/company_options.php', { limit: 500 }).then(function (d) {
companyOptions = d.list || [];
return companyOptions;
}).catch(function () { companyOptions = []; return companyOptions; });
}
/** 手机号输入后自动识别归属地(录入手机号码时自动识别:国内-省-市;港澳台-中国香港/澳门/台湾;海外-国籍) */
function bindPhoneGeo($phoneInput, $geoHint) {
var timer = null;
$phoneInput.on('blur', function () {
var val = $.trim($(this).val());
if (!val) { $geoHint.text('').hide(); return; }
clearTimeout(timer);
timer = setTimeout(function () {
httpGet('common/phone_geo.php', { phone: val }).then(function (d) {
if (d && d.label && d.label !== '未知') {
$geoHint.text('归属地:' + d.label).show();
} else {
$geoHint.text('归属地:未能识别').show();
}
}).catch(function () { $geoHint.text('').hide(); });
}, 300);
});
}
/** 名称去行政区后缀:湖南省->湖南,新疆维吾尔自治区->新疆,北京市->北京,石家庄市->石家庄 */
function stripAreaSuffix(name) {
return String(name || '')
.replace(/(维吾尔|壮族|回族)?自治区$/, '')
.replace(/省$/, '')
.replace(/特别行政区$/, '')
.replace(/市$/, '');
}
/** 省-市两级联动下拉(不细化区县;值存储为短结构,如 湖南衡阳 / 新疆乌鲁木齐 / 北京) */
function areaSelectsHtml(target, value) {
return '<div class="area-cascade" data-target="' + target + '" style="display:flex;gap:6px;">' +
'<select class="area-prov" style="flex:1;min-width:0;"><option value="">省</option></select>' +
'<select class="area-city" style="flex:1;min-width:0;"><option value="">市</option></select>' +
'</div>' +
'<input type="hidden" name="' + target + '" value="' + escHtml(value || '') + '">';
}
/** 构建省/市两级联动:填充选项并按已有值回选(兼容旧格式:湖南衡阳 / 湖南省衡阳市 / 北京市-东城区) */
function initAreaCascade(areas) {
var provMap = {}; // code -> name
var childMap = {}; // parent_code -> [{code,name}]
(areas || []).forEach(function (a) {
if (!a.parent_code) {
provMap[a.code] = a.name;
} else {
(childMap[a.parent_code] = childMap[a.parent_code] || []).push({ code: a.code, name: a.name });
}
});
var provCodes = Object.keys(provMap);
function fillProv($box) {
var html = '<option value="">省</option>';
provCodes.forEach(function (code) {
html += '<option value="' + code + '">' + escHtml(provMap[code]) + '</option>';
});
$box.find('.area-prov').html(html);
}
function fillCity($box, provCode) {
var html = '<option value="">市</option>';
(childMap[provCode] || []).forEach(function (c) {
html += '<option value="' + c.code + '">' + escHtml(c.name) + '</option>';
});
$box.find('.area-city').html(html);
}
function combine($box) {
var target = $box.data('target');
var provName = $box.find('.area-prov option:selected').text();
var cityName = $box.find('.area-city option:selected').text();
var provShort = provName ? stripAreaSuffix(provName) : '';
var cityShort = cityName ? stripAreaSuffix(cityName) : '';
var val = provShort;
// 直辖市(省/市同名)只存省
if (cityShort && cityShort !== provShort) val += cityShort;
$box.closest('.form-item').find('input[name="' + target + '"]').val(val);
}
/** 按短名匹配省(如 湖南 / 新疆 / 北京) */
function matchProv(shortName) {
var sorted = provCodes.slice().sort(function (a, b) { return b.length - a.length; });
for (var i = 0; i < sorted.length; i++) {
if (stripAreaSuffix(provMap[sorted[i]]) === shortName) return sorted[i];
}
return '';
}
/** 按短名匹配市 */
function matchCity(provCode, shortName) {
var list = childMap[provCode] || [];
for (var i = 0; i < list.length; i++) {
if (stripAreaSuffix(list[i].name) === shortName) return list[i].code;
}
return '';
}
/** 解析已有值 -> [省短名, 市短名](兼容 湖南衡阳 / 湖南省衡阳市 / 北京市-东城区 等格式) */
function parseValue(value) {
var v = String(value || '').trim();
if (!v) return ['', ''];
if (v.indexOf('-') >= 0) {
var parts = v.split('-');
return [stripAreaSuffix(parts[0]), parts[1] ? stripAreaSuffix(parts[1]) : ''];
}
// 无分隔符:最长省名前缀匹配
var sorted = provCodes.slice().sort(function (a, b) { return b.length - a.length; });
for (var i = 0; i < sorted.length; i++) {
var pShort = stripAreaSuffix(provMap[sorted[i]]);
if (pShort && v.indexOf(pShort) === 0) {
var rest = v.substring(pShort.length);
return [pShort, rest];
}
}
return ['', v];
}
$('.area-cascade').each(function () {
var $box = $(this);
var target = $box.data('target');
var current = $box.closest('.form-item').find('input[name="' + target + '"]').val() || '';
var parsed = parseValue(current);
var provShort = parsed[0];
var cityShort = parsed[1];
fillProv($box);
var provCode = provShort ? matchProv(provShort) : '';
if (!provCode) return;
$box.find('.area-prov').val(provCode);
fillCity($box, provCode);
// 直辖市:市=省本身
if (cityShort === provShort) {
var muniCode = matchCity(provCode, cityShort);
if (muniCode) $box.find('.area-city').val(muniCode);
return;
}
var cityCode = cityShort ? matchCity(provCode, cityShort) : '';
if (cityCode) $box.find('.area-city').val(cityCode);
});
// 联动事件
$('.area-cascade').off('change.area').on('change.area', '.area-prov', function () {
var $box = $(this).closest('.area-cascade');
fillCity($box, $(this).val());
combine($box);
});
$('.area-cascade').off('change.areaCity').on('change.areaCity', '.area-city', function () {
combine($(this).closest('.area-cascade'));
});
}
/** 国籍是否为中国大陆/港澳台(此时家乡置灰不可填) */
function isCnNationality(n) {
var v = String(n || '').trim();
return v === '中国' || v === '中国香港' || v === '中国澳门' || v === '中国台湾';
}
/** 工作履历行模板 */
function expRowHtml(e) {
e = e || {};
var empty = function (v) { return (v === null || v === undefined) ? '' : v; };
var opts = '<option value="">请选择公司</option>';
companyOptions.forEach(function (c) {
opts += '<option value="' + c.id + '"' + (String(c.id) === String(e.company_id) ? ' selected' : '') + '>' + escHtml(c.name) + '</option>';
});
return '<div class="exp-row">' +
'<select name="exp-company" style="width:180px;">' + opts + '</select>' +
'<input type="text" name="exp-position" placeholder="职位" value="' + escHtml(empty(e.position)) + '">' +
'<input type="text" name="exp-department" placeholder="部门" value="' + escHtml(empty(e.department)) + '">' +
'<input type="text" name="exp-level" placeholder="职级" value="' + escHtml(empty(e.job_level)) + '">' +
'<input type="date" name="exp-start" title="入职日期" value="' + escHtml(empty(e.start_date)) + '">' +
'<input type="date" name="exp-end" title="离职日期" value="' + escHtml(empty(e.end_date)) + '">' +
'<label title="当前在职" style="font-size:12px;color:#5a6472;white-space:nowrap;"><input type="checkbox" name="exp-current"' + (e.is_current ? ' checked' : '') + '> 在职</label>' +
'<button type="button" class="btn btn-sm btn-danger" onclick="$(this).closest(\'.exp-row\').remove()">删除</button>' +
'</div>';
}
function openForm(person, accounts, phone, email, experiences) {
var isEdit = !!person;
var p = person || {};
var pPhone = phone || '';
var pEmail = email || '';
// Tab1 基本信息
var baseHtml =
'<div class="form-grid">' +
' <div class="form-item"><label>姓名<span class="req">*</span></label><input type="text" name="full_name" value="' + escHtml(p.full_name) + '"></div>' +
' <div class="form-item"><label>性别</label><select name="gender">' +
' <option value="保密"' + (!p.gender || p.gender === '保密' ? ' selected' : '') + '>保密</option>' +
' <option value="男"' + (p.gender === '男' ? ' selected' : '') + '>男</option>' +
' <option value="女"' + (p.gender === '女' ? ' selected' : '') + '>女</option>' +
' <option value="其他"' + (p.gender === '其他' ? ' selected' : '') + '>其他</option></select></div>' +
' <div class="form-item"><label>国籍</label><input type="text" name="nationality" id="person-nationality" value="' + escHtml(p.nationality) + '" list="person-country-list" placeholder="选择或输入">' +
' <datalist id="person-country-list"></datalist></div>' +
' <div class="form-item"><label>证件类型</label><input type="text" name="id_type" value="' + escHtml(p.id_type) + '"></div>' +
' <div class="form-item"><label>证件号码</label><input type="text" name="id_number" value="' + escHtml(p.id_number) + '"></div>' +
' <div class="form-item"><label>学历</label><input type="text" name="education" value="' + escHtml(p.education) + '"></div>' +
' <div class="form-item"><label>毕业院校</label><input type="text" name="graduated_from" value="' + escHtml(p.graduated_from) + '"></div>' +
' <div class="form-item"><label>家乡</label><div class="hometown-box">' + areaSelectsHtml('hometown', p.hometown) + '</div></div>' +
' <div class="form-item"><label>工作所在地</label><div class="workloc-box">' + areaSelectsHtml('work_location', p.work_location) + '</div></div>' +
' <div class="form-item"><label>手机</label>' +
' <div><input type="text" name="phone" id="person-phone" value="' + escHtml(pPhone) + '" placeholder="常用手机号">' +
' <div class="geo-hint" id="person-phone-geo" style="font-size:12px;color:#2f8f46;margin-top:4px;display:none;"></div></div></div>' +
' <div class="form-item"><label>邮箱</label><input type="text" name="email" id="person-email" value="' + escHtml(pEmail) + '" placeholder="常用邮箱"></div>' +
' <div class="form-item"><label>来源渠道</label><select name="source_channel" id="person-source-channel"><option value="">-</option></select></div>' +
' <div class="form-item"><label>来源详情</label><input type="text" name="source_detail" value="' + escHtml(p.source_detail) + '" placeholder="如:华南工博会"></div>' +
'</div>';
// Tab2 工作履历
var expRowsHtml = '';
if (!experiences || !experiences.length) {
expRowsHtml = expRowHtml(null);
} else {
experiences.forEach(function (e) { expRowsHtml += expRowHtml(e); });
}
var expHtml =
'<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">' +
' <b style="font-size:13px;color:#1e2a3a;">工作履历</b>' +
' <button type="button" class="btn btn-sm" id="add-exp-row">+ 添加履历</button>' +
'</div>' +
'<div id="exp-rows">' + expRowsHtml + '</div>';
var content =
'<form id="person-form" style="padding:14px 22px 4px;">' +
' <div class="edit-tabs">' +
' <div class="edit-tabs-head">' +
' <span class="edit-tab active" data-tab="base" onclick="switchPersonTab(this)">基本信息</span>' +
' <span class="edit-tab" data-tab="exp" onclick="switchPersonTab(this)">工作履历</span>' +
' </div>' +
' <div class="edit-tabs-body">' +
' <div class="edit-pane" id="edit-pane-base">' + baseHtml + '</div>' +
' <div class="edit-pane" id="edit-pane-exp" style="display:none;">' + expHtml + '</div>' +
' </div>' +
' </div>' +
'<div class="dialog-footer"><button type="button" class="btn" id="form-cancel">取消</button>' +
'<button type="submit" class="btn btn-primary">保存</button></div>' +
'</form>';
var idx = Dialog.open({
title: isEdit ? '编辑人员' : '新增人员',
area: ['760px', 'auto'],
content: content,
btn: false
});
// 手机号归属地自动识别
bindPhoneGeo($('#person-phone'), $('#person-phone-geo'));
// 录入自动清洗:手机号去所有空格(含中间),邮箱去首尾空格
$('#person-phone').on('input', function () {
var v = cleanPhone($(this).val());
if ($(this).val() !== v) $(this).val(v);
});
$('#person-email').on('blur', function () { $(this).val(cleanEmail($(this).val())); });
// 加载国籍字典 + 行政区划字典(省-市两级) + 来源渠道字典 + 任职公司
httpGet('common/dicts.php', { type: 'all' }).then(function (d) {
var $dl = $('#person-country-list');
var html = '';
(d.countries || []).forEach(function (c) { html += '<option value="' + escHtml(c.name) + '"></option>'; });
$dl.html(html);
// 省-市两级联动
initAreaCascade(d.areas || []);
var $sc = $('#person-source-channel');
var scHtml = '<option value="">-</option>';
var hasCur = false;
(d.source_channels || []).forEach(function (s) {
var sel = (s.name === p.source_channel) ? ' selected' : '';
if (sel) hasCur = true;
scHtml += '<option value="' + escHtml(s.name) + '"' + sel + '>' + escHtml(s.name) + '</option>';
});
if (p.source_channel && !hasCur) {
scHtml += '<option value="' + escHtml(p.source_channel) + '" selected>' + escHtml(p.source_channel) + '(自定义)</option>';
}
$sc.html(scHtml);
// 国籍变化 -> 家乡置灰/可用
function syncHometownDisabled() {
var n = $('#person-nationality').val();
var disabled = isCnNationality(n);
var $box = $('.hometown-box');
$box.find('select, input').prop('disabled', disabled);
$box.toggleClass('area-disabled', disabled);
if (disabled) {
$box.closest('.form-item').find('input[name="hometown"]').val('');
}
}
$('#person-nationality').off('input.home').on('input.home', syncHometownDisabled);
syncHometownDisabled();
}).catch(function () {});
// 任职公司选项
loadCompanyOptions().then(function () {
// 已有行重填公司下拉(若首次加载后追加的选项)
$('#exp-rows .exp-row select[name="exp-company"]').each(function () {
if ($(this).find('option').length <= 1) {
var cur = $(this).data('cur') || '';
var opts = '<option value="">请选择公司</option>';
companyOptions.forEach(function (c) {
opts += '<option value="' + c.id + '"' + (String(c.id) === String(cur) ? ' selected' : '') + '>' + escHtml(c.name) + '</option>';
});
$(this).html(opts);
}
});
});
$('#add-exp-row').on('click', function () { $('#exp-rows').append(expRowHtml(null)); });
$('#form-cancel').on('click', function () { Dialog.close(idx); });
$('#person-form').on('submit', function (e) {
e.preventDefault();
var data = {};
$(this).find('input, select').each(function () {
var name = $(this).attr('name');
if (!name) return;
data[name] = $(this).val();
});
if (!data.full_name) { Dialog.error('姓名为必填项'); return; }
// 联系方式(手机/邮箱,均为常用)
data.phone = cleanPhone(data.phone);
data.email = cleanEmail(data.email);
var contacts = [];
if (data.phone) {
contacts.push({ platform: 'phone', account_id: data.phone, is_primary: 1, is_defult: 1 });
}
if (data.email) {
contacts.push({ platform: 'email', account_id: data.email, is_primary: 1, is_defult: 1 });
}
data.contacts = JSON.stringify(contacts);
delete data.phone;
delete data.email;
// 工作履历(整表替换)
var exps = [];
$('#exp-rows .exp-row').each(function () {
var $r = $(this);
var companyId = $r.find('[name="exp-company"]').val();
if (!companyId) return;
exps.push({
company_id: companyId,
position: $r.find('[name="exp-position"]').val(),
department: $r.find('[name="exp-department"]').val(),
job_level: $r.find('[name="exp-level"]').val(),
start_date: $r.find('[name="exp-start"]').val(),
end_date: $r.find('[name="exp-end"]').val(),
is_current: $r.find('[name="exp-current"]').prop('checked') ? 1 : 0
});
});
data.experiences = JSON.stringify(exps);
if (isEdit) data.id = p.id;
httpPost(isEdit ? 'person/update.php' : 'person/add.php', data).then(function () {
Dialog.success('保存成功', function () {
Dialog.close(idx);
loadList(currentPage);
});
});
});
}
/* ---------- 新增 / 编辑入口 ---------- */
window.addPerson = function () {
openForm(null, [], '', '', []);
};
window.editPerson = function (id) {
httpGet('person/detail.php', { id: id }).then(function (d) {
openForm(d.person, d.accounts || [], d.phone || '', d.email || '', d.experiences || []);
}).catch(function () {
Dialog.alert('加载人员详情失败');
});
};
$('#btn-add').on('click', function () { addPerson(); });
/* ---------- 人员弹窗 Tab 切换 ---------- */
window.switchPersonTab = function (el) {
var $tabs = $(el).closest('.edit-tabs');
$tabs.find('.edit-tab').removeClass('active');
$(el).addClass('active');
$tabs.find('.edit-pane').hide();
$('#edit-pane-' + $(el).data('tab')).show();
};
/* ---------- 导入 ---------- */
$('#btn-import').on('click', function () {
triggerFileInput('.csv', function (file) {
var fd = new FormData();
fd.append('file', file);
httpPost('person/import.php', fd, true).then(function (d) {
Dialog.alert('导入结果:成功 ' + d.inserted + ' 条,失败 ' + d.failed + ' 条', function () {
loadList(1);
});
});
});
});
/* ---------- 导出(仅导出勾选的人员,未勾选弹窗提醒) ---------- */
$('#btn-export').on('click', function () {
var ids = [];
$('.row-check:checked').each(function () { ids.push($(this).val()); });
if (!ids.length) {
layer.alert('请先选择需要导出的人员数据', { icon: 2, title: '提示' });
return;
}
download('person/export.php', { ids: ids.join(',') });
});
window.viewPerson = function (id) {
httpGet('person/detail.php', { id: id }).then(function (d) {
var p = d.person;
var expHtml = '';
(d.experiences || []).forEach(function (e) {
expHtml += '<tr><td>' + escHtml(e.display_name || '-') + '</td><td>' + escHtml(e.position || '-') + '</td>' +
'<td>' + escHtml(e.department || '-') + '</td><td>' + escHtml(e.job_level || '-') + '</td>' +
'<td>' + (e.is_current ? '<span class="tag tag-green">在职</span>' : fmtDate(e.start_date) + ' ~ ' + (e.end_date || '至今')) + '</td></tr>';
});
var html =
'<div style="padding:18px 22px;">' +
' <h3 style="margin-bottom:14px;">' + escHtml(p.full_name) + '</h3>' +
' <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px 24px;font-size:13px;">' +
' <div><b>性别:</b>' + escHtml(p.gender || '-') + '</div>' +
' <div><b>国籍:</b>' + escHtml(p.nationality || '-') + '</div>' +
' <div><b>证件:</b>' + escHtml(p.id_type || '-') + ' / ' + escHtml(p.id_number || '-') + '</div>' +
' <div><b>学历:</b>' + escHtml(p.education || '-') + '</div>' +
' <div><b>毕业院校:</b>' + escHtml(p.graduated_from || '-') + '</div>' +
' <div><b>家乡:</b>' + escHtml(p.hometown || '-') + '</div>' +
' <div><b>工作所在地:</b>' + escHtml(p.work_location || '-') + '</div>' +
' <div><b>来源渠道:</b>' + escHtml(p.source_channel || '-') + '</div>' +
' <div><b>来源详情:</b>' + escHtml(p.source_detail || '-') + '</div>' +
' <div><b>union_id:</b>' + escHtml(p.union_id) + '</div>' +
' </div>' +
' <h4 style="margin:16px 0 8px;">联系方式</h4>' +
' <div style="font-size:13px;"><b>手机:</b>' + escHtml(d.phone || '-') + '</div>' +
' <div style="font-size:13px;margin-top:4px;"><b>邮箱:</b>' + escHtml(d.email || '-') + '</div>' +
' <h4 style="margin:16px 0 8px;">工作履历</h4>' +
' <table class="grid" style="font-size:12px;"><tr><th>公司</th><th>职位</th><th>部门</th><th>级别</th><th>时间</th></tr>' +
(expHtml || '<tr><td colspan="5" style="color:#b6bfcc;text-align:center;">暂无</td></tr>') + '</table>' +
'</div>';
Dialog.open({ title: '人员详情', area: ['760px', 'auto'], content: html, btn: ['关闭'] });
});
}
/* ---------- 人脉弹窗(同事/老乡/校友 + 亲密度) ---------- */
var connPersonId = 0;
window.viewConnections = function (personId) {
connPersonId = personId;
var content =
'<div style="padding:14px 18px 6px;overflow:hidden;height:420px;">' +
' <div style="margin-bottom:10px;font-size:13px;color:#5a6472;">共 <b id="conn-total">0</b> 条人脉(交集:工作履历/家乡/毕业院校)</div>' +
' <div class="table-wrap"><table class="grid" style="font-size:13px;">' +
' <thead><tr><th>姓名</th><th>联系方式</th><th>交集</th><th>亲密度</th></tr></thead>' +
' <tbody id="conn-tbody"></tbody>' +
' </table></div>' +
'</div>';
Dialog.open({ title: '人脉', area: ['760px', 'auto'], content: content, btn: ['关闭'] });
loadConnections();
};
function loadConnections() {
httpGet('person/connections.php', { person_id: connPersonId, limit: 50 }).then(function (data) {
var rows = data.list || [];
$('#conn-total').text(rows.length);
var html = '';
rows.forEach(function (r) {
var tagHtml = (r.tags || []).map(function (t) {
return '<span class="tag">' + escHtml(t) + '</span>';
}).join(' ');
html += '<tr>' +
'<td><a href="javascript:void(0)" class="link" onclick="viewPerson(' + r.id + ')">' + escHtml(r.full_name) + '</a></td>' +
'<td>' + escHtml(r.phone || '-') + '</td>' +
'<td>' + (tagHtml || '-') + '</td>' +
'<td style="white-space:nowrap;">' +
' <span style="color:#2a5298;font-weight:bold;">' + r.intimacy + '%</span>' +
' <span style="display:inline-block;width:70px;height:6px;background:#eef0f4;border-radius:3px;vertical-align:middle;margin-left:6px;overflow:hidden;">' +
' <span style="display:block;height:100%;width:' + r.intimacy + '%;background:#4fa3ff;border-radius:3px;"></span>' +
' </span>' +
'</td>' +
'</tr>';
});
if (!rows.length) {
html = '<tr><td colspan="4" class="empty-tip" style="padding:40px 0;">暂无相关人脉</td></tr>';
}
$('#conn-tbody').html(html);
});
}
/* ---------- 任职履历弹窗(按人员查看任职公司/履历,分页) ---------- */
var compPersonId = 0;
window.viewResume = function (personId) {
compPersonId = personId;
var content =
'<div style="padding:14px 18px 6px;overflow:hidden;height:330px;">' +
' <div class="toolbar" style="margin-bottom:10px;">' +
' <span style="font-size:13px;color:#5a6472;">状态:</span>' +
' <label style="font-size:13px;color:#5a6472;"><input type="checkbox" id="comp-cur" checked> 在岗</label>' +
' <label style="font-size:13px;color:#5a6472;"><input type="checkbox" id="comp-off" checked> 离职</label>' +
' <button class="btn btn-primary btn-sm" id="comp-search">筛选</button>' +
' <button class="btn btn-sm" id="comp-reset">重置</button>' +
' </div>' +
' <div class="table-wrap"><table class="grid" style="font-size:13px;">' +
' <thead><tr><th>公司名称</th><th>部门</th><th>岗位</th><th>职级</th><th>入职日期</th><th>是否在岗</th></tr></thead>' +
' <tbody id="comp-tbody"></tbody>' +
' </table></div>' +
' <div class="pagination" id="comp-pagination"></div>' +
'</div>';
Dialog.open({ title: '工作履历', area: ['720px', 'auto'], content: content, btn: ['关闭'] });
loadCompanies(1);
$('#comp-search').on('click', function () { loadCompanies(1); });
$('#comp-reset').on('click', function () {
$('#comp-cur').prop('checked', true);
$('#comp-off').prop('checked', true);
loadCompanies(1);
});
};
function loadCompanies(page) {
var params = { person_id: compPersonId, page: page, limit: 5 };
var cur = $('#comp-cur').prop('checked');
var off = $('#comp-off').prop('checked');
// 状态筛选:只勾一项则按该项过滤;都不勾视为全部
if (cur && !off) params.is_current = 1;
else if (!cur && off) params.is_current = 0;
httpGet('person/companies.php', params).then(function (data) {
var rows = data.list || [];
var html = '';
rows.forEach(function (r) {
html += '<tr>' +
'<td>' + escHtml(r.company_name) + '</td>' +
'<td>' + escHtml(r.department || '-') + '</td>' +
'<td>' + escHtml(r.position || '-') + '</td>' +
'<td>' + escHtml(r.job_level || '-') + '</td>' +
'<td>' + escHtml(r.start_date || '-') + '</td>' +
'<td>' + (r.is_current ? '<span class="tag tag-green">在岗</span>' : '<span class="tag tag-gray">离岗</span>') + '</td>' +
'</tr>';
});
if (!rows.length) {
html = '<tr><td colspan="6" class="empty-tip" style="padding:30px 0;">暂无任职记录</td></tr>';
}
$('#comp-tbody').html(html);
renderPagination($('#comp-pagination'), data, loadCompanies);
});
}
});