|
@@ -0,0 +1,296 @@
|
|
|
+package com.iamberry.rst.utils;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.google.gson.Gson;
|
|
|
+import com.iamberry.redis.RedisUtils;
|
|
|
+import com.iamberry.rst.core.cm.SalesOrder;
|
|
|
+import com.iamberry.rst.core.cm.SalesOrderItem;
|
|
|
+import com.iamberry.rst.core.cm.StoreShip;
|
|
|
+import com.iamberry.wechat.tools.NameUtils;
|
|
|
+import com.kuaidi100.sdk.api.LabelV2;
|
|
|
+import com.kuaidi100.sdk.contant.ApiInfoConstant;
|
|
|
+import com.kuaidi100.sdk.contant.CompanyConstant;
|
|
|
+import com.kuaidi100.sdk.contant.PrintType;
|
|
|
+import com.kuaidi100.sdk.core.IBaseClient;
|
|
|
+import com.kuaidi100.sdk.pojo.HttpResult;
|
|
|
+import com.kuaidi100.sdk.request.ManInfo;
|
|
|
+import com.kuaidi100.sdk.request.PrintReq;
|
|
|
+import com.kuaidi100.sdk.request.labelV2.OrderReq;
|
|
|
+import com.kuaidi100.sdk.utils.SignUtils;
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
+import org.apache.http.HttpEntity;
|
|
|
+import org.apache.http.HttpResponse;
|
|
|
+import org.apache.http.client.HttpClient;
|
|
|
+import org.apache.http.client.methods.HttpGet;
|
|
|
+import org.apache.http.impl.client.HttpClientBuilder;
|
|
|
+import org.apache.pdfbox.pdmodel.PDDocument;
|
|
|
+import org.apache.pdfbox.pdmodel.PDPage;
|
|
|
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|
|
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|
|
+import org.apache.pdfbox.pdmodel.font.PDFont;
|
|
|
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
|
|
+import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|
|
+import org.apache.pdfbox.rendering.ImageType;
|
|
|
+import org.apache.pdfbox.rendering.PDFRenderer;
|
|
|
+
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.*;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
+import java.util.Base64;
|
|
|
+import java.util.Random;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 申通快递工具类
|
|
|
+ */
|
|
|
+public class STOUtil {
|
|
|
+
|
|
|
+ private static final String key = "uknWvlpO7197";
|
|
|
+ private static final String secret = "a70ccd810db645e296ebe1696b49ea5d";
|
|
|
+ private static final String tempId = "ee26673ec17a4e1ca7f7911d68e5304f";
|
|
|
+ private static final String JD_TYPE = "jdalpha";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 请求下单
|
|
|
+ */
|
|
|
+ public static String reqOrder(SalesOrder salesOrder, StoreShip sender) throws Exception {
|
|
|
+ // 判断快递类型:只处理申通的订单
|
|
|
+ if (!"STO".equalsIgnoreCase(salesOrder.getSalesPostFirm())) {
|
|
|
+ throw new RuntimeException("请使用申通快递");
|
|
|
+ }
|
|
|
+ // 获取店铺授权数据
|
|
|
+ JSONObject kuaidi100 = JSONObject.parseObject(RedisUtils.get("kuaidi100"));
|
|
|
+ if (kuaidi100 == null) {
|
|
|
+ throw new RuntimeException("请先配置快递100授权信息");
|
|
|
+ }
|
|
|
+ if (!kuaidi100.containsKey(salesOrder.getSalesStoreId().toString())) {
|
|
|
+ throw new RuntimeException("未查询到店铺配置的授权信息");
|
|
|
+ }
|
|
|
+ JSONObject store = kuaidi100.getJSONObject(salesOrder.getSalesStoreId().toString());
|
|
|
+ /*
|
|
|
+ * 组装数据
|
|
|
+ */
|
|
|
+ ManInfo recManInfo = new ManInfo();
|
|
|
+
|
|
|
+ // 收货人信息
|
|
|
+ recManInfo.setName(salesOrder.getSalesAddressName());
|
|
|
+ recManInfo.setMobile(salesOrder.getSalesAddressTel());
|
|
|
+ recManInfo.setPrintAddr(salesOrder.getSalesAddressInfo());
|
|
|
+ // 发货人信息
|
|
|
+ ManInfo sendManInfo = new ManInfo();
|
|
|
+ sendManInfo.setName(sender.getStoreShipName());
|
|
|
+ sendManInfo.setMobile(sender.getStoreShipTel());
|
|
|
+ sendManInfo.setPrintAddr(sender.getStoreShipProvince() + " " + sender.getStoreShipCity() + " " + sender.getStoreShipAddress());
|
|
|
+ /// 订单信息
|
|
|
+ OrderReq orderReq = new OrderReq();
|
|
|
+ orderReq.setKuaidicom(CompanyConstant.ST);
|
|
|
+ orderReq.setCount(1);
|
|
|
+ orderReq.setTempId(tempId);
|
|
|
+ orderReq.setSendMan(sendManInfo);
|
|
|
+ orderReq.setRecMan(recManInfo);
|
|
|
+ orderReq.setPrintType(JD_TYPE.equalsIgnoreCase(store.getString("net"))?PrintType.IMAGE:PrintType.HTML);
|
|
|
+ orderReq.setPartnerId(store.getString("parterId"));
|
|
|
+ orderReq.setPartnerKey(store.getString("partnerKey"));
|
|
|
+ orderReq.setPartnerName(store.getString("partnerName"));
|
|
|
+ orderReq.setNet(store.getString("net"));
|
|
|
+ String param = new Gson().toJson(orderReq);
|
|
|
+ String t = System.currentTimeMillis() + "";
|
|
|
+ PrintReq printReq = new PrintReq();
|
|
|
+ printReq.setT(t);
|
|
|
+ printReq.setKey(key);
|
|
|
+ printReq.setSign(SignUtils.printSign(param,t,key,secret));
|
|
|
+ printReq.setMethod(ApiInfoConstant.ORDER);
|
|
|
+ printReq.setParam(param);
|
|
|
+ // 请求
|
|
|
+ IBaseClient baseClient = new LabelV2();
|
|
|
+ HttpResult execute = baseClient.execute(printReq);
|
|
|
+ JSONObject result = JSONObject.parseObject(execute.getBody());
|
|
|
+ if (!result.containsKey("success") || !"true".equalsIgnoreCase(result.getString("success"))) {
|
|
|
+ throw new RuntimeException("下单失败:" + result.getString("message"));
|
|
|
+ }
|
|
|
+ // 暂停2秒
|
|
|
+ Thread.sleep(3000);
|
|
|
+ // 启动数据
|
|
|
+ JSONObject data = result.getJSONObject("data");
|
|
|
+ // 下单成功:如果是京东,返回的是image,所以先将Image转换为pdf
|
|
|
+ String filePath = orderReq.getPrintType()==PrintType.IMAGE ?
|
|
|
+ (saveImageToPdf(data.getString("label"), salesOrder.getSalesId().toString())) :
|
|
|
+ (savePdf(data.getString("label"), salesOrder.getSalesId().toString()));
|
|
|
+ // 添加产品水印
|
|
|
+ addWordText(filePath, salesOrder, orderReq.getPrintType());
|
|
|
+ // 返回文件路径
|
|
|
+ return data.getString("kuaidinum");
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String pdf2Base64(String path) throws IOException {
|
|
|
+ try (PDDocument document = PDDocument.load(new File(path))) {
|
|
|
+ // PDF转IMG
|
|
|
+ PDFRenderer renderer = new PDFRenderer(document);
|
|
|
+ BufferedImage image = renderer.renderImageWithDPI(0, 300, ImageType.RGB);
|
|
|
+ /*
|
|
|
+ 不用保存
|
|
|
+ ImageIO.write(image, "jpg", new File(path.replace("pdf", "jpg")));
|
|
|
+ // 获取原始图片的Graphics2D对象
|
|
|
+ java.awt.Graphics2D g2 = image.createGraphics();
|
|
|
+ g2.setRenderingHint(java.awt.RenderingHints.KEY_INTERPOLATION, java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
|
|
+ g2.drawImage(image, 0, 0, 100, 180, null);
|
|
|
+ g2.dispose();
|
|
|
+ // 保存新的图片文件
|
|
|
+ ImageIO.write(image, "jpg", new File(path.replace("pdf", "jpg")));
|
|
|
+ */
|
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
+ // 将字节转换为Base64字符串
|
|
|
+ ImageIO.write(image, "PNG", baos);
|
|
|
+ byte[] imageInByte = baos.toByteArray();
|
|
|
+ return Base64.getEncoder().encodeToString(imageInByte);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ try {
|
|
|
+ pdf2Base64("/Users/apple/Desktop/683695.pdf");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static void addWordText(String filePath, SalesOrder salesOrder, PrintType type) {
|
|
|
+ try {
|
|
|
+ // 加载PDF文档
|
|
|
+ System.out.println("加载PDF文档..."+filePath);
|
|
|
+ PDDocument document = PDDocument.load(new File(filePath));
|
|
|
+ // 加载字体文件
|
|
|
+ PDFont font = PDType0Font.load(document, new File(NameUtils.getConfig("font_file_path")));
|
|
|
+ // 获取第一页
|
|
|
+ PDPage page = document.getPage(0);
|
|
|
+ // 创建页面内容流
|
|
|
+ PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
|
|
|
+ // 设置字体和字体大小
|
|
|
+ contentStream.setFont(font, type==PrintType.IMAGE? 2 : 6);
|
|
|
+ // 设置文本颜色
|
|
|
+ contentStream.setStrokingColor(255, 0, 0);
|
|
|
+ // 开始文本绘制
|
|
|
+ for (int i = 0; i < salesOrder.getSalesOrderItemList().size(); i++) {
|
|
|
+ SalesOrderItem item = salesOrder.getSalesOrderItemList().get(i);
|
|
|
+ String productText = item.getItemProductName()+"("+item.getItemProductColor()+")*"+item.getItemNum();
|
|
|
+ contentStream.beginText();
|
|
|
+ if (type==PrintType.IMAGE) {
|
|
|
+ contentStream.moveTextPositionByAmount(8, 45 - (i * 3));
|
|
|
+ } else {
|
|
|
+ contentStream.moveTextPositionByAmount(10, 130 - (i * 10));
|
|
|
+ }
|
|
|
+ if (i == 0) {
|
|
|
+ contentStream.showText("产品:" + productText);
|
|
|
+ } else {
|
|
|
+ contentStream.showText(" >>" + productText);
|
|
|
+ }
|
|
|
+ contentStream.endText();
|
|
|
+ }
|
|
|
+ // 关闭页面内容流
|
|
|
+ contentStream.close();
|
|
|
+ // 保存PDF文档
|
|
|
+ document.save(filePath);
|
|
|
+ // 关闭PDF文档
|
|
|
+ document.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String saveImageToPdf(String imageUrl, String fileName) throws IOException {
|
|
|
+ // 1. 下载你的图片转成字节
|
|
|
+ byte[] imageBytes = downloadImage(imageUrl);
|
|
|
+ // 2. 生成一页 PDF document
|
|
|
+ PDDocument document = new PDDocument();
|
|
|
+ PDImageXObject image = PDImageXObject.createFromByteArray(document, imageBytes, "image");
|
|
|
+ // 这里是你生成PDF自适应图片大小,不设置会默认为A4
|
|
|
+ PDRectangle pageSize = new PDRectangle(100, 180);
|
|
|
+ PDPage page = new PDPage(pageSize);
|
|
|
+ document.addPage(page);
|
|
|
+ // 3.将 图片 添加进PDF document
|
|
|
+ PDPageContentStream contentStream = new PDPageContentStream(document, page);
|
|
|
+ float pageWidth = pageSize.getWidth();
|
|
|
+ float pageHeight = pageSize.getHeight();
|
|
|
+ float imageWidth = image.getWidth();
|
|
|
+ float imageHeight = image.getHeight();
|
|
|
+ float scale = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
|
|
|
+ float scaledWidth = imageWidth * scale;
|
|
|
+ float scaledHeight = imageHeight * scale;
|
|
|
+ float x = (pageWidth - scaledWidth) / 2;
|
|
|
+ float y = (pageHeight - scaledHeight) / 2;
|
|
|
+ // 这里是将你的图片填充入pdf页
|
|
|
+ contentStream.drawImage(image, x, y, scaledWidth, scaledHeight);
|
|
|
+ contentStream.close();
|
|
|
+
|
|
|
+ // 4. 保存PDF
|
|
|
+ String saveFile = NameUtils.getConfig("save_file_dir") + fileName + ".pdf";
|
|
|
+ File outputFile = new File(saveFile);
|
|
|
+ File parentFolder = outputFile.getParentFile();
|
|
|
+ if (parentFolder != null && !parentFolder.exists()) {
|
|
|
+ parentFolder.mkdirs();
|
|
|
+ }
|
|
|
+ document.save(outputFile);
|
|
|
+ document.close();
|
|
|
+ return saveFile;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从输入流中获取字节数组
|
|
|
+ * @param inputStream
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static byte[] readInputStream(InputStream inputStream) throws IOException {
|
|
|
+ byte[] buffer = new byte[1024];
|
|
|
+ int len = 0;
|
|
|
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
|
+ while((len = inputStream.read(buffer)) != -1) {
|
|
|
+ bos.write(buffer, 0, len);
|
|
|
+ }
|
|
|
+ bos.close();
|
|
|
+ return bos.toByteArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String savePdf(String imageUrl, String fileName) throws IOException {
|
|
|
+ // 保存PDF
|
|
|
+ String saveFile = NameUtils.getConfig("save_file_dir") + fileName + ".pdf";
|
|
|
+ URL url = new URL(imageUrl);
|
|
|
+ HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
|
|
+ conn.setConnectTimeout(5*1000);
|
|
|
+ conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
|
|
|
+ InputStream inputStream = conn.getInputStream();
|
|
|
+ byte[] getData = readInputStream(inputStream);
|
|
|
+ File saveDir = new File(NameUtils.getConfig("save_file_dir"));
|
|
|
+ if(!saveDir.exists()){
|
|
|
+ saveDir.mkdir();
|
|
|
+ }
|
|
|
+ File file = new File(saveFile);
|
|
|
+ FileOutputStream fos = new FileOutputStream(file);
|
|
|
+ fos.write(getData);
|
|
|
+ if(fos != null){
|
|
|
+ fos.close();
|
|
|
+ }
|
|
|
+ if(inputStream!=null){
|
|
|
+ inputStream.close();
|
|
|
+ }
|
|
|
+ return saveFile;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private static byte[] downloadImage(String imageUrl) throws IOException {
|
|
|
+ HttpClient httpClient = HttpClientBuilder.create().build();
|
|
|
+ HttpGet httpGet = new HttpGet(imageUrl);
|
|
|
+ HttpResponse response = httpClient.execute(httpGet);
|
|
|
+ HttpEntity entity = response.getEntity();
|
|
|
+ InputStream inputStream = entity.getContent();
|
|
|
+ byte[] imageBytes = IOUtils.toByteArray(inputStream);
|
|
|
+ inputStream.close();
|
|
|
+ return imageBytes;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|