feat(printer): 实现打印机轮询选择功能

- 新增 getNextPrinter 方法实现打印机轮询逻辑
- 添加 Redis 键前缀 PRINTER_INDEX_KEY_PREFIX 和过期时间常量
- 在创建打印任务时设置选中的打印机名称- 支持多个打印机按顺序轮流使用
- 使用 Redis 原子递增确保并发安全的索引获取
- 自动为 Redis 键设置 5 分钟过期时间以避免内存泄漏
This commit is contained in:
2025-10-28 17:31:08 +08:00
parent 5e2fe0329d
commit 85cdfe9ea1

View File

@@ -444,6 +444,8 @@ public class PrinterServiceImpl implements PrinterService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
private static final String USER_PHOTO_LIST_TO_PRINTER = "USER_PHOTO_LIST_TO_PRINTER:";
private static final String PRINTER_INDEX_KEY_PREFIX = "PRINTER_INDEX:";
private static final int PRINTER_INDEX_EXPIRE_MINUTES = 5;
private static final int TASK_STATUS_PENDING = 0;
private static final int TASK_STATUS_PROCESSING = 3;
private final Lock syncTaskLock = new ReentrantLock();
@@ -559,8 +561,12 @@ public class PrinterServiceImpl implements PrinterService {
log.error("获取景区配置失败,使用原始照片进行打印。景区ID: {}, 照片ID: {}", item.getScenicId(), item.getId(), e);
}
// 获取打印机名称(支持轮询)
String selectedPrinter = getNextPrinter(printer);
PrintTaskEntity task = new PrintTaskEntity();
task.setPrinterId(printer.getId());
task.setPrinterName(selectedPrinter);
task.setMpId(item.getId());
task.setPaper(printer.getPreferPaper());
task.setStatus(0);
@@ -572,4 +578,52 @@ public class PrinterServiceImpl implements PrinterService {
printTaskMapper.insertTask(task);
});
}
/**
* 获取下一个要使用的打印机名称(轮询逻辑)
*
* @param printer 打印机实体
* @return 选中的打印机名称
*/
private String getNextPrinter(PrinterEntity printer) {
String usePrinter = printer.getUsePrinter();
if (StringUtils.isBlank(usePrinter)) {
log.warn("打印机 {} 没有配置 usePrinter", printer.getId());
return "";
}
// 分割打印机列表
String[] printers = usePrinter.split("\\|");
if (printers.length == 0) {
log.warn("打印机 {} 的 usePrinter 配置为空", printer.getId());
return "";
}
// 如果只有一个打印机,直接返回
if (printers.length == 1) {
return printers[0].trim();
}
// 从 Redis 原子递增获取索引
String redisKey = PRINTER_INDEX_KEY_PREFIX + printer.getId();
Long incrementedValue = redisTemplate.opsForValue().increment(redisKey);
if (incrementedValue == null) {
log.warn("Redis increment 操作失败,打印机ID: {}", printer.getId());
incrementedValue = 1L;
}
// 每次递增后都重新设置过期时间为 5 分钟
redisTemplate.expire(redisKey, PRINTER_INDEX_EXPIRE_MINUTES, TimeUnit.MINUTES);
// 对打印机数量取模得到当前索引
int currentIndex = (int) ((incrementedValue - 1) % printers.length);
// 获取当前打印机
String selectedPrinter = printers[currentIndex].trim();
log.debug("打印机 {} 选择了第 {} 个打印机: {} (递增值: {})", printer.getId(), currentIndex, selectedPrinter, incrementedValue);
return selectedPrinter;
}
}