package com.doumee.core.utils.xpyun; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.constants.Constants; import com.doumee.core.utils.HttpsUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * 芯烨云打印机API服务 */ @Slf4j @Service public class XpyunPrintService { private static final String BASE_URL = "https://open.xpyun.net/api/openapi/xprinter/"; @Autowired private SystemDictDataBiz systemDictDataBiz; /** * 添加打印机 */ public XpyunResponse addPrinter(String sn, String name) { JSONObject body = buildBaseRequest(); JSONArray printerContent = new JSONArray(); JSONObject printer = new JSONObject(); printer.put("sn", sn); printer.put("name", name); printerContent.add(printer); body.put("printerContent", printerContent); return callApi("addPrinters", body); } /** * 删除打印机 */ public XpyunResponse deletePrinter(String sn) { JSONObject body = buildBaseRequest(); JSONArray snlist = new JSONArray(); snlist.add(sn); body.put("snlist", snlist); return callApi("delPrinters", body); } /** * 查询打印机状态 */ public XpyunResponse queryPrinterStatus(String sn) { JSONObject body = buildBaseRequest(); body.put("sn", sn); return callApi("queryPrinterStatus", body); } /** * 打印标签 */ public XpyunResponse printLabel(String sn, String content) { JSONObject body = buildBaseRequest(); body.put("sn", sn); body.put("content", content); return callApi("printLabel", body); } /** * 构建订单标签内容 (60mm × 60mm = 480 × 480 dots) * * 布局: * shopName sn/countSn * 订单编号:code 下单时间:xxx * 收件信息:张三(手机尾号1234) * 订单行李: * 行李箱×1 双肩包×2 * 订单备注 * xxxxxxx */ public String buildOrderLabel(String shopName, String orderCode, String createTime, String takeUser, String takePhone, String goodsInfo, String remark, String snLabel) { StringBuilder sb = new StringBuilder(); sb.append(""); sb.append("480"); sb.append("480"); // 第1行: shopName 左侧, snLabel 右侧 sb.append("") .append(escapeXml(shopName)).append(""); sb.append("") .append(escapeXml(snLabel)).append(""); // 第2行: 订单编号 + 下单时间 sb.append("") .append("订单编号:").append(escapeXml(orderCode)).append(""); sb.append("") .append(escapeXml(createTime)).append(""); // 订单编号条形码 sb.append(""); // 第4行: 收件信息 String contactInfo = takeUser != null ? takeUser : ""; if (takePhone != null && takePhone.length() >= 4) { contactInfo += "(手机尾号" + takePhone.substring(takePhone.length() - 4) + ")"; } sb.append("") .append("收件信息:").append(escapeXml(contactInfo)).append(""); // 第5行: 订单行李 sb.append("") .append("订单行李:"); if (StringUtils.isNotBlank(goodsInfo)) { sb.append("") .append(escapeXml(goodsInfo)).append(""); } // 订单备注 if (StringUtils.isNotBlank(remark)) { sb.append("") .append("订单备注:"); sb.append("") .append(escapeXml(remark)).append(""); } sb.append(""); return sb.toString(); } // ========== 私有方法 ========== private JSONObject buildBaseRequest() { String user = systemDictDataBiz.queryByCode(Constants.XPYUN_CONFIG, Constants.XPYUN_USER).getCode(); String userKey = systemDictDataBiz.queryByCode(Constants.XPYUN_CONFIG, Constants.XPYUN_USER_KEY).getCode(); long timestamp = System.currentTimeMillis() / 1000; String sign = sha1(user + userKey + timestamp); JSONObject body = new JSONObject(); body.put("user", user); body.put("timestamp", timestamp); body.put("sign", sign); return body; } private XpyunResponse callApi(String endpoint, JSONObject body) { try { String url = BASE_URL + endpoint; String result = HttpsUtil.postJson(url, body.toJSONString()); if (result == null) { log.error("芯烨云API调用失败: endpoint={}, 响应为空", endpoint); XpyunResponse resp = new XpyunResponse(); resp.setCode(-1); resp.setMsg("响应为空"); return resp; } return JSON.parseObject(result, XpyunResponse.class); } catch (Exception e) { log.error("芯烨云API调用异常: endpoint={}, error={}", endpoint, e.getMessage(), e); XpyunResponse resp = new XpyunResponse(); resp.setCode(-1); resp.setMsg(e.getMessage()); return resp; } } private static String sha1(String input) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (Exception e) { throw new RuntimeException("SHA-1计算失败", e); } } private static String escapeXml(String text) { if (text == null) return ""; return text.replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'"); } }