/** * person.js - 人员数据管理逻辑(列表+筛选+分页 / 新增编辑弹窗 / 导入导出 / 详情) */ $(function () { renderShell('人员数据', '数据管理 / 人员数据'); renderPage(); initPage('person', function (user) { if (!checkPagePermission('person')) return; loadList(1); }); var currentPage = 1; /** 渲染页面内容(工具栏+表格+分页) */ function renderPage() { $('#page-content').html( '
' + '
' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + '
' + '
' + ' ' + ' ' + '
ID姓名性别国籍工作所在地家乡学历手机邮箱创建时间操作
' + ' ' + '
' ); $('#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 = '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + areaSelectsHtml('hometown', p.hometown) + '
' + '
' + areaSelectsHtml('work_location', p.work_location) + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '' + '
'; 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); }); } });