From bc58cc89b4a8e84cd11885481667fb8bbe8918d0 Mon Sep 17 00:00:00 2001 From: lihao Date: Fri, 23 May 2025 10:32:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E7=A5=A8=E4=B8=8B=E8=BD=BD=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E4=B8=8B=E8=BD=BD=E5=8E=8B=E7=BC=A9=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sale/action/InvoiceDownloadAction.java | 395 +++++++++--------- 1 file changed, 200 insertions(+), 195 deletions(-) diff --git a/sscivm/src/client/nccloud/web/sscivm/ivsale/sale/action/InvoiceDownloadAction.java b/sscivm/src/client/nccloud/web/sscivm/ivsale/sale/action/InvoiceDownloadAction.java index d4f0182..9ef8900 100644 --- a/sscivm/src/client/nccloud/web/sscivm/ivsale/sale/action/InvoiceDownloadAction.java +++ b/sscivm/src/client/nccloud/web/sscivm/ivsale/sale/action/InvoiceDownloadAction.java @@ -4,14 +4,12 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.text.SimpleDateFormat; +import java.util.*; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; +import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; -import java.util.Base64; import java.net.URLEncoder; import com.alibaba.fastjson.JSONObject; @@ -20,6 +18,9 @@ import com.google.gson.Gson; import java.io.ByteArrayInputStream; import java.io.IOException; +import nc.bs.framework.common.NCLocator; +import nc.itf.uap.IUAPQueryBS; +import nc.jdbc.framework.processor.MapProcessor; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; @@ -44,210 +45,214 @@ import nccloud.framework.web.action.itf.ICommonAction; import nccloud.framework.web.container.IRequest; import nccloud.itf.sscivm.ivsale.service.IVSaleQueryService; import nccloud.pubitf.platform.attachment.IAttachmentService; +import java.io.ByteArrayOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; public class InvoiceDownloadAction implements ICommonAction { - IAttachmentService ncservice = ServiceLocator.find(IAttachmentService.class); + IAttachmentService ncservice = ServiceLocator.find(IAttachmentService.class); - @Override - public Object doAction(IRequest request) { + @Override + public Object doAction(IRequest request) { + Map params_1 = request.readParameters(); + String[] pks = params_1.get("pk"); // 获取所有 pk + String[] arrInvoiceTypes = params_1.get("arrInvoiceTypes"); + String isdoc = "z"; + WebFile file = null; - Map params_1 = request.readParameters(); + try { + // 创建内存中的 ZIP 输出流 + ByteArrayOutputStream zipOut = new ByteArrayOutputStream(); + ZipOutputStream zipStream = new ZipOutputStream(zipOut); + String zipName = ""; + // 遍历所有 pk + for (String pk : pks) { + List headVOList = ServiceLocator.find(IVSaleQueryService.class).queryIVMInvoiceHeadVOsByPks(new String[]{pk}); + IVMInvoiceHeadVO headVO = headVOList.get(0); - String[] pk = params_1.get("pk"); - String[] invoiceTypes = params_1.get("invoiceType"); - String isdoc = "z"; - WebFile file = null; - try { - List headVOList =ServiceLocator.find(IVSaleQueryService.class).queryIVMInvoiceHeadVOsByPks(new String[] {pk[0]}); - IVMInvoiceHeadVO headVO = headVOList.get(0); - String invoiceType = invoiceTypes[0]; + // 获取旗舰版的token + String appKey = "8c9eb1ea1ba54b3f9683a8b355f8e615"; + String appSecret = "999e15c2a13ee4eab480534be4bf52fdf9032a6d"; + String tokenUrl = "https://c2.yonyoucloud.com/iuap-api-auth/open-auth/selfAppAuth/getAccessToken"; + String getbsfileUrl = "https://c2.yonyoucloud.com/iuap-api-gateway/yonbip/tax/output-tax/api/einvoice/getbsfile?access_token="; + + Map params = new HashMap<>(); + params.put("appKey", appKey); + String timestamp = String.valueOf(System.currentTimeMillis()); + params.put("timestamp", timestamp); + + // 计算签名 + Map treeMap = new TreeMap<>(params); + StringBuilder stringBuilder = new StringBuilder(); + for (Map.Entry entry : treeMap.entrySet()) { + stringBuilder.append(entry.getKey()).append(entry.getValue()); + } + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + byte[] signData = mac.doFinal(stringBuilder.toString().getBytes(StandardCharsets.UTF_8)); + String base64String = Base64.getEncoder().encodeToString(signData); + String signature = URLEncoder.encode(base64String, "UTF-8"); + params.put("signature", signature); + + String responseString = doGet(tokenUrl, params); + Gson gson = new Gson(); + Map result = gson.fromJson(responseString, Map.class); + + if (StringUtils.equals("00000", result.get("code").toString())) { + Map tokenInfo = (Map) result.get("data"); + String access_token = (String) tokenInfo.get("access_token"); + + Map map = new HashMap<>(); + map.put("fplx", headVO.getInvoice_type()); + map.put("slfphm", headVO.getFphm()); + map.put("yypdf", "0"); + map.put("taxpdf", Arrays.asList(arrInvoiceTypes).contains("1") ? "1" : "0"); + map.put("taxxml", Arrays.asList(arrInvoiceTypes).contains("2") ? "1" : "0"); + map.put("taxofd", Arrays.asList(arrInvoiceTypes).contains("3") ? "1" : "0"); + + String resString = doPost(getbsfileUrl + access_token, map); + gson = new Gson(); + Map resultMap = gson.fromJson(resString, Map.class); + + if (StringUtils.equals("200", resultMap.get("code").toString())) { + Map infoMap = (Map) resultMap.get("data"); + String pdfData = (String) infoMap.get("taxpdf"); + String xmlData = (String) infoMap.get("taxxml"); + String ofdData = (String) infoMap.get("taxofd"); + + if (MMValueCheck.isEmpty(pdfData) && MMValueCheck.isEmpty(xmlData) && MMValueCheck.isEmpty(ofdData)) { + throw new Exception("未查询到发票信息"); + } + + String ctcode = ""; + HYSuperDMO dmo = new HYSuperDMO(); + IVApplogVO[] ivApplogVO = (IVApplogVO[]) dmo.queryByWhereClause(IVApplogVO.class, "fphm='" + headVO.getFphm() + "' and dr=0 "); + if (ivApplogVO != null && ivApplogVO.length > 0) { + IVApplicationHeadVO ivApplicationHeadVO = (IVApplicationHeadVO) dmo.queryByPrimaryKey(IVApplicationHeadVO.class, ivApplogVO[0].getLyid()); +// ctcode = ivApplicationHeadVO.getDef2(); // 合同号 + String operationSql = "SELECT bd.NAME name from bd_defdoc bd LEFT join bd_defdoclist bdl ON bd.pk_defdoclist=bdl.pk_defdoclist WHERE bdl.code ='zdy-001'\n" + + "AND bd.pk_defdoc = '" + ivApplicationHeadVO.getDef2().toString() + "' "; +// List> operationresult = (List>) getQueryService().executeQuery(operationSql, new ArrayListProcessor()); + Map valList = (Map) getQueryService().executeQuery(operationSql, new MapProcessor()); + ctcode = (String) valList.get("name"); + } + + // 添加 PDF + if (!MMValueCheck.isEmpty(pdfData)) { + byte[] pdfBytes = DatatypeConverter.parseBase64Binary(pdfData); + zipStream.putNextEntry(new ZipEntry(ctcode + "_" + headVO.getGmfmc() + "_" + headVO.getFphm() + "_" + String.valueOf(headVO.getJshj().toDouble()) + ".pdf")); + zipStream.write(pdfBytes); + zipStream.closeEntry(); + } + + // 添加 XML + if (!MMValueCheck.isEmpty(xmlData)) { + byte[] xmlBytes = DatatypeConverter.parseBase64Binary(xmlData); + zipStream.putNextEntry(new ZipEntry(ctcode + "_" + headVO.getGmfmc() + "_" + headVO.getFphm() + "_" + String.valueOf(headVO.getJshj().toDouble()) + ".xml")); + zipStream.write(xmlBytes); + zipStream.closeEntry(); + } + + // 添加 OFD + if (!MMValueCheck.isEmpty(ofdData)) { + byte[] ofdBytes = DatatypeConverter.parseBase64Binary(ofdData); + zipStream.putNextEntry(new ZipEntry(ctcode + "_" + headVO.getGmfmc() + "_" + headVO.getFphm() + "_" + String.valueOf(headVO.getJshj().toDouble()) + ".ofd")); + zipStream.write(ofdBytes); + zipStream.closeEntry(); + } + zipName=ctcode + "_" + headVO.getGmfmc() + "_" + headVO.getFphm() + "_" + String.valueOf(headVO.getJshj().toDouble()); + } else { + throw new Exception("获取发票信息失败"); + } + } else { + throw new Exception("获取access_token失败"); + } + } + + zipStream.finish(); + zipStream.close(); + if(pks.length > 1){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); + zipName = "发票下载_" + sdf.format(new Date()); + } + // 构造 WebFile 返回 ZIP 文件 + InputStream ins = new ByteArrayInputStream(zipOut.toByteArray()); + file = new WebFile(zipName+".zip", ins); + + } catch (BusinessException e) { + ExceptionUtils.wrappException(e); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidKeyException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return file; + } - // 鑾峰彇鏃楄埌鐗堢殑token - String appKey = "8c9eb1ea1ba54b3f9683a8b355f8e615"; - String appSecret = "999e15c2a13ee4eab480534be4bf52fdf9032a6d"; - String tokenUrl="https://c2.yonyoucloud.com/iuap-api-auth/open-auth/selfAppAuth/getAccessToken"; - String getbsfileUrl="https://c2.yonyoucloud.com/iuap-api-gateway/yonbip/tax/output-tax/api/einvoice/getbsfile?access_token="; + private String doPost(String requestUrl, Map param) throws IOException { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(500); + cm.setDefaultMaxPerRoute(50); - Map params = new HashMap<>(); + RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 连接池获取连接超时 + .setConnectTimeout(5000) // 连接建立超时 + .setSocketTimeout(20000) // 等待响应超时 + .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); - // 闄ょ鍚嶅鐨勫叾浠栧弬鏁 - params.put("appKey", appKey); - String timestamp = String.valueOf(System.currentTimeMillis()); - params.put("timestamp", timestamp); - // 璁$畻绛惧悕 - Map treeMap; - if (params instanceof TreeMap) { - treeMap = params; - } else { - treeMap = new TreeMap<>(params); - } - StringBuilder stringBuilder = new StringBuilder(); - for (Map.Entry entry : treeMap.entrySet()) { - stringBuilder.append(entry.getKey()).append(entry.getValue()); - } - Mac mac = Mac.getInstance("HmacSHA256"); + CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm) + .setDefaultRequestConfig(globalConfig).build(); + HttpPost post = new HttpPost(requestUrl); + post.setHeader("Content-Type", "application/json;charset=UTF-8"); + post.setEntity(new StringEntity(JSONObject.toJSONString(param), "utf-8")); + String responseString = httpClient.execute(post, response -> EntityUtils.toString(response.getEntity())); + return responseString; - mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); - byte[] signData = mac.doFinal(stringBuilder.toString().getBytes(StandardCharsets.UTF_8)); - String base64String = Base64.getEncoder().encodeToString(signData); - String signature = URLEncoder.encode(base64String, "UTF-8"); - params.put("signature", signature); -// String responseString = doGet( -// "https://c1.yonyoucloud.com/iuap-api-auth/open-auth/selfAppAuth/getAccessToken", params); - String responseString = doGet(tokenUrl, params); - Gson gson = new Gson(); - Map result = gson.fromJson(responseString, Map.class); - - if (StringUtils.equals("00000", result.get("code").toString())) { - - Map tokenInfo = (Map) result.get("data"); - String access_token = (String) tokenInfo.get("access_token"); - // 绋庡姟鏈嶅姟-璋冪敤閿椤瑰彂绁ㄧ鐞-宸插紑绁-鐗堝紡鏂囦欢鏌ヨ鎺ュ彛 - Map map = new HashMap<>(); - // 鍙戠エ绫诲瀷 1锛氬鍊肩◣鐢靛瓙鏅氬彂绁紱 2锛氬鍊肩◣鐢靛瓙涓撶敤鍙戠エ锛 3锛氬鍊肩◣鏅氬彂绁紱 4锛氬鍊肩◣涓撶敤鍙戠エ 銆佸鍊肩◣涓撶敤鍙戠エ(鏈哄姩杞)锛 5锛氭満鍔ㄨ溅閿鍞粺涓鍙戠エ锛 8锛氬鍊肩◣鐢靛瓙鏅氬彂绁紙鎴愬搧娌癸級锛 10锛氭垚鍝佹补鏅氬彂绁紱 11锛氭垚鍝佹补涓撶敤鍙戠エ锛 15锛氫簩鎵嬭溅閿鍞粺涓鍙戠エ锛 31锛氭暟鐢典笓鐢ㄥ彂绁紱 32锛氭暟鐢垫櫘閫氬彂绁紱 33锛氭暟鐢电焊璐ㄥ彂绁(澧炲肩◣涓撶敤鍙戠エ)锛 34锛氭暟鐢电焊璐ㄥ彂绁(鏅氬彂绁)锛 - map.put("fplx", headVO.getInvoice_type()); - // 鏁扮數鍙戠エ鍙风爜 - map.put("slfphm", headVO.getFphm()); - // 鐢ㄥ弸鑷敾pdf - map.put("yypdf", "0"); - // 绋庡眬pdf - map.put("taxpdf", "1".equals(invoiceType) ? "1" : "0"); - // 绋庡眬xml - map.put("taxxml", "2".equals(invoiceType) ? "1" : "0"); - // 绋庡眬ofd - map.put("taxofd", "3".equals(invoiceType) ? "1" : "0"); -// String resString = doPost( -// "https://c1.yonyoucloud.com/iuap-api-gateway/yonbip/tax/output-tax/api/einvoice/getbsfile?access_token=" + access_token, -// map); - - String resString = doPost(getbsfileUrl + access_token,map); - gson = new Gson(); - - Map resultMap = gson.fromJson(resString, Map.class); - if (StringUtils.equals("200", resultMap.get("code").toString())) { - Map infoMap = (Map) resultMap.get("data"); - String tax = "1".equals(invoiceType) ? (String) infoMap.get("taxpdf") : "2".equals(invoiceType) ? (String) infoMap.get("taxxml") : "3".equals(invoiceType) ? (String) infoMap.get("taxofd") : ""; - if (MMValueCheck.isEmpty(tax)) { - throw new Exception("鏈煡璇㈠埌鍙戠エ淇℃伅"); - } - byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(tax); - InputStream ins = new ByteArrayInputStream(imageBytes); - String Fphm = headVO.getFphm(); - - //鍙戠エ鍙风爜+鍗曚綅鍚嶇О+鍚堝悓鍙凤紙寮绁ㄧ敵璇峰瓧娈碉級+閲戦锛堝彂绁ㄤ笂鐨勪环绋庡悎璁★級 - String filename = "1".equals(invoiceType) ? ".pdf" : "2".equals(invoiceType) ? ".xml" : "3".equals(invoiceType) ? ".ofd" : ""; + } - String ctcode=""; - HYSuperDMO dmo = new HYSuperDMO(); - IVApplogVO[] ivApplogVO=(IVApplogVO[]) dmo.queryByWhereClause(IVApplogVO.class, "fphm='"+Fphm+"' and dr=0 "); - if(ivApplogVO!=null&&ivApplogVO.length>0) { - ivApplogVO[0].getLyid();//寮绁ㄧ敵璇峰崟涓婚敭 - IVApplicationHeadVO ivApplicationHeadVO =(IVApplicationHeadVO) dmo.queryByPrimaryKey(IVApplicationHeadVO.class, ivApplogVO[0].getLyid()); - ctcode=ivApplicationHeadVO.getDef2();//鍚堝悓鍙 - } - //鍙戠エ鍙风爜+鍗曚綅鍚嶇О+鍚堝悓鍙凤紙寮绁ㄧ敵璇峰瓧娈碉級+閲戦锛堝彂绁ㄤ笂鐨勪环绋庡悎璁★級 鍚堝悓鍙穇鍗曚綅鍚嶇О_鍙戠エ鍙风爜_閲戦 + private String doGet(String requestUrl, Map paramMap) throws IOException { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(500); + cm.setDefaultMaxPerRoute(50); -// 鍚堝悓鍙穇鍗曚綅鍚嶇О_鍙戠エ鍙风爜_閲戦 + RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 连接池获取连接超时 + .setConnectTimeout(5000) // 连接建立超时 + .setSocketTimeout(20000) // 等待响应超时 + .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); - String name = ctcode+"_"+headVO.getGmfmc()+"_"+Fphm+"_"+String.valueOf(headVO.getJshj().toDouble()) + filename; - -// String name = Fphm+"_"+headVO.getGmfmc()+"_"+ctcode+"_"+String.valueOf(headVO.getJshj().toDouble()) + filename; - file = new WebFile(name, ins); - } else { - throw new Exception("鑾峰彇鍙戠エ淇℃伅澶辫触"); - } - - }else { - throw new Exception("鑾峰彇access_token澶辫触"); - } -// String url = ""; -// IVMInvoiceHeadVO headVO = headVOList.get(0); -// -// if (headVOList != null && headVOList.size() > 0) { -// url = headVO.getViewurl(); -// } -// InputStream ins = this.ncservice.download(isdoc, url, "sscivm"); -// String Fpdm = headVO.getFpdm(); -// String Fphm = headVO.getFphm(); -// String name = headVO.getFilename(); -// String filename = ".pdf"; -// if(name!=null && name.endsWith(".ofd")){ -// filename = ".ofd"; -// } -// file = new WebFile(Fpdm + "_" + Fphm + filename, ins); - } catch (BusinessException e) { - ExceptionUtils.wrappException(e); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidKeyException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (UnsupportedEncodingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return file; - } - - - private String doPost(String requestUrl, Map param) throws IOException { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - cm.setMaxTotal(500); - cm.setDefaultMaxPerRoute(50); - - RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 杩炴帴姹犺幏鍙栬繛鎺ヨ秴鏃 - .setConnectTimeout(5000) // 杩炴帴寤虹珛瓒呮椂 - .setSocketTimeout(20000) // 绛夊緟鍝嶅簲瓒呮椂 - .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); - - CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm) - .setDefaultRequestConfig(globalConfig).build(); - HttpPost post = new HttpPost(requestUrl); - post.setHeader("Content-Type", "application/json;charset=UTF-8"); - post.setEntity(new StringEntity(JSONObject.toJSONString(param), "utf-8")); - String responseString = httpClient.execute(post, response -> EntityUtils.toString(response.getEntity())); - return responseString; - - } - - - private String doGet(String requestUrl, Map paramMap) throws IOException { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - cm.setMaxTotal(500); - cm.setDefaultMaxPerRoute(50); - - RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 杩炴帴姹犺幏鍙栬繛鎺ヨ秴鏃 - .setConnectTimeout(5000) // 杩炴帴寤虹珛瓒呮椂 - .setSocketTimeout(20000) // 绛夊緟鍝嶅簲瓒呮椂 - .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); - - CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm) - .setDefaultRequestConfig(globalConfig).build(); - StringBuilder param = new StringBuilder("?"); - if (paramMap != null) { - for (Map.Entry entry : paramMap.entrySet()) { - param.append(entry.getKey()); - param.append("="); - param.append(entry.getValue()); - param.append("&"); - } - param.deleteCharAt(param.length() - 1); - } - String url = requestUrl + param; - HttpGet get = new HttpGet(url); - String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity())); - get.releaseConnection(); - return responseString; - } + CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm) + .setDefaultRequestConfig(globalConfig).build(); + StringBuilder param = new StringBuilder("?"); + if (paramMap != null) { + for (Map.Entry entry : paramMap.entrySet()) { + param.append(entry.getKey()); + param.append("="); + param.append(entry.getValue()); + param.append("&"); + } + param.deleteCharAt(param.length() - 1); + } + String url = requestUrl + param; + HttpGet get = new HttpGet(url); + String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity())); + get.releaseConnection(); + return responseString; + } + public IUAPQueryBS getQueryService() { + return NCLocator.getInstance().lookup(IUAPQueryBS.class); + } }