package com.mes.print.config; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.regex.Pattern; import com.mes.print.PrinterException; /** * 打印配置加载器(UTF-8)。查找顺序: * 1. 系统属性 -Dprint.config=xxx 指定的路径 * 2. 当前工作目录 ./config/print.properties * 3. classpath 上的 print.properties(打进 jar 里的默认值) * 都没有就全用默认值(标签机 TSC TTP-244 PRO) */ public class PrinterConfig { private static final String CONFIG_FILE = "config/print.properties"; /** 默认标签机名 */ public static final String DEFAULT_LABEL_PRINTER = "TSC TTP-244 PRO"; private static Properties props; public static synchronized Properties load() { if (props != null) return props; Properties p = new Properties(); // 用 UTF-8 读:打印机名可能带中文(如「副本 1」),按 ISO-8859-1 读会乱码 try (InputStream in = openStream()) { // 找不到配置文件就全用默认值,单 jar 放在任何目录都能跑 if (in != null) p.load(new InputStreamReader(in, StandardCharsets.UTF_8)); } catch (Exception e) { throw new PrinterException("加载打印配置失败: " + e.getMessage(), e); } props = p; return props; } private static InputStream openStream() throws Exception { String sysPath = System.getProperty("print.config"); if (sysPath != null && new File(sysPath).exists()) { return new FileInputStream(sysPath); } File f = new File(CONFIG_FILE); System.out.println("[PrinterConfig] 查找配置文件: " + f.getAbsolutePath() + " (exists=" + f.exists() + ")"); if (f.exists()) return new FileInputStream(f); InputStream in = PrinterConfig.class.getClassLoader().getResourceAsStream("print.properties"); if (in != null) { System.out.println("[PrinterConfig] 从 classpath 加载配置"); return in; } System.out.println("[PrinterConfig] 未找到配置文件,使用默认值"); return null; } public static String get(String key) { return load().getProperty(key); } public static String get(String key, String defaultValue) { String v = load().getProperty(key); return v == null ? defaultValue : v; } /** 标签机 Windows 打印机名:label.printer.name,没配用默认 */ public static String getLabelPrinterName() { String name = get("label.printer.name", "").trim(); return name.isEmpty() ? DEFAULT_LABEL_PRINTER : name; } /** 重置缓存,下次 get 重新加载 */ public static synchronized void reset() { props = null; } /** * 写单个配置项到 ./config/print.properties 并立即生效。 * 按行替换,保留文件里的注释和其他键;键不存在就追加到末尾。 */ public static synchronized void set(String key, String value) { File f = new File(CONFIG_FILE).getAbsoluteFile(); // properties 里反斜杠是转义符,网络打印机名 \\server\TSC 要写成 \\\\server\\TSC String entry = key + "=" + (value == null ? "" : value.trim().replace("\\", "\\\\")); Pattern keyLine = Pattern.compile("^\\s*" + Pattern.quote(key) + "\\s*[=:].*$"); try { List lines = f.exists() ? new ArrayList<>(Files.readAllLines(f.toPath(), StandardCharsets.UTF_8)) : new ArrayList<>(); boolean replaced = false; for (int i = 0; i < lines.size(); i++) { if (keyLine.matcher(lines.get(i)).matches()) { lines.set(i, entry); replaced = true; break; } } if (!replaced) lines.add(entry); File dir = f.getParentFile(); if (dir != null && !dir.exists()) dir.mkdirs(); Files.write(f.toPath(), lines, StandardCharsets.UTF_8); } catch (Exception e) { throw new PrinterException("保存打印配置失败: " + e.getMessage(), e); } reset(); } }