package com.ruoyi.system.service.impl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.SysEmployee; import com.ruoyi.system.dto.SysEmployeeAddRequest; import com.ruoyi.system.dto.SysEmployeeDeleteRequest; import com.ruoyi.system.dto.SysEmployeeDetailRequest; import com.ruoyi.system.dto.SysEmployeeEditRequest; import com.ruoyi.system.dto.SysEmployeePageRequest; import com.ruoyi.system.dto.SysEmployeeStatusRequest; import com.ruoyi.system.dto.SysEmployeeUnbindRequest; import com.ruoyi.system.mapper.SysDeptMapper; import com.ruoyi.system.mapper.SysEmployeeMapper; import com.ruoyi.system.service.ISysEmployeeService; import com.ruoyi.system.utils.EmployeePhoneCrypto; import com.ruoyi.system.vo.SysEmployeeVO; import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; /** * 员工管理服务实现 * * @author ruoyi */ @Service public class SysEmployeeServiceImpl implements ISysEmployeeService { private static final Pattern MOBILE_PATTERN = Pattern.compile("^1\\d{10}$"); @Autowired private SysEmployeeMapper employeeMapper; @Autowired private SysDeptMapper deptMapper; @Override public PageInfo pageList(SysEmployeePageRequest request) { SysEmployeePageRequest query = request == null ? new SysEmployeePageRequest() : request; query.setEmployeeName(StringUtils.trim(query.getEmployeeName())); query.setEmployeeNo(StringUtils.trim(query.getEmployeeNo())); query.setContactPhone(EmployeePhoneCrypto.normalize(query.getContactPhone())); query.setPosition(StringUtils.trim(query.getPosition())); String phoneHash = StringUtils.isEmpty(query.getContactPhone()) ? null : EmployeePhoneCrypto.hash(query.getContactPhone()); PageInfo pageInfo = new PageInfo(query.getPageNum(), query.getPageSize()); List list = employeeMapper.pageList(query, phoneHash, pageInfo); for (SysEmployeeVO employee : list) { fillDisplayFields(employee, false); } pageInfo.setRecords(list); return pageInfo; } @Override public SysEmployeeVO detail(SysEmployeeDetailRequest request) { Long employeeId = getRequiredEmployeeId(request == null ? null : request.getEmployeeId()); SysEmployeeVO detail = employeeMapper.selectVoById(employeeId); if (detail == null) { throw new ServiceException("员工不存在"); } fillDisplayFields(detail, true); return detail; } @Override public int add(SysEmployeeAddRequest request, String username) { if (request == null) { throw new ServiceException("员工内容不能为空"); } SysEmployee employee = buildEmployee(request.getDeptId(), request.getEmployeeName(), request.getEmployeeNo(), request.getContactPhone(), request.getPosition(), request.getCardNo(), request.getFaceImage(), request.getEnabled(), null); employee.setCreateBy(username); return employeeMapper.insertEmployee(employee); } @Override public int edit(SysEmployeeEditRequest request, String username) { if (request == null) { throw new ServiceException("员工内容不能为空"); } Long employeeId = getRequiredEmployeeId(request.getEmployeeId()); if (employeeMapper.selectById(employeeId) == null) { throw new ServiceException("员工不存在"); } SysEmployee employee = buildEmployee(request.getDeptId(), request.getEmployeeName(), request.getEmployeeNo(), request.getContactPhone(), request.getPosition(), request.getCardNo(), request.getFaceImage(), request.getEnabled(), employeeId); employee.setEmployeeId(employeeId); employee.setUpdateBy(username); return employeeMapper.updateEmployee(employee); } @Override public int changeStatus(SysEmployeeStatusRequest request, String username) { List employeeIds = getRequiredEmployeeIds(request == null ? null : request.getEmployeeIds()); if (request.getEnabled() == null) { throw new ServiceException("启用状态不能为空"); } return employeeMapper.updateEnabled(employeeIds, request.getEnabled(), username); } @Override public int unbindCard(SysEmployeeUnbindRequest request, String username) { return employeeMapper.clearCard(getRequiredEmployeeIds(request == null ? null : request.getEmployeeIds()), username); } @Override public int unbindFace(SysEmployeeUnbindRequest request, String username) { return employeeMapper.clearFace(getRequiredEmployeeIds(request == null ? null : request.getEmployeeIds()), username); } @Override public int delete(SysEmployeeDeleteRequest request, String username) { return employeeMapper.deleteByIds(getRequiredEmployeeIds(request == null ? null : request.getEmployeeIds()), username); } @Override public String importData(InputStream inputStream, String username) { int successCount = 0; List errorMessages = new ArrayList(); Map deptNameMap = buildDeptNameMap(errorMessages); DataFormatter formatter = new DataFormatter(); try (Workbook workbook = WorkbookFactory.create(inputStream)) { Sheet sheet = workbook.getSheetAt(0); if (sheet == null || sheet.getLastRowNum() < 1) { throw new ServiceException("导入文件没有员工数据"); } for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) { Row row = sheet.getRow(rowIndex); if (isImportRowEmpty(row, formatter)) { continue; } try { SysEmployeeAddRequest request = buildImportRequest(row, formatter, deptNameMap); add(request, username); successCount++; } catch (Exception e) { errorMessages.add("第" + (rowIndex + 1) + "行:" + e.getMessage()); } } } catch (ServiceException e) { throw e; } catch (Exception e) { throw new ServiceException("员工导入失败:" + e.getMessage()); } if (successCount == 0 && errorMessages.isEmpty()) { throw new ServiceException("导入文件没有有效员工数据"); } if (errorMessages.isEmpty()) { return "导入成功,共导入" + successCount + "条员工数据"; } return "导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "条;" + String.join(";", errorMessages); } private SysEmployee buildEmployee(Long deptId, String employeeName, String employeeNo, String contactPhone, String position, String cardNo, String faceImage, Boolean enabled, Long excludeEmployeeId) { Long requiredDeptId = getRequiredDeptId(deptId); String requiredName = getRequiredText(employeeName, "员工名称不能为空"); String requiredNo = getRequiredText(employeeNo, "员工编号不能为空"); String requiredPhone = getRequiredPhone(contactPhone); String normalizedPosition = normalizePosition(position); String phoneHash = EmployeePhoneCrypto.hash(requiredPhone); String normalizedCardNo = StringUtils.trim(cardNo); if (employeeMapper.checkEmployeeNoUnique(requiredNo, excludeEmployeeId) != null) { throw new ServiceException("员工编号已存在"); } if (employeeMapper.checkPhoneUnique(phoneHash, excludeEmployeeId) != null) { throw new ServiceException("联系电话已存在"); } if (StringUtils.isNotEmpty(normalizedCardNo) && employeeMapper.checkCardNoUnique(normalizedCardNo, excludeEmployeeId) != null) { throw new ServiceException("卡号已绑定其他员工"); } SysEmployee employee = new SysEmployee(); employee.setDeptId(requiredDeptId); employee.setEmployeeName(requiredName); employee.setEmployeeNo(requiredNo); employee.setContactPhoneCipher(EmployeePhoneCrypto.encrypt(requiredPhone)); employee.setContactPhoneHash(phoneHash); employee.setPosition(normalizedPosition); employee.setCardNo(normalizedCardNo); employee.setFaceImage(StringUtils.trim(faceImage)); employee.setEnabled(enabled == null ? Boolean.TRUE : enabled); return employee; } private Map buildDeptNameMap(List errorMessages) { Map deptNameMap = new HashMap(); Map countMap = new HashMap(); List depts = deptMapper.selectDeptList(new SysDept()); for (SysDept dept : depts) { String deptName = StringUtils.trim(dept.getDeptName()); if (StringUtils.isEmpty(deptName)) { continue; } countMap.put(deptName, countMap.containsKey(deptName) ? countMap.get(deptName) + 1 : 1); deptNameMap.put(deptName, dept.getDeptId()); } for (Map.Entry entry : countMap.entrySet()) { if (entry.getValue() > 1) { errorMessages.add("部门名称重复:" + entry.getKey()); } } return deptNameMap; } private SysEmployeeAddRequest buildImportRequest(Row row, DataFormatter formatter, Map deptNameMap) { String employeeName = getImportCell(row, 0, formatter); String employeeNo = getImportCell(row, 1, formatter); String contactPhone = getImportCell(row, 2, formatter); String deptName = getImportCell(row, 3, formatter); String position = normalizePosition(getImportCell(row, 4, formatter)); String cardNo = getImportCell(row, 5, formatter); Long deptId = deptNameMap.get(deptName); if (deptId == null) { throw new ServiceException("所属部门不存在:" + deptName); } SysEmployeeAddRequest request = new SysEmployeeAddRequest(); request.setEmployeeName(employeeName); request.setEmployeeNo(employeeNo); request.setContactPhone(contactPhone); request.setDeptId(deptId); request.setPosition(position); request.setCardNo(cardNo); request.setEnabled(Boolean.TRUE); return request; } private boolean isImportRowEmpty(Row row, DataFormatter formatter) { if (row == null) { return true; } for (int index = 0; index <= 5; index++) { if (StringUtils.isNotEmpty(getImportCell(row, index, formatter))) { return false; } } return true; } private String getImportCell(Row row, int index, DataFormatter formatter) { return StringUtils.trim(formatter.formatCellValue(row.getCell(index))); } private Long getRequiredDeptId(Long deptId) { if (deptId == null || deptId <= 0) { throw new ServiceException("所属部门不能为空"); } SysDept dept = deptMapper.selectDeptById(deptId); if (dept == null) { throw new ServiceException("所属部门不存在"); } return deptId; } private Long getRequiredEmployeeId(Long employeeId) { if (employeeId == null || employeeId <= 0) { throw new ServiceException("员工主键不能为空"); } return employeeId; } private List getRequiredEmployeeIds(List employeeIds) { if (CollectionUtils.isEmpty(employeeIds)) { throw new ServiceException("请选择员工"); } for (Long employeeId : employeeIds) { getRequiredEmployeeId(employeeId); } return employeeIds; } private String getRequiredText(String value, String message) { String result = StringUtils.trim(value); if (StringUtils.isEmpty(result)) { throw new ServiceException(message); } return result; } private String getRequiredPhone(String value) { String phone = EmployeePhoneCrypto.normalize(value); if (!MOBILE_PATTERN.matcher(phone).matches()) { throw new ServiceException("联系电话必须为11位手机号"); } return phone; } private String normalizePosition(String value) { return StringUtils.trim(value); } private void fillDisplayFields(SysEmployeeVO employee, boolean fullPhone) { String phone = EmployeePhoneCrypto.decrypt(employee.getContactPhone()); employee.setContactPhone(fullPhone ? phone : maskPhone(phone)); employee.setPositionName(employee.getPosition()); } private String maskPhone(String phone) { if (phone == null || phone.length() < 7) { return ""; } return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4); } }