/**
* person.js - 人员数据管理逻辑(列表+筛选+分页 / 新增编辑弹窗 / 导入导出 / 详情)
*/
$(function () {
renderShell('人员数据', '数据管理 / 人员数据');
renderPage();
initPage('person', function (user) {
if (!checkPagePermission('person')) return;
loadList(1);
});
var currentPage = 1;
/** 渲染页面内容(工具栏+表格+分页) */
function renderPage() {
$('#page-content').html(
'
'
);
$('#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 += '' +
' | ' +
'' + r.id + ' | ' +
'' + escHtml(r.full_name) + ' | ' +
'' + escHtml(r.gender || '-') + ' | ' +
'' + escHtml(r.nationality || '-') + ' | ' +
'' + escHtml(r.work_location || '-') + ' | ' +
'' + escHtml(r.hometown || '-') + ' | ' +
'' + escHtml(r.education || '-') + ' | ' +
'' + escHtml(r.phone || '-') + ' | ' +
'' + escHtml((r.email || '-').substring(0, 30)) + ' | ' +
'' + fmtDate(r.created_at) + ' | ' +
'' +
' 详情' +
' 履历' +
' 编辑' +
' |
';
});
if (!rows.length) {
html = '| 暂无数据 |
';
}
$('#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);
});
$('#btn-add').on('click', function () { openForm(null, null, null, null, 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);
});
};
/** 手机号输入后自动识别归属地(录入手机号码时自动识别:国内-国家省-市;港澳台-中国香港/澳门/台湾;海外-国籍) */
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);
});
}
/** 省市区三级联动下拉(数据来自 date_dict_area 字典)
* value 格式:"省-市-区县"(直辖市省略市,如 "北京市-东城区") */
function areaSelectsHtml(target, value) {
return '' +
'' +
'' +
'' +
'
' +
'';
}
/** 构建省/市/区三级联动:填充选项并按已有值回选 */
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 = '';
provCodes.forEach(function (code) {
html += '';
});
$box.find('.area-prov').html(html);
}
function fillCity($box, provCode) {
var html = '';
(childMap[provCode] || []).forEach(function (c) {
html += '';
});
$box.find('.area-city').html(html);
$box.find('.area-dist').html('');
}
function fillDist($box, cityCode) {
var html = '';
(childMap[cityCode] || []).forEach(function (c) {
html += '';
});
$box.find('.area-dist').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 distName = $box.find('.area-dist option:selected').text();
var parts = [];
if ($box.find('.area-prov').val()) parts.push(provName);
if ($box.find('.area-city').val() && cityName !== provName) parts.push(cityName);
if ($box.find('.area-dist').val()) parts.push(distName);
$box.closest('.form-item').find('input[name="' + target + '"]').val(parts.join('-'));
}
$('.area-cascade').each(function () {
var $box = $(this);
var target = $box.data('target');
var current = $box.closest('.form-item').find('input[name="' + target + '"]').val() || '';
var parts = current.split('-');
var provName = parts[0] || '';
var cityName = parts[1] || '';
var distName = parts[2] || '';
fillProv($box);
// 回选省
var provCode = '';
provCodes.forEach(function (code) {
if (provMap[code] === provName) {
provCode = code;
$box.find('.area-prov').val(code);
}
});
if (!provCode) return;
fillCity($box, provCode);
var cityList = childMap[provCode] || [];
var cityCode = '';
// 直接按市名匹配;直辖市(省/市同名,如"北京市-东城区")时 parts[1] 实为区县
var direct = cityList.filter(function (c) { return c.name === cityName; });
if (direct.length) {
cityCode = direct[0].code;
$box.find('.area-city').val(cityCode);
} else if (cityList.length === 1 && cityList[0].name === provName) {
cityCode = cityList[0].code;
$box.find('.area-city').val(cityCode);
if (parts[1] && !distName) {
distName = parts[1]; // 直辖市:第二段实为区县
}
}
if (!cityCode) return;
fillDist($box, cityCode);
(childMap[cityCode] || []).forEach(function (c) {
if (c.name === distName) $box.find('.area-dist').val(c.code);
});
});
// 联动事件
$('.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 () {
var $box = $(this).closest('.area-cascade');
fillDist($box, $(this).val());
combine($box);
});
$('.area-cascade').off('change.areaDist').on('change.areaDist', '.area-dist', function () {
combine($(this).closest('.area-cascade'));
});
}
function openForm(person, accounts, phone, email, experiences) {
var isEdit = !!person;
var p = person || {};
var pPhone = phone || '';
var pEmail = email || '';
var content =
'';
var idx = Dialog.open({
title: isEdit ? '编辑人员' : '新增人员',
area: ['720px', 'auto'],
content: content,
btn: false
});
// 手机号归属地自动识别
bindPhoneGeo($('#person-phone'), $('#person-phone-geo'));
// 加载国籍字典 + 行政区划字典(三级联动) + 来源渠道字典
httpGet('common/dicts.php', { type: 'all' }).then(function (d) {
var $dl = $('#person-country-list');
var html = '';
(d.countries || []).forEach(function (c) { html += ''; });
$dl.html(html);
// 省市区三级联动
initAreaCascade(d.areas || []);
var $sc = $('#person-source-channel');
var scHtml = '';
var hasCur = false;
(d.source_channels || []).forEach(function (s) {
var sel = (s.name === p.source_channel) ? ' selected' : '';
if (sel) hasCur = true;
scHtml += '';
});
if (p.source_channel && !hasCur) {
scHtml += '';
}
$sc.html(scHtml);
}).catch(function () {});
$('#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; }
// 联系方式(手机/邮箱,均为常用)
var contacts = [];
if ($.trim(data.phone || '')) {
contacts.push({ platform: 'phone', account_id: $.trim(data.phone), is_primary: 1, is_defult: 1 });
}
if ($.trim(data.email || '')) {
contacts.push({ platform: 'email', account_id: $.trim(data.email), is_primary: 1, is_defult: 1 });
}
data.contacts = JSON.stringify(contacts);
delete data.phone;
delete data.email;
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);
});
});
});
}
/* ---------- 导入 ---------- */
$('#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 += '| ' + escHtml(e.display_name || '-') + ' | ' + escHtml(e.position || '-') + ' | ' +
'' + escHtml(e.department || '-') + ' | ' + escHtml(e.job_level || '-') + ' | ' +
'' + (e.is_current ? '在职' : fmtDate(e.start_date) + ' ~ ' + (e.end_date || '至今')) + ' |
';
});
var html =
'' +
'
' + escHtml(p.full_name) + '
' +
'
' +
'
性别:' + escHtml(p.gender || '-') + '
' +
'
国籍:' + escHtml(p.nationality || '-') + '
' +
'
证件:' + escHtml(p.id_type || '-') + ' / ' + escHtml(p.id_number || '-') + '
' +
'
学历:' + escHtml(p.education || '-') + '
' +
'
毕业院校:' + escHtml(p.graduated_from || '-') + '
' +
'
家乡:' + escHtml(p.hometown || '-') + '
' +
'
工作所在地:' + escHtml(p.work_location || '-') + '
' +
'
来源渠道:' + escHtml(p.source_channel || '-') + '
' +
'
来源详情:' + escHtml(p.source_detail || '-') + '
' +
'
union_id:' + escHtml(p.union_id) + '
' +
'
' +
'
联系方式
' +
'
手机:' + escHtml(d.phone || '-') + '
' +
'
邮箱:' + escHtml(d.email || '-') + '
' +
'
工作履历
' +
'
| 公司 | 职位 | 部门 | 级别 | 时间 |
' +
(expHtml || '| 暂无 |
') + '
' +
'
';
Dialog.open({ title: '人员详情', area: ['760px', 'auto'], content: html, btn: ['关闭'] });
});
}
/* ---------- 任职履历弹窗(按人员查看任职公司/履历,分页) ---------- */
var compPersonId = 0;
window.viewResume = function (personId) {
compPersonId = personId;
var content =
'';
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 += '' +
'| ' + escHtml(r.company_name) + ' | ' +
'' + escHtml(r.department || '-') + ' | ' +
'' + escHtml(r.position || '-') + ' | ' +
'' + escHtml(r.job_level || '-') + ' | ' +
'' + escHtml(r.start_date || '-') + ' | ' +
'' + (r.is_current ? '在岗' : '离岗') + ' | ' +
'
';
});
if (!rows.length) {
html = '| 暂无任职记录 |
';
}
$('#comp-tbody').html(html);
renderPagination($('#comp-pagination'), data, loadCompanies);
});
}
});