package com.ruoyi.system.service.impl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.SysCard; import com.ruoyi.system.domain.SysEmployee; import com.ruoyi.system.dto.SysCardDeleteRequest; import com.ruoyi.system.dto.SysCardDetailRequest; import com.ruoyi.system.dto.SysCardEmployeeRequest; import com.ruoyi.system.dto.SysCardPageRequest; import com.ruoyi.system.dto.SysCardSaveRequest; import com.ruoyi.system.mapper.SysCardMapper; import com.ruoyi.system.mapper.SysEmployeeMapper; import com.ruoyi.system.service.ISysCardService; import com.ruoyi.system.utils.EmployeePhoneCrypto; import com.ruoyi.system.vo.SysCardVO; 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.transaction.annotation.Transactional; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 卡片管理服务实现。 */ @Service public class SysCardServiceImpl implements ISysCardService { @Autowired private SysCardMapper cardMapper; @Autowired private SysEmployeeMapper employeeMapper; @Override public PageInfo pageList(SysCardPageRequest request) { SysCardPageRequest query = normalizeQuery(request); PageInfo pageInfo = new PageInfo(query.getPageNum(), query.getPageSize()); List rows = cardMapper.pageList(query, pageInfo); fillDisplayFields(rows, false); pageInfo.setRecords(rows); return pageInfo; } @Override public List list(SysCardPageRequest request) { List rows = cardMapper.selectList(normalizeQuery(request)); fillDisplayFields(rows, true); return rows; } @Override public SysCardVO detail(SysCardDetailRequest request) { Long cardId = requiredId(request == null ? null : request.getCardId(), "卡片主键不能为空"); SysCardVO card = cardMapper.selectVoById(cardId); if (card == null) { throw new ServiceException("卡片不存在"); } fillDisplayFields(Collections.singletonList(card), true); return card; } @Override public SysCardVO findEmployee(SysCardEmployeeRequest request) { String employeeName = requiredText(request == null ? null : request.getEmployeeName(), "请输入员工姓名"); List employees = employeeMapper.selectVoByName(employeeName); if (employees == null || employees.isEmpty()) { throw new ServiceException("该员工不存在,请到员工管理中添加"); } if (employees.size() > 1) { throw new ServiceException("员工姓名重复,请使用员工管理中的唯一姓名"); } SysEmployeeVO employee = employees.get(0); employee.setContactPhone(EmployeePhoneCrypto.decrypt(employee.getContactPhone())); SysCardVO result = new SysCardVO(); result.setEmployeeId(employee.getEmployeeId()); result.setEmployeeName(employee.getEmployeeName()); result.setContactPhone(employee.getContactPhone()); result.setDeptId(employee.getDeptId()); result.setDeptName(employee.getDeptName()); return result; } @Override @Transactional(rollbackFor = Exception.class) public int save(SysCardSaveRequest request, String username) { if (request == null) { throw new ServiceException("卡片内容不能为空"); } String cardNo = requiredText(request.getCardNo(), "卡号不能为空"); SysCard existing = request.getCardId() == null ? null : cardMapper.selectById(request.getCardId()); if (request.getCardId() != null && existing == null) { throw new ServiceException("卡片不存在"); } Long employeeId = resolveEmployeeId(request); SysCard duplicated = cardMapper.selectByCardNo(cardNo); if (duplicated != null && (existing == null || !duplicated.getCardId().equals(existing.getCardId()))) { throw new ServiceException("卡号已存在"); } SysEmployee employee = employeeId == null ? null : employeeMapper.selectById(employeeId); if (employeeId != null && employee == null) { throw new ServiceException("该员工不存在,请到员工管理中添加"); } if (employeeId != null) { if (StringUtils.isNotEmpty(StringUtils.trim(request.getEmployeeName())) && !StringUtils.trim(request.getEmployeeName()).equals(employee.getEmployeeName())) { throw new ServiceException("员工信息已变更,请重新校验员工姓名"); } boolean editingEmployeeCard = existing != null && employeeId.equals(existing.getEmployeeId()); if (StringUtils.isNotEmpty(employee.getCardNo()) && !cardNo.equals(employee.getCardNo()) && !editingEmployeeCard) { throw new ServiceException("该员工已绑定其他卡片"); } SysCard employeeCard = cardMapper.selectByEmployeeId(employeeId); if (employeeCard != null && (existing == null || !employeeCard.getCardId().equals(existing.getCardId()))) { throw new ServiceException("该员工已绑定其他卡片"); } SysEmployee sameCardEmployee = employeeMapper.checkCardNoUnique(cardNo, employeeId); if (sameCardEmployee != null) { throw new ServiceException("卡号已绑定其他员工"); } } if (existing == null) { SysCard card = new SysCard(); card.setCardNo(cardNo); card.setEmployeeId(employeeId); card.setCreateBy(username); int rows = cardMapper.insertCard(card); if (employeeId != null) { employeeMapper.updateCardNo(employeeId, cardNo, username); } return rows; } String oldCardNo = existing.getCardNo(); Long oldEmployeeId = existing.getEmployeeId(); if (oldEmployeeId != null && (!oldEmployeeId.equals(employeeId) || !oldCardNo.equals(cardNo))) { clearEmployeeCard(oldEmployeeId, oldCardNo, username); cardMapper.unbindByEmployeeId(oldEmployeeId, username); } existing.setCardNo(cardNo); existing.setUpdateBy(username); int rows = cardMapper.updateCard(existing); if (employeeId == null) { cardMapper.unbindByCardNo(cardNo, username); } else { cardMapper.bindCard(existing.getCardId(), employeeId, username); employeeMapper.updateCardNo(employeeId, cardNo, username); } return rows; } @Override @Transactional(rollbackFor = Exception.class) public int delete(SysCardDeleteRequest request, String username) { List cardIds = request == null ? null : request.getCardIds(); if (cardIds == null || cardIds.isEmpty()) { throw new ServiceException("请选择卡片"); } for (Long cardId : cardIds) { SysCard card = cardMapper.selectById(requiredId(cardId, "卡片主键不能为空")); if (card != null && card.getEmployeeId() != null) { clearEmployeeCard(card.getEmployeeId(), card.getCardNo(), username); } } return cardMapper.deleteByIds(cardIds, username); } @Override @Transactional(rollbackFor = Exception.class) public String importData(InputStream inputStream, String username) { int successCount = 0; List errors = new ArrayList(); 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); String cardNo = getCell(row, 0, formatter); String employeeName = getCell(row, 1, formatter); if (StringUtils.isEmpty(cardNo) && StringUtils.isEmpty(employeeName)) { continue; } try { SysCardSaveRequest request = new SysCardSaveRequest(); request.setCardNo(cardNo); request.setEmployeeName(employeeName); save(request, username); successCount++; } catch (Exception e) { errors.add("第" + (rowIndex + 1) + "行:" + e.getMessage()); } } } catch (ServiceException e) { throw e; } catch (Exception e) { throw new ServiceException("卡片导入失败:" + e.getMessage()); } if (successCount == 0 && errors.isEmpty()) { throw new ServiceException("导入文件没有有效卡片数据"); } if (errors.isEmpty()) { return "导入成功,共导入" + successCount + "条卡片数据"; } return "导入完成,成功" + successCount + "条,失败" + errors.size() + "条;" + String.join(";", errors); } private Long resolveEmployeeId(SysCardSaveRequest request) { if (request.getEmployeeId() != null) { return request.getEmployeeId(); } if (StringUtils.isEmpty(StringUtils.trim(request.getEmployeeName()))) { return null; } SysCardEmployeeRequest employeeRequest = new SysCardEmployeeRequest(); employeeRequest.setEmployeeName(request.getEmployeeName()); return findEmployee(employeeRequest).getEmployeeId(); } private void clearEmployeeCard(Long employeeId, String cardNo, String username) { SysEmployee employee = employeeMapper.selectById(employeeId); if (employee != null && cardNo != null && cardNo.equals(employee.getCardNo())) { employeeMapper.updateCardNo(employeeId, null, username); } } private SysCardPageRequest normalizeQuery(SysCardPageRequest request) { SysCardPageRequest query = request == null ? new SysCardPageRequest() : request; query.setCardNo(StringUtils.trim(query.getCardNo())); query.setEmployeeName(StringUtils.trim(query.getEmployeeName())); return query; } private void fillDisplayFields(List cards, boolean fullPhone) { for (SysCardVO card : cards) { String phone = EmployeePhoneCrypto.decrypt(card.getContactPhone()); card.setContactPhone(fullPhone ? phone : maskPhone(phone)); card.setBound(card.getEmployeeId() != null); } } private String maskPhone(String phone) { if (phone == null || phone.length() < 7) { return ""; } return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4); } private String requiredText(String value, String message) { String result = StringUtils.trim(value); if (StringUtils.isEmpty(result)) { throw new ServiceException(message); } return result; } private Long requiredId(Long value, String message) { if (value == null || value <= 0) { throw new ServiceException(message); } return value; } private String getCell(Row row, int index, DataFormatter formatter) { return row == null ? "" : StringUtils.trim(formatter.formatCellValue(row.getCell(index))); } }