feat(hrm): 新增员工紧急联系人管理功能
完成员工紧急联系人模块的全流程开发,包括: 1. 数据库表结构、Mapper、Service、Controller后端代码 2. 前端页面、API接口、导入导出功能 3. 配套SQL脚本、导入模板与使用文档 4. 支持批量导入导出、数据校验与用户关联匹配
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
package com.ruoyi.hrm.controller;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.hrm.domain.bo.HrmEmergencyContactBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactImportVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
import com.ruoyi.hrm.service.IHrmEmergencyContactService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/hrm/emergencyContact")
|
||||
public class HrmEmergencyContactController extends BaseController {
|
||||
|
||||
private final IHrmEmergencyContactService service;
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<HrmEmergencyContactVo> list(HrmEmergencyContactBo bo, PageQuery pageQuery) {
|
||||
return service.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
@GetMapping("/{contactId}")
|
||||
public R<HrmEmergencyContactVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long contactId) {
|
||||
return R.ok(service.queryById(contactId));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated @RequestBody HrmEmergencyContactBo bo) {
|
||||
return toAjax(service.insertByBo(bo));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated @RequestBody HrmEmergencyContactBo bo) {
|
||||
return toAjax(service.updateByBo(bo));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{contactIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] contactIds) {
|
||||
return toAjax(service.deleteWithValidByIds(Arrays.asList(contactIds), true));
|
||||
}
|
||||
|
||||
@Log(title = "紧急联系人管理", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HrmEmergencyContactBo bo, HttpServletResponse response) {
|
||||
List<HrmEmergencyContactVo> list = service.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "紧急联系人数据", HrmEmergencyContactVo.class, response);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<String> importData(@RequestPart("file") MultipartFile file, @RequestParam(defaultValue = "false") boolean updateSupport) throws IOException {
|
||||
List<HrmEmergencyContactImportVo> list = ExcelUtil.importExcel(file.getInputStream(), HrmEmergencyContactImportVo.class, false).getList();
|
||||
String msg = service.importByVoList(list, updateSupport);
|
||||
return R.ok(msg);
|
||||
}
|
||||
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("紧急联系人导入模板", "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
|
||||
// 示例数据(字段名第一行,示例数据第二行)
|
||||
List<HrmEmergencyContactImportVo> exampleList = new ArrayList<>();
|
||||
|
||||
// 添加示例数据
|
||||
HrmEmergencyContactImportVo example = new HrmEmergencyContactImportVo();
|
||||
example.setHireDate("2025.06.18");
|
||||
example.setCompanyName("山东福安德信息科技有限公司");
|
||||
example.setDeptName("信息化部");
|
||||
example.setRealName("张三");
|
||||
example.setPhone("183xxxxxxxx");
|
||||
example.setIdCard("341xxxxxxxxxxxxxxx");
|
||||
example.setGender("男");
|
||||
example.setAge(23);
|
||||
example.setEmergencyContact("李四");
|
||||
example.setRelationship("母子");
|
||||
example.setEmergencyPhone1("159xxxxxxxx");
|
||||
example.setEmergencyPhone2("");
|
||||
example.setEmergencyAddress("xx省xx市xx县xx镇xx村");
|
||||
example.setRemark("仅紧急情况联系");
|
||||
exampleList.add(example);
|
||||
|
||||
// 使用EasyExcel写入(字段名在第一行,示例数据在第二行)
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
EasyExcel.write(out, HrmEmergencyContactImportVo.class)
|
||||
.sheet("导入模板")
|
||||
.doWrite(exampleList);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ruoyi.hrm.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hrm_emergency_contact")
|
||||
public class HrmEmergencyContact extends BaseEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long contactId;
|
||||
private Long userId;
|
||||
private Long deptId;
|
||||
private String realName;
|
||||
private String phone;
|
||||
private String idCard;
|
||||
private String gender;
|
||||
private Integer age;
|
||||
private String companyName;
|
||||
private Date hireDate;
|
||||
private String emergencyContact;
|
||||
private String relationship;
|
||||
private String emergencyPhone1;
|
||||
private String emergencyPhone2;
|
||||
private String emergencyAddress;
|
||||
private String remark;
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ruoyi.hrm.domain.bo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class HrmEmergencyContactBo extends BaseEntity {
|
||||
|
||||
private Long contactId;
|
||||
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private Long userId;
|
||||
|
||||
private Long deptId;
|
||||
private String realName;
|
||||
private String phone;
|
||||
private String idCard;
|
||||
private String gender;
|
||||
private Integer age;
|
||||
private String companyName;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date hireDate;
|
||||
|
||||
@NotBlank(message = "紧急联系人姓名不能为空")
|
||||
private String emergencyContact;
|
||||
|
||||
private String relationship;
|
||||
|
||||
@NotBlank(message = "紧急联系人电话1不能为空")
|
||||
private String emergencyPhone1;
|
||||
|
||||
private String emergencyPhone2;
|
||||
private String emergencyAddress;
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.ruoyi.hrm.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.excel.annotation.write.style.ContentStyle;
|
||||
import com.alibaba.excel.annotation.write.style.HeadStyle;
|
||||
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 紧急联系人导入 VO
|
||||
* 与用户提供的Excel格式保持一致
|
||||
*
|
||||
* Excel表头顺序:
|
||||
* 入职时间 | 公司名称 | 部门 | 姓名 | 联系电话 | 身份证号 | 性别 | 年龄 | 紧急联系人 | 与本人关系 | 联系电话1 | 联系电话2 | 紧急联系人地址 | 备注
|
||||
*/
|
||||
@Data
|
||||
@HeadStyle(fillForegroundColor = 44, horizontalAlignment = HorizontalAlignmentEnum.CENTER)
|
||||
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.LEFT)
|
||||
public class HrmEmergencyContactImportVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 入职时间
|
||||
* 格式:yyyy.MM.dd 或 yyyy-MM-dd
|
||||
*/
|
||||
@Excel(name = "入职时间", width = 12)
|
||||
@ExcelProperty("入职时间")
|
||||
@ColumnWidth(12)
|
||||
private String hireDate;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
@Excel(name = "公司名称", width = 40)
|
||||
@ExcelProperty("公司名称")
|
||||
@ColumnWidth(40)
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 部门
|
||||
*/
|
||||
@Excel(name = "部门", width = 12)
|
||||
@ExcelProperty("部门")
|
||||
@ColumnWidth(12)
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
@Excel(name = "姓名", width = 10)
|
||||
@ExcelProperty("姓名")
|
||||
@ColumnWidth(10)
|
||||
private String realName;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
@Excel(name = "联系电话", width = 15)
|
||||
@ExcelProperty("联系电话")
|
||||
@ColumnWidth(15)
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
@Excel(name = "身份证号", width = 22)
|
||||
@ExcelProperty("身份证号")
|
||||
@ColumnWidth(22)
|
||||
private String idCard;
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
@Excel(name = "性别", width = 8, readConverterExp = "男=0,女=1,未知=2")
|
||||
@ExcelProperty("性别")
|
||||
@ColumnWidth(8)
|
||||
private String gender;
|
||||
|
||||
/**
|
||||
* 年龄
|
||||
*/
|
||||
@Excel(name = "年龄", width = 8)
|
||||
@ExcelProperty("年龄")
|
||||
@ColumnWidth(8)
|
||||
private Integer age;
|
||||
|
||||
/**
|
||||
* 紧急联系人
|
||||
*/
|
||||
@Excel(name = "紧急联系人", width = 12)
|
||||
@ExcelProperty("紧急联系人")
|
||||
@ColumnWidth(12)
|
||||
private String emergencyContact;
|
||||
|
||||
/**
|
||||
* 与本人关系
|
||||
*/
|
||||
@Excel(name = "与本人关系", width = 12)
|
||||
@ExcelProperty("与本人关系")
|
||||
@ColumnWidth(12)
|
||||
private String relationship;
|
||||
|
||||
/**
|
||||
* 联系电话1
|
||||
*/
|
||||
@Excel(name = "联系电话1", width = 15)
|
||||
@ExcelProperty("联系电话1")
|
||||
@ColumnWidth(15)
|
||||
private String emergencyPhone1;
|
||||
|
||||
/**
|
||||
* 联系电话2
|
||||
*/
|
||||
@Excel(name = "联系电话2", width = 15)
|
||||
@ExcelProperty("联系电话2")
|
||||
@ColumnWidth(15)
|
||||
private String emergencyPhone2;
|
||||
|
||||
/**
|
||||
* 紧急联系人地址
|
||||
*/
|
||||
@Excel(name = "紧急联系人地址", width = 40)
|
||||
@ExcelProperty("紧急联系人地址")
|
||||
@ColumnWidth(40)
|
||||
private String emergencyAddress;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Excel(name = "备注", width = 20)
|
||||
@ExcelProperty("备注")
|
||||
@ColumnWidth(20)
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ruoyi.hrm.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class HrmEmergencyContactVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Excel(name = "联系人ID")
|
||||
private Long contactId;
|
||||
|
||||
@Excel(name = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Excel(name = "部门ID")
|
||||
private Long deptId;
|
||||
|
||||
@Excel(name = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Excel(name = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Excel(name = "联系电话")
|
||||
private String phone;
|
||||
|
||||
@Excel(name = "身份证号")
|
||||
private String idCard;
|
||||
|
||||
@Excel(name = "性别", readConverterExp = "0=男,1=女,2=未知")
|
||||
private String gender;
|
||||
|
||||
@Excel(name = "年龄")
|
||||
private Integer age;
|
||||
|
||||
@Excel(name = "公司名称")
|
||||
private String companyName;
|
||||
|
||||
@Excel(name = "入职时间", width = 20, dateFormat = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date hireDate;
|
||||
|
||||
@Excel(name = "紧急联系人")
|
||||
private String emergencyContact;
|
||||
|
||||
@Excel(name = "与本人关系")
|
||||
private String relationship;
|
||||
|
||||
@Excel(name = "紧急电话1")
|
||||
private String emergencyPhone1;
|
||||
|
||||
@Excel(name = "紧急电话2")
|
||||
private String emergencyPhone2;
|
||||
|
||||
@Excel(name = "紧急联系人地址")
|
||||
private String emergencyAddress;
|
||||
|
||||
@Excel(name = "备注")
|
||||
private String remark;
|
||||
|
||||
private String createBy;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
private String updateBy;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.ruoyi.hrm.mapper;
|
||||
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import com.ruoyi.hrm.domain.HrmEmergencyContact;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
|
||||
public interface HrmEmergencyContactMapper extends BaseMapperPlus<HrmEmergencyContactMapper, HrmEmergencyContact, HrmEmergencyContactVo> {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ruoyi.hrm.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.hrm.domain.bo.HrmEmergencyContactBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactImportVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface IHrmEmergencyContactService {
|
||||
|
||||
HrmEmergencyContactVo queryById(Long contactId);
|
||||
|
||||
TableDataInfo<HrmEmergencyContactVo> queryPageList(HrmEmergencyContactBo bo, PageQuery pageQuery);
|
||||
|
||||
List<HrmEmergencyContactVo> queryList(HrmEmergencyContactBo bo);
|
||||
|
||||
Boolean insertByBo(HrmEmergencyContactBo bo);
|
||||
|
||||
Boolean updateByBo(HrmEmergencyContactBo bo);
|
||||
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
String importByVoList(List<HrmEmergencyContactImportVo> voList, boolean updateSupport);
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package com.ruoyi.hrm.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.hrm.domain.HrmEmergencyContact;
|
||||
import com.ruoyi.hrm.domain.bo.HrmEmergencyContactBo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactVo;
|
||||
import com.ruoyi.hrm.domain.vo.HrmEmergencyContactImportVo;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.hrm.mapper.HrmEmergencyContactMapper;
|
||||
import com.ruoyi.hrm.service.IHrmEmergencyContactService;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HrmEmergencyContactServiceImpl implements IHrmEmergencyContactService {
|
||||
|
||||
private final HrmEmergencyContactMapper baseMapper;
|
||||
private final SysUserMapper sysUserMapper;
|
||||
|
||||
// 手机号正则
|
||||
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
|
||||
// 身份证号正则(15位或18位)
|
||||
private static final Pattern ID_CARD_PATTERN = Pattern.compile("(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)");
|
||||
|
||||
@Override
|
||||
public HrmEmergencyContactVo queryById(Long contactId) {
|
||||
return baseMapper.selectVoById(contactId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<HrmEmergencyContactVo> queryPageList(HrmEmergencyContactBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = buildQueryWrapper(bo);
|
||||
Page<HrmEmergencyContactVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HrmEmergencyContactVo> queryList(HrmEmergencyContactBo bo) {
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(HrmEmergencyContactBo bo) {
|
||||
HrmEmergencyContact add = BeanUtil.toBean(bo, HrmEmergencyContact.class);
|
||||
return baseMapper.insert(add) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(HrmEmergencyContactBo bo) {
|
||||
HrmEmergencyContact update = BeanUtil.toBean(bo, HrmEmergencyContact.class);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importByVoList(List<HrmEmergencyContactImportVo> voList, boolean updateSupport) {
|
||||
if (CollUtil.isEmpty(voList)) {
|
||||
throw new ServiceException("导入数据不能为空");
|
||||
}
|
||||
int successNum = 0;
|
||||
int failNum = 0;
|
||||
StringBuilder failMsg = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < voList.size(); i++) {
|
||||
HrmEmergencyContactImportVo vo = voList.get(i);
|
||||
int rowNum = i + 2;
|
||||
|
||||
try {
|
||||
// 转换日期格式:将 yyyy.MM.dd 转换为 yyyy-MM-dd
|
||||
Date hireDate = null;
|
||||
if (StrUtil.isNotBlank(vo.getHireDate())) {
|
||||
String dateStr = vo.getHireDate().replace(".", "-");
|
||||
vo.setHireDate(dateStr);
|
||||
hireDate = DateUtil.parseDate(dateStr);
|
||||
}
|
||||
|
||||
// 性别转换:Excel 中为"男"/"女"/"未知",统一转代码值
|
||||
String gender = vo.getGender();
|
||||
if (StrUtil.isNotBlank(gender)) {
|
||||
if ("男".equals(gender)) { gender = "0"; }
|
||||
else if ("女".equals(gender)) { gender = "1"; }
|
||||
else if ("未知".equals(gender)) { gender = "2"; }
|
||||
vo.setGender(gender);
|
||||
}
|
||||
|
||||
// 数据校验
|
||||
String validateMsg = validateImportData(vo);
|
||||
if (StrUtil.isNotBlank(validateMsg)) {
|
||||
failNum++;
|
||||
failMsg.append("<br/>").append(failNum).append("、第").append(rowNum).append("行 ")
|
||||
.append(StrUtil.blankToDefault(vo.getRealName(), "无名")).append(":").append(validateMsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
HrmEmergencyContact entity = BeanUtil.toBean(vo, HrmEmergencyContact.class);
|
||||
// 根据姓名+身份证号匹配 sys_user,自动填充 userId/deptId
|
||||
Long matchedUserId = matchUserId(vo.getRealName(), vo.getIdCard());
|
||||
entity.setUserId(matchedUserId != null ? matchedUserId : 0L);
|
||||
// 显式设置入职日期(BeanUtil 可能无法自动转换 String -> Date)
|
||||
if (hireDate != null) {
|
||||
entity.setHireDate(hireDate);
|
||||
}
|
||||
|
||||
// 按「姓名 + 身份证号」去重
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(HrmEmergencyContact::getRealName, entity.getRealName());
|
||||
lqw.eq(HrmEmergencyContact::getIdCard, entity.getIdCard());
|
||||
HrmEmergencyContact existing = baseMapper.selectOne(lqw);
|
||||
|
||||
if (existing != null) {
|
||||
if (updateSupport) {
|
||||
entity.setContactId(existing.getContactId());
|
||||
baseMapper.updateById(entity);
|
||||
successNum++;
|
||||
} else {
|
||||
failNum++;
|
||||
failMsg.append("<br/>").append(failNum).append("、第").append(rowNum).append("行 ")
|
||||
.append(vo.getRealName()).append(":数据已存在(姓名+身份证号重复)");
|
||||
}
|
||||
} else {
|
||||
baseMapper.insert(entity);
|
||||
successNum++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failNum++;
|
||||
failMsg.append("<br/>").append(failNum).append("、第").append(rowNum).append("行 ")
|
||||
.append(StrUtil.blankToDefault(vo.getRealName(), "无名")).append(":导入失败,").append(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (failNum > 0) {
|
||||
return "导入完成!成功 " + successNum + " 条,失败 " + failNum + " 条。错误信息:" + failMsg;
|
||||
}
|
||||
return "恭喜您,数据已全部导入成功!共 " + successNum + " 条";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据姓名+身份证号匹配 sys_user,返回 userId;匹配不到返回 null
|
||||
*/
|
||||
private Long matchUserId(String realName, String idCard) {
|
||||
// 1. 优先按 realName + idCard 精确匹配
|
||||
if (StrUtil.isNotBlank(realName) && StrUtil.isNotBlank(idCard)) {
|
||||
SysUser user = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getNickName, realName)
|
||||
.eq(SysUser::getIdCard, idCard)
|
||||
.last("limit 1"));
|
||||
if (user != null) {
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
// 2. 仅按 idCard 匹配(唯一性高)
|
||||
if (StrUtil.isNotBlank(idCard)) {
|
||||
SysUser user = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getIdCard, idCard)
|
||||
.last("limit 1"));
|
||||
if (user != null) {
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
// 3. 仅按 realName 匹配(有重名风险,作为最后的兜底)
|
||||
if (StrUtil.isNotBlank(realName)) {
|
||||
SysUser user = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getNickName, realName)
|
||||
.last("limit 1"));
|
||||
if (user != null) {
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验导入数据
|
||||
*/
|
||||
private String validateImportData(HrmEmergencyContactImportVo vo) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
|
||||
if (StrUtil.isBlank(vo.getRealName())) {
|
||||
msg.append("姓名为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getPhone())) {
|
||||
msg.append("联系电话为空;");
|
||||
} else if (!PHONE_PATTERN.matcher(vo.getPhone()).matches()) {
|
||||
msg.append("联系电话格式错误(需11位手机号);");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getIdCard())) {
|
||||
msg.append("身份证号为空;");
|
||||
} else if (!ID_CARD_PATTERN.matcher(vo.getIdCard()).matches()) {
|
||||
msg.append("身份证号格式错误;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getGender())) {
|
||||
msg.append("性别为空;");
|
||||
}
|
||||
if (vo.getAge() == null) {
|
||||
msg.append("年龄为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getEmergencyContact())) {
|
||||
msg.append("紧急联系人为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getRelationship())) {
|
||||
msg.append("与本人关系为空;");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getEmergencyPhone1())) {
|
||||
msg.append("联系电话1为空;");
|
||||
} else if (!PHONE_PATTERN.matcher(vo.getEmergencyPhone1()).matches()) {
|
||||
msg.append("联系电话1格式错误(需11位手机号);");
|
||||
}
|
||||
if (StrUtil.isBlank(vo.getEmergencyAddress())) {
|
||||
msg.append("紧急联系人地址为空;");
|
||||
}
|
||||
if (StrUtil.isNotBlank(vo.getEmergencyPhone2()) && !PHONE_PATTERN.matcher(vo.getEmergencyPhone2()).matches()) {
|
||||
msg.append("联系电话2格式错误(需11位手机号);");
|
||||
}
|
||||
|
||||
return msg.toString();
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HrmEmergencyContact> buildQueryWrapper(HrmEmergencyContactBo bo) {
|
||||
LambdaQueryWrapper<HrmEmergencyContact> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getContactId() != null, HrmEmergencyContact::getContactId, bo.getContactId());
|
||||
lqw.eq(bo.getUserId() != null, HrmEmergencyContact::getUserId, bo.getUserId());
|
||||
lqw.like(bo.getRealName() != null, HrmEmergencyContact::getRealName, bo.getRealName());
|
||||
lqw.like(bo.getPhone() != null, HrmEmergencyContact::getPhone, bo.getPhone());
|
||||
lqw.like(bo.getEmergencyContact() != null, HrmEmergencyContact::getEmergencyContact, bo.getEmergencyContact());
|
||||
lqw.eq(bo.getDeptId() != null, HrmEmergencyContact::getDeptId, bo.getDeptId());
|
||||
lqw.eq(bo.getGender() != null, HrmEmergencyContact::getGender, bo.getGender());
|
||||
return lqw;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.hrm.mapper.HrmEmergencyContactMapper">
|
||||
<resultMap id="BaseResultMap" type="com.ruoyi.hrm.domain.HrmEmergencyContact">
|
||||
<id column="contact_id" property="contactId"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="dept_id" property="deptId"/>
|
||||
<result column="real_name" property="realName"/>
|
||||
<result column="phone" property="phone"/>
|
||||
<result column="id_card" property="idCard"/>
|
||||
<result column="gender" property="gender"/>
|
||||
<result column="age" property="age"/>
|
||||
<result column="company_name" property="companyName"/>
|
||||
<result column="hire_date" property="hireDate"/>
|
||||
<result column="emergency_contact" property="emergencyContact"/>
|
||||
<result column="relationship" property="relationship"/>
|
||||
<result column="emergency_phone1" property="emergencyPhone1"/>
|
||||
<result column="emergency_phone2" property="emergencyPhone2"/>
|
||||
<result column="emergency_address" property="emergencyAddress"/>
|
||||
<result column="remark" property="remark"/>
|
||||
<result column="create_by" property="createBy"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_by" property="updateBy"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
<result column="del_flag" property="delFlag"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
55
ruoyi-ui/src/api/hrm/emergencyContact.js
Normal file
55
ruoyi-ui/src/api/hrm/emergencyContact.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import request from '@/utils/request'
|
||||
import { download } from '@/utils/request'
|
||||
|
||||
// 查询紧急联系人列表
|
||||
export function listEmergencyContact(query) {
|
||||
return request({
|
||||
url: '/hrm/emergencyContact/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询紧急联系人详细
|
||||
export function getEmergencyContact(contactId) {
|
||||
return request({
|
||||
url: `/hrm/emergencyContact/${contactId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增紧急联系人
|
||||
export function addEmergencyContact(data) {
|
||||
return request({
|
||||
url: '/hrm/emergencyContact',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改紧急联系人
|
||||
export function updateEmergencyContact(data) {
|
||||
return request({
|
||||
url: '/hrm/emergencyContact',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除紧急联系人
|
||||
export function delEmergencyContact(contactIds) {
|
||||
return request({
|
||||
url: `/hrm/emergencyContact/${contactIds}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出紧急联系人
|
||||
export function exportEmergencyContact(query) {
|
||||
return download('/hrm/emergencyContact/export', query, '紧急联系人数据.xlsx')
|
||||
}
|
||||
|
||||
// 下载导入模板
|
||||
export function importTemplate() {
|
||||
return download('/hrm/emergencyContact/importTemplate', {}, '紧急联系人导入模板.xlsx')
|
||||
}
|
||||
@@ -12,4 +12,5 @@ export * from './org'
|
||||
export * from './reimburse'
|
||||
export * from './seal'
|
||||
export * from './travel'
|
||||
export * from './emergencyContact'
|
||||
|
||||
|
||||
449
ruoyi-ui/src/views/hrm/emergencyContact/index.vue
Normal file
449
ruoyi-ui/src/views/hrm/emergencyContact/index.vue
Normal file
@@ -0,0 +1,449 @@
|
||||
<template>
|
||||
<div class="emergency-contact-page">
|
||||
<el-card shadow="never" class="main-card">
|
||||
<div slot="header" class="card-header">
|
||||
<span class="header-title">员工紧急联系人</span>
|
||||
<div class="header-actions">
|
||||
<el-input v-model="query.realName" placeholder="姓名" size="small" clearable style="width: 160px;"
|
||||
@keyup.enter.native="loadList" />
|
||||
<el-input v-model="query.emergencyContact" placeholder="紧急联系人" size="small" clearable style="width: 160px;"
|
||||
@keyup.enter.native="loadList" />
|
||||
<el-select v-model="query.deptId" size="small" placeholder="部门" clearable filterable style="width: 160px;"
|
||||
@change="loadList">
|
||||
<el-option v-for="dept in deptOptions" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
|
||||
</el-select>
|
||||
<el-button size="small" type="primary" icon="el-icon-search" @click="loadList">查询</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
|
||||
<el-button size="small" icon="el-icon-download" @click="handleExport">导出</el-button>
|
||||
<el-button size="small" icon="el-icon-upload2" @click="importVisible = true">导入</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table :data="list" v-loading="loading" stripe height="calc(100vh - 280px)">
|
||||
<el-table-column prop="hireDate" label="入职时间" min-width="110" />
|
||||
<el-table-column prop="realName" label="姓名" min-width="100" />
|
||||
<el-table-column prop="phone" label="联系电话" min-width="130" />
|
||||
<el-table-column prop="gender" label="性别" min-width="60">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ { '0': '男', '1': '女', '2': '未知' }[scope.row.gender] || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="age" label="年龄" min-width="60" />
|
||||
<el-table-column prop="companyName" label="公司名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="emergencyContact" label="紧急联系人" min-width="100" />
|
||||
<el-table-column prop="relationship" label="关系" min-width="80" />
|
||||
<el-table-column prop="emergencyPhone1" label="紧急电话1" min-width="130" />
|
||||
<el-table-column prop="emergencyPhone2" label="紧急电话2" min-width="130" />
|
||||
<el-table-column prop="remark" label="备注" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-wrapper">
|
||||
<el-pagination :current-page="query.pageNum" :page-sizes="[10, 20, 50, 100]" :page-size="query.pageSize"
|
||||
:total="total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
|
||||
@current-change="handlePageChange" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px" append-to-body>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" size="small">
|
||||
<el-divider content-position="left">员工信息</el-divider>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="选择人员" prop="userId">
|
||||
<el-select v-model="form.userId" placeholder="请选择人员" filterable remote
|
||||
:remote-method="searchUsers" :loading="userLoading" style="width: 100%" clearable
|
||||
@change="handleUserChange">
|
||||
<el-option v-for="user in userOptions" :key="user.userId"
|
||||
:label="`${user.nickName} (${user.userName})`" :value="user.userId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="form.realName" placeholder="自动带出可修改" :disabled="!form.userId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话" prop="phone">
|
||||
<el-input v-model="form.phone" placeholder="自动带出可修改" :disabled="!form.userId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-select v-model="form.gender" placeholder="自动带出可修改" style="width: 100%" :disabled="!form.userId">
|
||||
<el-option label="男" value="0" />
|
||||
<el-option label="女" value="1" />
|
||||
<el-option label="未知" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input v-model="form.idCard" placeholder="自动带出可修改" :disabled="!form.userId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="年龄" prop="age">
|
||||
<el-input-number v-model="form.age" :min="0" :max="150" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider content-position="left">公司信息</el-divider>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司名称" prop="companyName">
|
||||
<el-input v-model="form.companyName" placeholder="请输入公司名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="入职时间" prop="hireDate">
|
||||
<el-date-picker v-model="form.hireDate" type="date" placeholder="选择日期" style="width: 100%"
|
||||
value-format="yyyy-MM-dd" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider content-position="left">紧急联系人</el-divider>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人姓名" prop="emergencyContact">
|
||||
<el-input v-model="form.emergencyContact" placeholder="请输入紧急联系人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="与本人关系" prop="relationship">
|
||||
<el-select v-model="form.relationship" placeholder="请选择关系" style="width: 100%" clearable filterable>
|
||||
<el-option label="配偶" value="配偶" />
|
||||
<el-option label="父母" value="父母" />
|
||||
<el-option label="子女" value="子女" />
|
||||
<el-option label="兄弟姐妹" value="兄弟姐妹" />
|
||||
<el-option label="朋友" value="朋友" />
|
||||
<el-option label="同事" value="同事" />
|
||||
<el-option label="其他" value="其他" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话1" prop="emergencyPhone1">
|
||||
<el-input v-model="form.emergencyPhone1" placeholder="请输入紧急联系人电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话2" prop="emergencyPhone2">
|
||||
<el-input v-model="form.emergencyPhone2" placeholder="请输入备用电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="联系地址" prop="emergencyAddress">
|
||||
<el-input v-model="form.emergencyAddress" placeholder="请输入紧急联系人地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="handleSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog title="导入紧急联系人数据" :visible.sync="importVisible" width="500px" append-to-body>
|
||||
<!-- 导入规则说明 -->
|
||||
<el-alert
|
||||
title="导入规则说明"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 15px;"
|
||||
>
|
||||
<div slot="description" style="font-size: 12px; line-height: 1.8;">
|
||||
<p>1. <strong>文件格式</strong>:必须是 .xlsx 格式,表头顺序不能乱</p>
|
||||
<p>2. <strong>必填字段</strong>:带 * 号的为必填项(姓名、联系电话、身份证号、性别、年龄等)</p>
|
||||
<p>3. <strong>重复数据</strong>:系统会按「姓名 + 身份证号」去重,已存在的记录会自动更新</p>
|
||||
<p>4. <strong>数据校验</strong>:手机号必须为 11 位数字,身份证号会做基础格式校验</p>
|
||||
<p>5. <strong>导入后核对</strong>:导入完成后请在列表页核对数据,如有错误可直接修改</p>
|
||||
</div>
|
||||
</el-alert>
|
||||
|
||||
<el-upload ref="upload" :limit="1" accept=".xlsx,.xls" :headers="upload.headers"
|
||||
:action="upload.url" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
|
||||
:on-success="handleFileSuccess" :on-error="handleFileError" :auto-upload="false"
|
||||
drag>
|
||||
<i class="el-icon-upload" />
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div slot="tip" class="el-upload__tip" style="color:red;padding:0 12px">
|
||||
仅允许导入 xlsx / xls 格式文件。
|
||||
<el-link type="primary" :underline="false" style="font-size:12px" @click="handleDownloadTemplate">下载导入模板(含字段说明和示例数据)</el-link>
|
||||
</div>
|
||||
</el-upload>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="importVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="upload.isUploading" @click="submitImport">确定导入</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listDept } from '@/api/system/dept'
|
||||
import { selectUser } from '@/api/system/user'
|
||||
import { listEmergencyContact, addEmergencyContact, updateEmergencyContact, delEmergencyContact, exportEmergencyContact, importTemplate } from '@/api/hrm/emergencyContact'
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
export default {
|
||||
name: 'HrmEmergencyContact',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
submitting: false,
|
||||
list: [],
|
||||
total: 0,
|
||||
deptOptions: [],
|
||||
userOptions: [],
|
||||
userLoading: false,
|
||||
query: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
realName: '',
|
||||
emergencyContact: '',
|
||||
deptId: null
|
||||
},
|
||||
dialogVisible: false,
|
||||
dialogTitle: '新增紧急联系人',
|
||||
form: {},
|
||||
rules: {
|
||||
userId: [{ required: true, message: '请选择人员', trigger: 'change' }],
|
||||
emergencyContact: [{ required: true, message: '请输入紧急联系人姓名', trigger: 'blur' }],
|
||||
emergencyPhone1: [{ required: true, message: '请输入紧急联系人电话', trigger: 'blur' }]
|
||||
},
|
||||
// 导入相关
|
||||
importVisible: false,
|
||||
upload: {
|
||||
headers: { Authorization: 'Bearer ' + getToken() },
|
||||
url: process.env.VUE_APP_BASE_API + '/hrm/emergencyContact/importData',
|
||||
isUploading: false
|
||||
},
|
||||
// 导入字段说明
|
||||
importFieldDesc: [
|
||||
{ field: '入职时间', required: false, desc: '格式:yyyy-MM-dd', example: '2025-06-18' },
|
||||
{ field: '公司名称', required: true, desc: '全称,与OA内一致', example: '山东福安德信息科技有限公司' },
|
||||
{ field: '部门', required: true, desc: '与OA内部门名称一致', example: '信息化部' },
|
||||
{ field: '姓名', required: true, desc: '员工真实姓名', example: '张三' },
|
||||
{ field: '联系电话', required: true, desc: '员工本人手机号,11位数字', example: '183xxxxxxxx' },
|
||||
{ field: '身份证号', required: true, desc: '18位或15位,含X大写', example: '341xxxxxxxxxxxxxxx' },
|
||||
{ field: '性别', required: true, desc: '男 / 女', example: '男' },
|
||||
{ field: '年龄', required: true, desc: '整数,按周岁填写', example: '23' },
|
||||
{ field: '紧急联系人', required: true, desc: '联系人真实姓名', example: '李四' },
|
||||
{ field: '与本人关系', required: true, desc: '如父子/母子/夫妻等', example: '母子' },
|
||||
{ field: '联系电话1', required: true, desc: '紧急联系人手机号,11位数字', example: '159xxxxxxxx' },
|
||||
{ field: '联系电话2', required: false, desc: '备用手机号,11位数字', example: '182xxxxxxxx' },
|
||||
{ field: '紧急联系人地址', required: true, desc: '详细地址', example: 'xx省xx市xx县xx镇' },
|
||||
{ field: '备注', required: false, desc: '补充说明', example: '仅紧急情况联系' }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadDeptOptions()
|
||||
this.loadList()
|
||||
},
|
||||
methods: {
|
||||
loadDeptOptions() {
|
||||
listDept({}).then(res => {
|
||||
this.deptOptions = res.data || []
|
||||
})
|
||||
},
|
||||
loadList() {
|
||||
this.loading = true
|
||||
listEmergencyContact(this.query).then(res => {
|
||||
this.list = res.rows || []
|
||||
this.total = res.total || 0
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.query.pageSize = val
|
||||
this.loadList()
|
||||
},
|
||||
handlePageChange(val) {
|
||||
this.query.pageNum = val
|
||||
this.loadList()
|
||||
},
|
||||
handleAdd() {
|
||||
this.dialogTitle = '新增紧急联系人'
|
||||
this.form = {
|
||||
userId: undefined,
|
||||
realName: '',
|
||||
phone: '',
|
||||
idCard: '',
|
||||
gender: '0',
|
||||
age: undefined,
|
||||
companyName: '',
|
||||
hireDate: undefined,
|
||||
emergencyContact: '',
|
||||
relationship: '',
|
||||
emergencyPhone1: '',
|
||||
emergencyPhone2: '',
|
||||
emergencyAddress: '',
|
||||
remark: ''
|
||||
}
|
||||
this.userOptions = []
|
||||
this.dialogVisible = true
|
||||
this.$nextTick(() => { this.$refs.formRef?.clearValidate() })
|
||||
},
|
||||
handleEdit(row) {
|
||||
this.dialogTitle = '编辑紧急联系人'
|
||||
this.form = { ...row }
|
||||
// 加载已选用户信息用于展示
|
||||
if (this.form.userId) {
|
||||
this.searchUsers('')
|
||||
}
|
||||
this.dialogVisible = true
|
||||
this.$nextTick(() => { this.$refs.formRef?.clearValidate() })
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm(`确认删除 "${row.realName}" 的紧急联系人信息吗?`, '提示', { type: 'warning' }).then(() => {
|
||||
delEmergencyContact(row.contactId).then(() => {
|
||||
this.$message.success('删除成功')
|
||||
this.loadList()
|
||||
})
|
||||
})
|
||||
},
|
||||
searchUsers(query) {
|
||||
this.userLoading = true
|
||||
selectUser({ userName: query, nickName: query, pageNum: 1, pageSize: 20 }).then(res => {
|
||||
this.userOptions = res.rows || []
|
||||
// 编辑时确保已选用户在选项中
|
||||
if (this.form.userId && !this.userOptions.find(u => u.userId === this.form.userId)) {
|
||||
selectUser({ userId: this.form.userId }).then(res2 => {
|
||||
if (res2.rows && res2.rows.length > 0) {
|
||||
this.userOptions.unshift(res2.rows[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}).finally(() => {
|
||||
this.userLoading = false
|
||||
})
|
||||
},
|
||||
handleUserChange(userId) {
|
||||
if (!userId) return
|
||||
const user = this.userOptions.find(u => u.userId === userId)
|
||||
if (user) {
|
||||
this.form.realName = user.nickName || ''
|
||||
this.form.phone = user.phonenumber || ''
|
||||
this.form.gender = user.sex || '0'
|
||||
this.form.idCard = user.idCard || ''
|
||||
// 根据身份证号计算年龄
|
||||
if (user.idCard && user.idCard.length >= 18) {
|
||||
const birthYear = parseInt(user.idCard.substring(6, 10))
|
||||
const currentYear = new Date().getFullYear()
|
||||
this.form.age = currentYear - birthYear
|
||||
}
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.formRef.validate(valid => {
|
||||
if (!valid) return
|
||||
this.submitting = true
|
||||
const api = this.form.contactId ? updateEmergencyContact : addEmergencyContact
|
||||
api(this.form).then(() => {
|
||||
this.$message.success(this.form.contactId ? '更新成功' : '新增成功')
|
||||
this.dialogVisible = false
|
||||
if (!this.form.contactId) {
|
||||
this.query.pageNum = 1
|
||||
}
|
||||
this.loadList()
|
||||
}).finally(() => {
|
||||
this.submitting = false
|
||||
})
|
||||
})
|
||||
},
|
||||
// 导出
|
||||
handleExport() {
|
||||
this.$confirm('确认导出紧急联系人数据吗?', '提示', { type: 'warning' }).then(() => {
|
||||
exportEmergencyContact(this.query)
|
||||
})
|
||||
},
|
||||
// 下载导入模板
|
||||
handleDownloadTemplate() {
|
||||
importTemplate()
|
||||
},
|
||||
handleFileUploadProgress() {
|
||||
this.upload.isUploading = true
|
||||
},
|
||||
handleFileSuccess(res) {
|
||||
this.upload.isUploading = false
|
||||
this.$refs.upload.clearFiles()
|
||||
this.importVisible = false
|
||||
this.$modal.msgSuccess(res.msg || '导入成功')
|
||||
this.loadList()
|
||||
},
|
||||
handleFileError() {
|
||||
this.upload.isUploading = false
|
||||
this.$message.error('导入失败,请检查文件格式')
|
||||
},
|
||||
submitImport() {
|
||||
this.$refs.upload.submit()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.emergency-contact-page {
|
||||
padding: 20px;
|
||||
background-color: #f0f2f5;
|
||||
}
|
||||
|
||||
.main-card {
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
41
sql/hrm_emergency_contact.sql
Normal file
41
sql/hrm_emergency_contact.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
-- =====================================================================
|
||||
-- 员工紧急联系人信息表
|
||||
-- 通过 user_id 关联 sys_user,自动带出姓名/性别/身份证号/联系电话
|
||||
-- =====================================================================
|
||||
CREATE TABLE IF NOT EXISTS `hrm_emergency_contact` (
|
||||
`contact_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '紧急联系人ID',
|
||||
|
||||
-- 关联信息(从 sys_user 自动带出 / 关联查询)
|
||||
`user_id` BIGINT NOT NULL COMMENT '用户ID(关联 sys_user)',
|
||||
`dept_id` BIGINT DEFAULT NULL COMMENT '部门ID(关联 sys_dept,从 sys_user 自动带出)',
|
||||
|
||||
-- 员工基本信息(新增/导入时从 sys_user 自动填充,允许手动修改)
|
||||
`real_name` VARCHAR(30) DEFAULT NULL COMMENT '姓名(从 sys_user.nick_name 自动带出)',
|
||||
`phone` VARCHAR(20) DEFAULT NULL COMMENT '联系电话(从 sys_user.phonenumber 自动带出)',
|
||||
`id_card` VARCHAR(200) DEFAULT NULL COMMENT '身份证号(从 sys_user.id_card 自动带出)',
|
||||
`gender` CHAR(1) DEFAULT '0' COMMENT '性别(0男 1女 2未知,从 sys_user.sex 自动带出)',
|
||||
`age` INT DEFAULT NULL COMMENT '年龄',
|
||||
|
||||
-- 公司信息(sys_user 无此字段,手动录入)
|
||||
`company_name` VARCHAR(100) DEFAULT NULL COMMENT '公司名称',
|
||||
`hire_date` DATE DEFAULT NULL COMMENT '入职时间',
|
||||
|
||||
-- 紧急联系人信息
|
||||
`emergency_contact` VARCHAR(30) DEFAULT NULL COMMENT '紧急联系人姓名',
|
||||
`relationship` VARCHAR(30) DEFAULT NULL COMMENT '与本人关系',
|
||||
`emergency_phone1` VARCHAR(20) DEFAULT NULL COMMENT '紧急联系人电话1',
|
||||
`emergency_phone2` VARCHAR(20) DEFAULT NULL COMMENT '紧急联系人电话2',
|
||||
`emergency_address` VARCHAR(200) DEFAULT NULL COMMENT '紧急联系人地址',
|
||||
|
||||
-- 基础字段
|
||||
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||||
`del_flag` CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
|
||||
`create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
|
||||
|
||||
PRIMARY KEY (`contact_id`) USING BTREE,
|
||||
KEY `idx_user_id` (`user_id`) USING BTREE,
|
||||
KEY `idx_dept_id` (`dept_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='员工紧急联系人信息表';
|
||||
30
sql/hrm_emergency_contact_cleanup.sql
Normal file
30
sql/hrm_emergency_contact_cleanup.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
-- =====================================================================
|
||||
-- 清理紧急联系人菜单脏数据(执行前请确认)
|
||||
-- =====================================================================
|
||||
|
||||
-- 方式1:按 menu_id 范围删除(如果之前用的是 2000-2100 或 2070-2076)
|
||||
-- DELETE FROM sys_menu WHERE menu_id BETWEEN 2000 AND 2100;
|
||||
-- DELETE FROM sys_menu WHERE menu_id BETWEEN 2070 AND 2076;
|
||||
|
||||
-- 方式2:按菜单名称删除(推荐,更精确)
|
||||
-- DELETE FROM sys_menu WHERE menu_name = '紧急联系人';
|
||||
|
||||
-- 方式3:按权限标识删除(删除所有相关按钮权限)
|
||||
-- DELETE FROM sys_menu WHERE perms LIKE 'hrm:emergencyContact:%';
|
||||
|
||||
-- 方式4:组合删除(先查后删,安全)
|
||||
-- 先查询确认
|
||||
SELECT menu_id, menu_name, parent_id, perms, create_time
|
||||
FROM sys_menu
|
||||
WHERE menu_name = '紧急联系人'
|
||||
OR perms LIKE 'hrm:emergencyContact:%';
|
||||
|
||||
-- 确认无误后再执行删除
|
||||
-- DELETE FROM sys_menu WHERE menu_name = '紧急联系人' OR perms LIKE 'hrm:emergencyContact:%';
|
||||
|
||||
-- =====================================================================
|
||||
-- 执行步骤:
|
||||
-- 1. 先执行 SELECT 查询,确认要删除的数据
|
||||
-- 2. 确认无误后,再执行 DELETE 语句
|
||||
-- 3. 删除完成后,在若依系统菜单管理界面手动添加菜单
|
||||
-- =====================================================================
|
||||
115
sql/hrm_emergency_contact_manual_guide.md
Normal file
115
sql/hrm_emergency_contact_manual_guide.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# 紧急联系人菜单手动添加指南
|
||||
|
||||
## 第一步:清理脏数据(在Navicat/DBeaver中执行)
|
||||
|
||||
```sql
|
||||
-- 先查询确认
|
||||
SELECT menu_id, menu_name, parent_id, perms, create_time
|
||||
FROM sys_menu
|
||||
WHERE menu_name = '紧急联系人'
|
||||
OR perms LIKE 'hrm:emergencyContact:%';
|
||||
|
||||
-- 确认无误后再执行删除
|
||||
DELETE FROM sys_menu
|
||||
WHERE menu_name = '紧急联系人'
|
||||
OR perms LIKE 'hrm:emergencyContact:%';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 第二步:在若依系统菜单管理中手动添加
|
||||
|
||||
### 1. 添加主菜单
|
||||
|
||||
进入 **系统管理 → 菜单管理**,点击【新增】按钮,填写以下信息:
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| 上级菜单 | 人事中心(或你想要的父菜单) |
|
||||
| 菜单类型 | 菜单 |
|
||||
| 菜单图标 | user |
|
||||
| 菜单名称 | 紧急联系人 |
|
||||
| 显示排序 | 99 |
|
||||
| 是否外链 | 否 |
|
||||
| 路由地址 | emergencyContact |
|
||||
| 组件路径 | hrm/emergencyContact/index |
|
||||
| 权限字符 | hrm:emergencyContact:list |
|
||||
| 路由参数 | (留空) |
|
||||
| 是否缓存 | 缓存 |
|
||||
| 显示状态 | 显示 |
|
||||
| 菜单状态 | 正常 |
|
||||
|
||||
点击【确定】保存。
|
||||
|
||||
---
|
||||
|
||||
### 2. 添加按钮权限
|
||||
|
||||
主菜单添加成功后,在菜单列表中找到【紧急联系人】,点击右侧的【新增】按钮(添加子菜单/按钮)。
|
||||
|
||||
需要添加以下6个按钮权限:
|
||||
|
||||
#### ① 查询按钮
|
||||
- 菜单类型:按钮
|
||||
- 菜单名称:查询
|
||||
- 显示排序:1
|
||||
- 权限字符:hrm:emergencyContact:query
|
||||
- 显示状态:显示
|
||||
- 菜单状态:正常
|
||||
|
||||
#### ② 新增按钮
|
||||
- 菜单类型:按钮
|
||||
- 菜单名称:新增
|
||||
- 显示排序:2
|
||||
- 权限字符:hrm:emergencyContact:add
|
||||
- 显示状态:显示
|
||||
- 菜单状态:正常
|
||||
|
||||
#### ③ 修改按钮
|
||||
- 菜单类型:按钮
|
||||
- 菜单名称:修改
|
||||
- 显示排序:3
|
||||
- 权限字符:hrm:emergencyContact:edit
|
||||
- 显示状态:显示
|
||||
- 菜单状态:正常
|
||||
|
||||
#### ④ 删除按钮
|
||||
- 菜单类型:按钮
|
||||
- 菜单名称:删除
|
||||
- 显示排序:4
|
||||
- 权限字符:hrm:emergencyContact:remove
|
||||
- 显示状态:显示
|
||||
- 菜单状态:正常
|
||||
|
||||
#### ⑤ 导出按钮
|
||||
- 菜单类型:按钮
|
||||
- 菜单名称:导出
|
||||
- 显示排序:5
|
||||
- 权限字符:hrm:emergencyContact:export
|
||||
- 显示状态:显示
|
||||
- 菜单状态:正常
|
||||
|
||||
#### ⑥ 导入按钮
|
||||
- 菜单类型:按钮
|
||||
- 菜单名称:导入
|
||||
- 显示排序:6
|
||||
- 权限字符:hrm:emergencyContact:import
|
||||
- 显示状态:显示
|
||||
- 菜单状态:正常
|
||||
|
||||
---
|
||||
|
||||
## 第三步:刷新系统
|
||||
|
||||
1. 添加完成后,**退出登录**或 **刷新页面**
|
||||
2. 重新登录后,在对应父菜单下应该能看到【紧急联系人】菜单
|
||||
3. 进入菜单测试功能是否正常
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **上级菜单选择**:如果想放在"人事中心"下,就选择"人事中心";如果想放在顶级,就选择"主类目"
|
||||
2. **权限字符**:必须严格按照 `hrm:emergencyContact:list`、`hrm:emergencyContact:query` 等格式填写
|
||||
3. **路由地址**:必须与前端路由配置一致,这里是 `emergencyContact`
|
||||
4. **组件路径**:必须与前端组件路径一致,这里是 `hrm/emergencyContact/index`
|
||||
42
sql/hrm_emergency_contact_menu.sql
Normal file
42
sql/hrm_emergency_contact_menu.sql
Normal file
@@ -0,0 +1,42 @@
|
||||
-- =====================================================================
|
||||
-- 菜单 SQL:员工紧急联系人管理(若依框架兼容版)
|
||||
-- 必须分步执行,不能批量执行!
|
||||
-- =====================================================================
|
||||
|
||||
-- ============================================================
|
||||
-- 第一步:清理可能存在的脏数据(如果之前执行失败过)
|
||||
-- ============================================================
|
||||
-- DELETE FROM sys_menu WHERE menu_id BETWEEN 2070 AND 2076;
|
||||
|
||||
-- ============================================================
|
||||
-- 第二步:插入主菜单(先执行这行,成功后再执行按钮)
|
||||
-- parent_id = 0 表示顶级菜单,可根据需要改为实际的HRM菜单ID
|
||||
-- ============================================================
|
||||
INSERT INTO sys_menu (
|
||||
menu_id, menu_name, parent_id, order_num, path, component, query_param,
|
||||
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time
|
||||
) VALUES (
|
||||
2070, '紧急联系人', 0, 99, 'emergencyContact', 'hrm/emergencyContact/index', '',
|
||||
1, 0, 'C', '0', '0', 'hrm:emergencyContact:list', 'user', 'admin', NOW()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 第三步:主菜单插入成功后,再执行按钮权限
|
||||
-- ============================================================
|
||||
INSERT INTO sys_menu (
|
||||
menu_id, menu_name, parent_id, order_num, path, component,
|
||||
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time
|
||||
) VALUES
|
||||
(2071, '查询', 2070, 1, '#', NULL, 1, 0, 'F', '0', '0', 'hrm:emergencyContact:query', '#', 'admin', NOW()),
|
||||
(2072, '新增', 2070, 2, '#', NULL, 1, 0, 'F', '0', '0', 'hrm:emergencyContact:add', '#', 'admin', NOW()),
|
||||
(2073, '修改', 2070, 3, '#', NULL, 1, 0, 'F', '0', '0', 'hrm:emergencyContact:edit', '#', 'admin', NOW()),
|
||||
(2074, '删除', 2070, 4, '#', NULL, 1, 0, 'F', '0', '0', 'hrm:emergencyContact:remove', '#', 'admin', NOW()),
|
||||
(2075, '导出', 2070, 5, '#', NULL, 1, 0, 'F', '0', '0', 'hrm:emergencyContact:export', '#', 'admin', NOW()),
|
||||
(2076, '导入', 2070, 6, '#', NULL, 1, 0, 'F', '0', '0', 'hrm:emergencyContact:import', '#', 'admin', NOW());
|
||||
|
||||
-- ============================================================
|
||||
-- 使用说明:
|
||||
-- 1. 如果之前执行失败过,先执行第一步的 DELETE 清理脏数据
|
||||
-- 2. 先执行第二步(主菜单),确认成功后再执行第三步(按钮权限)
|
||||
-- 3. 如需将菜单放在HRM模块下,将 parent_id 从 0 改为 HRM菜单的实际ID
|
||||
-- ============================================================
|
||||
24
sql/hrm_emergency_contact_sample_data.sql
Normal file
24
sql/hrm_emergency_contact_sample_data.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- =====================================================================
|
||||
-- 示例数据:信息部员工紧急联系人
|
||||
-- 使用前请将 user_id 替换为实际 sys_user 表中的 ID
|
||||
-- =====================================================================
|
||||
|
||||
-- 示例数据1:张伟
|
||||
INSERT INTO `hrm_emergency_contact` (`user_id`, `dept_id`, `real_name`, `phone`, `id_card`, `gender`, `age`, `company_name`, `hire_date`, `emergency_contact`, `relationship`, `emergency_phone1`, `emergency_phone2`, `emergency_address`, `remark`, `del_flag`, `create_by`, `create_time`)
|
||||
VALUES (1, 100, '张伟', '13800138001', '110101199001011234', '0', 36, '上海泛微网络科技股份有限公司', '2022-03-15', '李芳', '配偶', '13900139001', '13800138002', '上海市浦东新区张江高科技园区200号', '信息部经理', '0', 'admin', NOW());
|
||||
|
||||
-- 示例数据2:李娜
|
||||
INSERT INTO `hrm_emergency_contact` (`user_id`, `dept_id`, `real_name`, `phone`, `id_card`, `gender`, `age`, `company_name`, `hire_date`, `emergency_contact`, `relationship`, `emergency_phone1`, `emergency_phone2`, `emergency_address`, `remark`, `del_flag`, `create_by`, `create_time`)
|
||||
VALUES (2, 100, '李娜', '13800138003', '110101199205022345', '1', 34, '上海泛微网络科技股份有限公司', '2021-07-01', '王强', '配偶', '13900139003', '', '上海市徐汇区漕河泾开发区100号', '需求分析师', '0', 'admin', NOW());
|
||||
|
||||
-- 示例数据3:王强
|
||||
INSERT INTO `hrm_emergency_contact` (`user_id`, `dept_id`, `real_name`, `phone`, `id_card`, `gender`, `age`, `company_name`, `hire_date`, `emergency_contact`, `relationship`, `emergency_phone1`, `emergency_phone2`, `emergency_address`, `remark`, `del_flag`, `create_by`, `create_time`)
|
||||
VALUES (3, 100, '王强', '13800138005', '110101198803033456', '0', 38, '上海泛微网络科技股份有限公司', '2020-01-10', '刘静', '配偶', '13900139005', '13800138006', '上海市闵行区七宝镇50号', '开发主管', '0', 'admin', NOW());
|
||||
|
||||
-- 示例数据4:赵敏
|
||||
INSERT INTO `hrm_emergency_contact` (`user_id`, `dept_id`, `real_name`, `phone`, `id_card`, `gender`, `age`, `company_name`, `hire_date`, `emergency_contact`, `relationship`, `emergency_phone1`, `emergency_phone2`, `emergency_address`, `remark`, `del_flag`, `create_by`, `create_time`)
|
||||
VALUES (4, 100, '赵敏', '13800138007', '110101199507044567', '1', 31, '上海泛微网络科技股份有限公司', '2023-05-20', '赵建国', '父母', '13900139007', '', '上海市静安区南京西路300号', '前端开发', '0', 'admin', NOW());
|
||||
|
||||
-- 示例数据5:陈浩
|
||||
INSERT INTO `hrm_emergency_contact` (`user_id`, `dept_id`, `real_name`, `phone`, `id_card`, `gender`, `age`, `company_name`, `hire_date`, `emergency_contact`, `relationship`, `emergency_phone1`, `emergency_phone2`, `emergency_address`, `remark`, `del_flag`, `create_by`, `create_time`)
|
||||
VALUES (5, 100, '陈浩', '13800138009', '110101199608055678', '0', 30, '上海泛微网络科技股份有限公司', '2022-11-01', '陈芳', '父母', '13900139009', '13800138010', '上海市浦东新区陆家嘴环路1000号', '后端开发', '0', 'admin', NOW());
|
||||
BIN
sql/信息部紧急联系人导入.xlsx
Normal file
BIN
sql/信息部紧急联系人导入.xlsx
Normal file
Binary file not shown.
25
sql/紧急联系人导入模板示例.xlsx
Normal file
25
sql/紧急联系人导入模板示例.xlsx
Normal file
@@ -0,0 +1,25 @@
|
||||
这是一个示例说明文件,实际Excel模板需要通过系统下载
|
||||
|
||||
Excel模板字段顺序:
|
||||
1. 入职时间 (yyyy.MM.dd格式,如:2025.06.18)
|
||||
2. 公司名称 (如:山东福安德信息科技有限公司)
|
||||
3. 部门 (如:信息化部)
|
||||
4. 姓名 (如:高鑫磊)
|
||||
5. 联系电话 (如:18324818443)
|
||||
6. 身份证号 (如:341222200309052816)
|
||||
7. 性别 (男/女/未知)
|
||||
8. 年龄 (如:23)
|
||||
9. 紧急联系人 (如:李继敏)
|
||||
10. 与本人关系 (如:母子)
|
||||
11. 联系电话1 (如:15955868031)
|
||||
12. 联系电话2 (可选)
|
||||
13. 紧急联系人地址 (如:安徽省阜阳市太和县皮条孙镇)
|
||||
14. 备注 (可选)
|
||||
|
||||
示例数据:
|
||||
2025.06.18,山东福安德信息科技有限公司,信息化部,高鑫磊,18324818443,341222200309052816,男,23,李继敏,母子,15955868031,,安徽省阜阳市太和县皮条孙镇,
|
||||
2025.06.18,山东福安德信息科技有限公司,信息化部,刘敬超,19932047759,13043520021117093X,男,24,刘建领,父子,18932719783,,河北省邯郸市曲周县槐桥乡,
|
||||
,山东福安德信息科技有限公司,信息化部,王文昊,19711921991,130923200312073014,男,22,王海军,父子,18233665966,18233691998,河北省沧州市东光县,
|
||||
,山东福安德信息科技有限公司,信息化部,井昊东,17803227053,13063420041124001X,男,22,井小苗,母子,13803279482,18603228769,河北省保定市曲阳县七里庄村,
|
||||
,山东福安德信息科技有限公司,信息化部,祖启佳,13308587452,520221200406220769,女,22,黄倩,母女,18188276838,,贵州省六盘水市水城县,
|
||||
,山东福安德信息科技有限公司,信息化部,朱昊天,19930382154,131121200310093614,男,22,朱庆忠,父子,15832865136,,河北省衡水市枣强县,
|
||||
Reference in New Issue
Block a user