| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963 |
- package com.malk.qiwang.Controller;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.malk.qiwang.Service.QiWangService;
- import com.malk.qiwang.Service.TXYInvoice;
- import com.malk.qiwang.entity.CompanyTitle;
- import com.malk.qiwang.entity.InvoiceLibrary;
- import com.malk.qiwang.model.McInvoiceDto;
- import com.malk.server.aliwork.YDConf;
- import com.malk.server.aliwork.YDParam;
- import com.malk.server.common.FilePath;
- import com.malk.server.common.McException;
- import com.malk.server.common.McR;
- import com.malk.server.dingtalk.DDR_New;
- import com.malk.service.aliwork.YDClient;
- import com.malk.service.dingtalk.DDClient;
- import com.malk.service.dingtalk.DDClient_Contacts;
- import com.malk.service.dingtalk.DDClient_Workflow;
- import com.malk.utils.*;
- import com.spire.pdf.PdfCompressionLevel;
- import com.spire.pdf.PdfDocument;
- import com.spire.pdf.PdfPageBase;
- import com.spire.pdf.exporting.PdfImageInfo;
- import com.spire.pdf.graphics.PdfBitmap;
- import com.tencentcloudapi.common.Credential;
- import com.tencentcloudapi.common.exception.TencentCloudSDKException;
- import lombok.SneakyThrows;
- import lombok.extern.slf4j.Slf4j;
- import net.coobird.thumbnailator.Thumbnails;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.poi.util.IOUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.core.io.Resource;
- import org.springframework.core.io.UrlResource;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.MediaType;
- import org.springframework.http.ResponseEntity;
- import org.springframework.web.bind.annotation.*;
- import java.io.*;
- import java.math.BigDecimal;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.util.*;
- import java.util.stream.Collectors;
- @RestController
- @Slf4j
- @RequestMapping("/qw")
- public class QiWangController {
- @Autowired
- private QiWangService qiWangService;
- @Autowired
- private DDClient ddClient;
- @Autowired
- private YDClient ydClient;
- @Autowired
- private TXYInvoice txyInvoice;
- @Value("${dingtalk.operator}")
- private String operator;
- @Value("${dingtalk.downloadPath}")
- private String downloadPath;
- @Autowired
- private DDClient_Workflow ddClientWorkflow ;
- @Autowired
- private DDClient_Contacts ddClient_contacts;
- private static final String bdurl = "D://qiwang//files//";
- private static final String url = "http://47.103.203.2:9092/qiwang/";
- // private static final String bdurl = "C:\\Users\\EDY\\Desktop\\项目\\琦王\\files\\";
- //private static final String url = "http://4784d4b1.r39.cpolar.top/qiwang/";
- @PostMapping("/test")
- public McR test(@RequestBody Map map) {
- log.info("map:{}", map);
- String processInstanceId = UtilMap.getString(map, "processInstanceId");
- // 获取审批实例信息
- Map processInstance = ddClientWorkflow.getProcessInstanceId(
- ddClient.getAccessToken(), processInstanceId);
- // System.out.println("processInstance====" + processInstance);
- String businessId = (String) processInstance.get("businessId");
- System.out.println(businessId);
- //
- // if (Objects.nonNull(processInstance)) {
- // List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
- // System.out.println("formComponentValues====" + formComponentValues);
- // 存储所有处理结果
- // List<Object> allResults = new ArrayList<>();
- //
- // // 遍历所有表单组件
- // for (Map formComponentValue : formComponentValues) {
- // String id = String.valueOf(formComponentValue.get("id"));
- //
- // // 查找 TableField_1A1CDMEN8DDS0 组件
- // if ("TableField_1A1CDMEN8DDS0".equals(id)) {
- // String tableFieldValue = String.valueOf(formComponentValue.get("value"));
- // System.out.println("原始value值: " + tableFieldValue);
- // }
- //
- // try {
- // if ("DDAttachment_OF8QX7XQWWW0".equals(id)) {
- // String attachmentListStr = UtilMap.getString(formComponentValue, "value");
- // List<Map> attachmentList = (List<Map>) JSONObject.parse(attachmentListStr);
- //
- // for (Map attachment : attachmentList) {
- //
- // String fileId = UtilMap.getString(attachment, "fileId");
- // String fileType = UtilMap.getString(attachment, "fileType");
- // String fileName = UtilMap.getString(attachment, "fileName");
- //
- // //下载钉盘文件
- // String filePath = downloadPath + fileId + "." + fileType;
- // downloadDdFile(processInstanceId, fileId, filePath);
- // String hz = "qw/files/" + fileId + "." + fileType;
- // Map fileMap = new HashMap();
- // fileMap.put("url", url + hz);
- //
- // // 处理每个附件并收集结果
- // McR<Object> result = processMixedInvoice(fileMap);
- // allResults.add(result.getData());
- //// allResults.add(fileMap);
- // }
- // }
- // } catch (Exception e) {
- // log.error("解析 TableField 数据失败", e);
- // return McR.error("300", "解析数据失败");
- // }
- // }
- // 处理完所有附件后,汇总结果
- // return McR.success() ;
- //
- // }
- return McR.success();
- }
- @PostMapping ("/test3")
- public McR test3(@RequestBody Map map) {
- log.info("map:{}", map);
- String processInstanceId = UtilMap.getString(map, "processInstanceId");
- // 获取审批实例信息
- Map processInstance = ddClientWorkflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
- System.out.println("processInstance====" + processInstance);
- if (Objects.nonNull(processInstance)) {
- List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
- System.out.println("formComponentValues====" + formComponentValues);
- // 查找 TableField_1A1CDMEN8DDS0 组件
- for (Map formComponentValue : formComponentValues) {
- String id = String.valueOf(formComponentValue.get("id"));
- if ("TableField_1A1CDMEN8DDS0".equals(id)) {
- String tableFieldValue = String.valueOf(formComponentValue.get("value"));
- System.out.println("原始value值: " + tableFieldValue);
- try {
- // 解析子表数据
- List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
- // 收集所有行的结果
- List<Object> allResults = new ArrayList<>();
- // 遍历子表的每一行
- for (Map row : tableRows) {
- List<Map> rowValues = (List<Map>) row.get("rowValue");
- // 存储当前行的"是否有发票"状态和附件
- String hasInvoice = null;
- List<Map> attachmentList = null;
- // 先收集这一行的字段值
- for (Map rowItem : rowValues) {
- String key = String.valueOf(rowItem.get("key"));
- if ("DDSelectField_1ORUK0KIM5D6O".equals(key)) {
- hasInvoice = String.valueOf(rowItem.get("value"));
- }
- if ("DDAttachment_Z02OGR5QL8U8".equals(key)) {
- attachmentList = (List<Map>) rowItem.get("value");
- }
- }
- // 只有当"是否有发票"为"是"且有附件时,才处理
- if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
- // 只处理这一行的第一个附件
- Map attachment = attachmentList.get(0);
- System.out.println("fileName: " + UtilMap.getString(attachment, "fileName"));
- System.out.println("fileId: " + UtilMap.getString(attachment, "fileId"));
- String fileId = UtilMap.getString(attachment, "fileId");
- String fileType = UtilMap.getString(attachment, "fileType");
- String fileName = UtilMap.getString(attachment, "fileName");
- // 下载钉盘文件
- String filePath = downloadPath + fileId + "." + fileType;
- downloadDdFile(processInstanceId, fileId, filePath);
- String hz = "qw/files/" + fileId + "." + fileType;
- Map fileMap = new HashMap();
- fileMap.put("url", url + hz);
- // 处理发票识别
- // McR<Object> result = processMixedInvoice(fileMap);
- allResults.add(fileMap);
- } else {
- // 如果这一行不符合条件,可以添加null或跳过
- // allResults.add(null); // 如果需要保持行数对应
- }
- }
- // 所有行处理完成后统一返回
- return McR.success(allResults);
- } catch (Exception e) {
- log.error("解析子表数据失败", e);
- return McR.error("300", "解析数据失败");
- }
- }
- }
- }
- return McR.success();
- }
- @PostMapping("/test4")
- public McR test4(@RequestBody Map map) {
- log.info("map:{}", map);
- String processInstanceId = UtilMap.getString(map, "processInstanceId");
- // 获取审批实例信息
- Map processInstance = ddClientWorkflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
- // System.out.println("processInstance====" + processInstance);
- String userId = (String) processInstance.get("originatorUserId");
- System.out.println(userId);
- if (Objects.nonNull(processInstance)) {
- List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
- System.out.println("formComponentValues====" + formComponentValues);
- // 存储主表的 zt 和 je 值
- String zt = "是";
- String mainJe = null;
- // 先遍历收集主表字段值
- for (Map formComponentValue : formComponentValues) {
- String id = String.valueOf(formComponentValue.get("id"));
- if ("DDSelectField_4SITXLYUEO80".equals(id)) {
- zt = String.valueOf(formComponentValue.get("value"));
- }
- if ("MoneyField_3QZLY8BD3780".equals(id)) {
- mainJe = String.valueOf(formComponentValue.get("value"));
- }
- }
- // 判断主表状态
- if ("否".equals(zt)) {
- // 当为"否"时,直接返回 je 字段值
- Map<String, Object> result = new HashMap<>();
- result.put("je", mainJe);
- result.put("status", "否");
- Map body = new HashMap<>();
- body.put("processInstanceId",processInstanceId);
- body.put("text", result);
- body.put("commentUserId",userId);
- // body.put("file",fileMap);
- //
- String re =UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/comments",ddClient.initTokenHeader(),null,body);
- return McR.success(result);
- }
- // 当为"是"时,继续处理子表附件
- if ("是".equals(zt)) {
- // 查找 TableField_1A1CDMEN8DDS0 组件
- for (Map formComponentValue : formComponentValues) {
- String id = String.valueOf(formComponentValue.get("id"));
- if ("TableField_1A1CDMEN8DDS0".equals(id)) {
- String tableFieldValue = String.valueOf(formComponentValue.get("value"));
- System.out.println("原始value值: " + tableFieldValue);
- try {
- // 解析子表数据
- List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
- // 收集所有发票识别结果
- List<Object> allResults = new ArrayList<>();
- // 遍历子表的每一行
- for (Map row : tableRows) {
- List<Map> rowValues = (List<Map>) row.get("rowValue");
- // 先检查这一行的"是否有发票"字段值
- String hasInvoice = null;
- List<Map> attachmentList = null;
- for (Map rowItem : rowValues) {
- String key = String.valueOf(rowItem.get("key"));
- // 获取"是否有发票"字段的值
- if ("DDSelectField_1ORUK0KIM5D6O".equals(key)) {
- hasInvoice = String.valueOf(rowItem.get("value"));
- }
- // 获取附件字段
- if ("DDAttachment_Z02OGR5QL8U8".equals(key)) {
- attachmentList = (List<Map>) rowItem.get("value");
- }
- }
- // 只有当"是否有发票"为"是"时,才处理附件
- if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
- // 遍历这一行的所有附件
- for (Map attachment : attachmentList) {
- System.out.println("fileName: " + UtilMap.getString(attachment, "fileName"));
- System.out.println("fileId: " + UtilMap.getString(attachment, "fileId"));
- String fileId = UtilMap.getString(attachment, "fileId");
- String fileType = UtilMap.getString(attachment, "fileType");
- String fileName = UtilMap.getString(attachment, "fileName");
- // 下载钉盘文件
- String filePath = downloadPath + fileId + "." + fileType;
- downloadDdFile(processInstanceId, fileId, filePath);
- String hz = "qw/files/" + fileId + "." + fileType;
- Map fileMap = new HashMap();
- fileMap.put("url", url + hz);
- // 处理发票识别并收集结果
- McR<Object> result = processMixedInvoice(fileMap);
- allResults.add(result.getData());
- }
- }
- }
- Map body = new HashMap<>();
- body.put("processInstanceId",processInstanceId);
- body.put("text", JSON.toJSONString(allResults));
- body.put("commentUserId",userId);
- String re =UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/comments",ddClient.initTokenHeader(),null,body);
- // 所有附件处理完成后统一返回
- return McR.success(allResults);
- } catch (Exception e) {
- log.error("解析子表数据失败", e);
- return McR.error("300", "解析数据失败");
- }
- }
- }
- }
- }
- return McR.success();
- }
- @PostMapping("/test2")
- public McR test2(@RequestBody Map map) {
- log.info("map:{}", map);
- // String procInstId = String.valueOf(map.get("procInstId"));
- String processInstanceId = UtilMap.getString(map, "processInstanceId");
- // 获取审批实例信息
- Map processInstance = ddClientWorkflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
- System.out.println("processInstance====" + processInstance);
- // Map body = new HashMap<>();
- // body.put("processInstanceId",processInstanceId);
- // body.put("text", "发票信息如下:\n\n1. 电子发票(普通发票) | 全电普通发票 | 发票号码:26312000001701010876 | 开票日期:2026-03-20 | 金额:103.28 | 不含税:94.75 | 税额:8.53 | 购买方:罗庆宇(个人) | 销售方:上海聪雷贸易有限公司 | 税号:91310107MA1G0XPA4K\n\n2. 电子发票(普通发票) | 全电普通发票 | 发票号码:26442000003207012931 | 开票日期:2026-03-25 | 金额:239.00 | 不含税:211.50 | 税额:27.50 | 购买方:罗庆宇 | 销售方:广州延阳电子商务有限公司 | 税号:91440101MA5AWRGH4L\n\n3. 电子发票(普通发票) | 全电普通发票 | 发票号码:26332000002236540291 | 开票日期:2026-03-20 | 金额:518.00 | 不含税:458.41 | 税额:59.59 | 购买方:罗庆宇(个人) | 销售方:杭州亿奥网络科技有限公司 | 税号:91330108MA28MK7K08\n\n4. 电子发票(普通发票) | 全电普通发票 | 发票号码:26442000003052085371 | 开票日期:2026-03-21 | 金额:183.00 | 不含税:161.95 | 税额:21.05 | 购买方:罗庆宇 | 销售方:广州梓夕贸易有限公司 | 税号:91440101MA59M7J471");
- // body.put("commentUserId","16441447913471369");
- //// body.put("file",fileMap);
- //
- // String re =UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/comments",ddClient.initTokenHeader(),null,body);
- // System.out.println("re"+ re);
- // if (Objects.nonNull(processInstance)) {
- // Map formData = new HashMap<>();
- // String title = String.valueOf(processInstance.get("title"));
- // String type = "";
- // List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
- // }
- return McR.success();
- }
- @GetMapping("/files/{fileId}")
- public ResponseEntity<Resource> getFileResource(
- @PathVariable String fileId,
- @RequestParam(defaultValue = "download") String option) throws IOException {
- // 根据fileId获取实际文件路径,这里简化处理,实际可能需要从数据库查询
- Path filePath = Paths.get(bdurl).resolve(fileId).normalize();
- // 检查文件是否存在
- if (!Files.exists(filePath)) {
- return ResponseEntity.notFound().build();
- }
- // 创建Resource对象
- Resource resource = new UrlResource(filePath.toUri());
- // 根据选项设置响应头
- HttpHeaders headers = new HttpHeaders();
- if ("preview".equalsIgnoreCase(option)) {
- // 预览模式 - 尝试确定内容类型
- String contentType = Files.probeContentType(filePath);
- // 强制修正 PDF 的 Content-Type
- if (filePath.toString().toLowerCase().endsWith(".pdf")) {
- contentType = "application/pdf";
- } else if (contentType == null) {
- contentType = "application/octet-stream";
- }
- headers.setContentType(MediaType.parseMediaType(contentType));
- headers.add("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
- headers.add("X-Content-Type-Options", "nosniff"); // 防止浏览器忽略 Content-Type
- } else {
- // 下载模式 - 默认处理
- headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
- headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
- }
- return ResponseEntity.ok()
- .headers(headers)
- .contentLength(resource.contentLength())
- .body(resource);
- }
- @PostMapping("/test1")
- public McR test1(@RequestBody Map<String, String> data) throws TencentCloudSDKException {
- log.info("test: {}", data);
- McException.assertParamException_Null(data, "url");
- // String image = ydClient.convertTemporaryUrl(data.get("url"));
- String image = data.get("url");
- log.info("混票识别, 免登地址, {}", image);
- // 非PDF, 且内存大于3M, 压缩后上传
- if (UtilMap.getFloat(data, "size") > 3.0f && !UtilMap.getBoolean(data, "isPdf")) {
- image = imageUrlConvertBase64(image);
- }
- if (UtilMap.getFloat(data, "size") > 6.0f && UtilMap.getBoolean(data, "isPdf")) {
- image = pdfUrlConvertBase64(image);
- }
- List<Map> invoices = (List<Map>) txyInvoice.doRecognizeGeneralInvoice(image).get("MixedInvoiceItems");
- System.out.println("invoices===="+invoices);
- List<String> nos=new ArrayList<>();
- List<McInvoiceDto> result = invoices.stream().map(item -> {
- Map prop = UtilMap.getMap(UtilMap.getMap(item, "SingleInvoiceInfos"), UtilMap.getString(item, "SubType"));
- // List<Map<String, Object>> vatInvoiceItemInfos = UtilMap.getList(prop, "VatInvoiceItemInfos");
- // if (!vatInvoiceItemInfos.isEmpty()) {
- // String taxRate = UtilMap.getString(vatInvoiceItemInfos.get(0), "TaxRate");
- // System.out.println("TaxRate: " + taxRate); // 输出: 9%
- // }
- String taxRate = null;
- // List<Map<String, Object>> vatInvoiceItemInfos = UtilMap.getList(prop, "VatInvoiceItemInfos");
- // 优先使用 VatInvoiceItemInfos,如果为空则使用 VatElectronicItems
- List<Map<String, Object>> vatInvoiceItemInfos =
- UtilMap.getList(prop, "VatInvoiceItemInfos") != null && !UtilMap.getList(prop, "VatInvoiceItemInfos").isEmpty()
- ? UtilMap.getList(prop, "VatInvoiceItemInfos")
- : UtilMap.getList(prop, "VatElectronicItems");
- // if (!vatInvoiceItemInfos.isEmpty()) {
- // taxRate = UtilMap.getString(vatInvoiceItemInfos.get(0), "TaxRate");
- // }
- if (!vatInvoiceItemInfos.isEmpty()) {
- String originalTaxRate = UtilMap.getString(vatInvoiceItemInfos.get(0), "TaxRate");
- // 判断是否为有效数字(包括带%号的格式,如"9%")
- if (StringUtils.isNotBlank(originalTaxRate)) {
- // 移除百分号并尝试解析为数字
- String cleanedTaxRate = originalTaxRate.replace("%", "").trim();
- try {
- // 尝试转换为数字
- new BigDecimal(cleanedTaxRate);
- taxRate = originalTaxRate; // 保持原值(可能带%)
- } catch (NumberFormatException e) {
- // 如果不是数字(如"不征税"、"免税"等),赋值为"0"
- taxRate = "0";
- log.debug("税率格式异常,原始值: {}, 已设置为0", originalTaxRate);
- }
- } else {
- taxRate = "0";
- }
- } else {
- taxRate = "0";
- }
- System.out.println("prop====="+prop);
- String no=UtilMap.getString(prop, "Number");
- if(nos.contains(no)){
- return null;
- }
- nos.add(no);
- String kind = UtilMap.getString(item, "TypeDescription");
- String invoiceName = UtilMap.getString(item, "SubTypeDescription");
- if (kind.equals("全电发票")) {
- if(invoiceName.contains("铁路电子客票")){
- kind="火车票";
- } else if(invoiceName.contains("机票行程单")){
- kind="机票行程单";
- } else if (invoiceName.contains("专用发票")) {
- kind="全电专用发票";
- }else {
- kind="全电普通发票";
- }
- }
- if (kind.equals("增值税发票")) {
- if(invoiceName.contains("区块链电子发票")){
- kind="区块链电子发票";
- } else if(invoiceName.contains("增值税专用发票")){
- kind="增值税专用发票";
- } else if(invoiceName.contains("增值税普通发票")){
- kind="增值税普通发票";
- } else if (invoiceName.contains("增值税电子专用发票")) {
- kind="增值税电子专用发票";
- } else if (invoiceName.contains("增值税电子普通发票")) {
- kind="增值税电子普通发票";
- }else {
- kind="增值税普通发票";
- }
- }
- // ppExt: 通用字段定义
- McInvoiceDto invoiceDto = McInvoiceDto.builder()
- .name(UtilMap.getString(item, "SubTypeDescription"))
- .kindName(kind)
- .taxRate(taxRate)
- .kind(UtilMap.getInt(item, "Type"))
- .code(UtilMap.getString(prop, "Code"))
- .serial(UtilMap.getString(prop, "Number"))
- .date(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "Date")))
- .checkCode(UtilMap.getString(prop, "CheckCode"))
- // ppExt: 多明细行时, 优先取值合计 [全电票返回了subTotal字段, 但值为空] // 2025.5.12 去除小计金额,并去除发票编号重复数据
- .amount(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Total", "Fare"))) // "SubTotal",
- .tax(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Tax"))) // "SubTax",
- .excludingTax(UtilNumber.setBigDecimal(UtilMap.getString(prop, "PretaxAmount")))
- .buyerName(StringUtils.isBlank(guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))?"上海能辉科技股份有限公司":guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))
- // ppExt: 中央非税未返回税号官方说明: 非税发票理论是没有税号的,图片中属于信用代码
- .buyerTaxId(StringUtils.isBlank(UtilMap.getString(prop, "BuyerTaxID"))?"": UtilMap.getString(prop, "BuyerTaxID"))
- .sellerName(guyuanNameRepalce(UtilMap.getString_first(prop, "Seller", "Issuer"))) // 行程单: 填开单位
- .sellerTaxId(UtilMap.getString_first(prop, "SellerTaxID", "AgentCode")) // 行程单: 销售单位代号
- .passengerName(UtilMap.getString_first(prop, "Name", "UserName")) // 火车票, 行程单
- // 交通出行
- .seatType(UtilMap.getString(prop, "Seat"))
- .departureTime(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"))
- .departurePort(UtilMap.getString_first(prop, "StationGetOn", "Entrance", "Place")) // 火车票: 出发车站, 过路过桥费: 入口, 出租车: 发票所在地
- .arrivePort(UtilMap.getString_first(prop, "StationGetOff", "Exit")) // 行程单, 火车票: 到达车站, 过路过桥费: 出口
- .trainNo(UtilMap.getString_first(prop, "TrainNumber", "LicensePlate")) // 火车票: 车次, 出租车: 车牌号
- .insuranceCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "Insurance")))) // 行程单: 保险费
- .fuelCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "FuelSurcharge")))) // 行程单: 燃油附加费
- .constructionCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "AirDevelopmentFund")))) // 行程单: 民航发展基金
- .build();
- // ppExt: 机票行程单, 行程与座位信息在明细内
- if ("机票行程单".equals(kind)) {
- invoiceDto.setSellerName(UtilMap.getString_first(prop, "Issuer"));
- invoiceDto.setSellerTaxId(UtilMap.getString_first(prop, "Seller"));
- Map flight = (Map) UtilMap.getList(prop, "FlightItems").get(0);
- invoiceDto.setDepartureTime(UtilString.replaceDateZH_cn(UtilMap.getString(item, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"));
- invoiceDto.setDeparturePort(UtilMap.getString(flight, "StationGetOn"));
- invoiceDto.setArrivePort(UtilMap.getString(flight, "StationGetOff"));
- invoiceDto.setSeatType(UtilMap.getString(flight, "Seat"));
- }
- if ("出租车发票".equals(item.get("TypeDescription"))) {
- // 上下车时间
- invoiceDto.setDepartureTime(UtilMap.getString(prop, "TimeGetOn") + " ~ " + UtilMap.getString(prop, "TimeGetOff"));
- }
- return invoiceDto;
- }).filter(item -> item!=null).collect(Collectors.toList());
- return McR.success(McInvoiceDto.formatResponse(result));
- }
- @PostMapping("invoice-iv2")
- McR invoice_iv2(@RequestBody Map<String, String> data) throws TencentCloudSDKException {
- McException.assertParamException_Null(data, "url");
- String image = ydClient.convertTemporaryUrl(data.get("url"));
- log.info("混票识别, 免登地址, {}", image);
- // 非PDF, 且内存大于3M, 压缩后上传
- if (UtilMap.getFloat(data, "size") > 3.0f && !UtilMap.getBoolean(data, "isPdf")) {
- image = imageUrlConvertBase64(image);
- }
- if (UtilMap.getFloat(data, "size") > 6.0f && UtilMap.getBoolean(data, "isPdf")) {
- image = pdfUrlConvertBase64(image);
- }
- List<Map> invoices = (List<Map>) txyInvoice.doRecognizeGeneralInvoice(image).get("MixedInvoiceItems");
- List<String> nos=new ArrayList<>();
- List<McInvoiceDto> result = invoices.stream().map(item -> {
- Map prop = UtilMap.getMap(UtilMap.getMap(item, "SingleInvoiceInfos"), UtilMap.getString(item, "SubType"));
- String no=UtilMap.getString(prop, "Number");
- if(nos.contains(no)){
- return null;
- }
- nos.add(no);
- String kind = UtilMap.getString(item, "TypeDescription");
- String invoiceName = UtilMap.getString(item, "SubTypeDescription");
- if (kind.equals("全电发票")) {
- if(invoiceName.contains("铁路电子客票")){
- kind="火车票";
- } else if(invoiceName.contains("机票行程单")){
- kind="机票行程单";
- } else if (invoiceName.contains("专用发票")) {
- kind="全电专用发票";
- }else {
- kind="全电普通发票";
- }
- }
- if (kind.equals("增值税发票")) {
- if(invoiceName.contains("区块链电子发票")){
- kind="区块链电子发票";
- } else if(invoiceName.contains("增值税专用发票")){
- kind="增值税专用发票";
- } else if(invoiceName.contains("增值税普通发票")){
- kind="增值税普通发票";
- } else if (invoiceName.contains("增值税电子专用发票")) {
- kind="增值税电子专用发票";
- } else if (invoiceName.contains("增值税电子普通发票")) {
- kind="增值税电子普通发票";
- }else {
- kind="增值税普通发票";
- }
- }
- // ppExt: 通用字段定义
- McInvoiceDto invoiceDto = McInvoiceDto.builder()
- .name(UtilMap.getString(item, "SubTypeDescription"))
- .kindName(kind)
- .kind(UtilMap.getInt(item, "Type"))
- .code(UtilMap.getString(prop, "Code"))
- .serial(UtilMap.getString(prop, "Number"))
- .date(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "Date")))
- .checkCode(UtilMap.getString(prop, "CheckCode"))
- // ppExt: 多明细行时, 优先取值合计 [全电票返回了subTotal字段, 但值为空] // 2025.5.12 去除小计金额,并去除发票编号重复数据
- .amount(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Total", "Fare"))) // "SubTotal",
- .tax(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Tax"))) // "SubTax",
- .excludingTax(UtilNumber.setBigDecimal(UtilMap.getString(prop, "PretaxAmount")))
- .buyerName(StringUtils.isBlank(guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))?"上海能辉科技股份有限公司":guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))
- // ppExt: 中央非税未返回税号官方说明: 非税发票理论是没有税号的,图片中属于信用代码
- .buyerTaxId(StringUtils.isBlank(UtilMap.getString(prop, "BuyerTaxID"))?"": UtilMap.getString(prop, "BuyerTaxID"))
- .sellerName(guyuanNameRepalce(UtilMap.getString_first(prop, "Seller", "Issuer"))) // 行程单: 填开单位
- .sellerTaxId(UtilMap.getString_first(prop, "SellerTaxID", "AgentCode")) // 行程单: 销售单位代号
- .passengerName(UtilMap.getString_first(prop, "Name", "UserName")) // 火车票, 行程单
- // 交通出行
- .seatType(UtilMap.getString(prop, "Seat"))
- .departureTime(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"))
- .departurePort(UtilMap.getString_first(prop, "StationGetOn", "Entrance", "Place")) // 火车票: 出发车站, 过路过桥费: 入口, 出租车: 发票所在地
- .arrivePort(UtilMap.getString_first(prop, "StationGetOff", "Exit")) // 行程单, 火车票: 到达车站, 过路过桥费: 出口
- .trainNo(UtilMap.getString_first(prop, "TrainNumber", "LicensePlate")) // 火车票: 车次, 出租车: 车牌号
- .insuranceCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "Insurance")))) // 行程单: 保险费
- .fuelCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "FuelSurcharge")))) // 行程单: 燃油附加费
- .constructionCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "AirDevelopmentFund")))) // 行程单: 民航发展基金
- .build();
- // ppExt: 机票行程单, 行程与座位信息在明细内
- if ("机票行程单".equals(kind)) {
- invoiceDto.setSellerName(UtilMap.getString_first(prop, "Issuer"));
- invoiceDto.setSellerTaxId(UtilMap.getString_first(prop, "Seller"));
- Map flight = (Map) UtilMap.getList(prop, "FlightItems").get(0);
- invoiceDto.setDepartureTime(UtilString.replaceDateZH_cn(UtilMap.getString(item, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"));
- invoiceDto.setDeparturePort(UtilMap.getString(flight, "StationGetOn"));
- invoiceDto.setArrivePort(UtilMap.getString(flight, "StationGetOff"));
- invoiceDto.setSeatType(UtilMap.getString(flight, "Seat"));
- }
- if ("出租车发票".equals(item.get("TypeDescription"))) {
- // 上下车时间
- invoiceDto.setDepartureTime(UtilMap.getString(prop, "TimeGetOn") + " ~ " + UtilMap.getString(prop, "TimeGetOff"));
- }
- return invoiceDto;
- }).filter(item -> item!=null).collect(Collectors.toList());
- return McR.success(McInvoiceDto.formatResponse(result));
- }
- //校验查重
- @PostMapping("invoice-va")
- McR invoice_va(@RequestBody Map data) {
- McException.assertParamException_Null(data, "param");
- List<McInvoiceDto> invoices = JSON.parseArray(JSON.toJSONString(data.get("param")), McInvoiceDto.class);
- log.info("发票查重, 验真, {}", invoices);
- invoices.forEach(UtilMc.consumerWithIndex((item, index) -> {
- McInvoiceDto dto = (McInvoiceDto) item;
- String invoiceNo = dto.getSerial(); // 唯一标识, 发票号码
- String serial = "第【" + (index + 1) + "】张发票";
- validateBuyer(dto.getBuyerName(), serial + "有疑问");
- McException.assertAccessException(StringUtils.isBlank(invoiceNo), serial + ", 识别结果为空, 请检查!");
- YDParam ydParam = YDParam.builder()
- .formUuid("FORM-W2A66Z910O9B3LP9C6IYUDPRVWY62DO0YHIILY")
- .searchFieldJson(JSON.toJSONString(UtilMap.map("radioField_liihyrtb, textField_liihyrt8", "否", invoiceNo)))
- .build();
- List<String> idList = (List<String>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form_id).getData();
- if (idList.size() > 0) {
- McException.exceptionAccess(serial + "已存在, 请勿重复提交!");
- }
- // prd 仅仅识别增值税普通发票
- // if (dto.getName().contains("普通发票")) {
- // String serialTips = serial + "有疑问";
- // try {
- // // ppExt: 识别与验真后抬头对比 [全电票, 新版本识别接口, 返回名称为: 电子发票(普通发票) 不包含全电标识, 发类型为: 全电发票. 注意取值]
- // Map rsp = txyInvoice.doVatInvoiceVerifyNew(dto.getKindName(), dto.getCode(), invoiceNo, dto.getDate(), String.valueOf(dto.getAmount()), dto.getCheckCode(), String.valueOf(dto.getExcludingTax()), serialTips);
- // Map invoice = (Map) rsp.get("Invoice");
- // McException.assertAccessException(!dto.getBuyerName().equals(guyuanNameRepalce(invoice.get("BuyerName").toString())), serialTips + ", 购买方名称不匹配!");
- // McException.assertAccessException(!dto.getBuyerTaxId().equals(invoice.get("BuyerTaxCode")), serialTips + ", 购买方税号不匹配!");
- // McException.assertAccessException(!dto.getSellerName().equals(guyuanNameRepalce(invoice.get("SellerName").toString())), serialTips + ", 销售方名称不匹配!");
- // McException.assertAccessException(!dto.getSellerTaxId().equals(invoice.get("SellerTaxCode")), serialTips + ", 销售方税号不匹配!");
- // } catch (TencentCloudSDKException e) {
- // log.error(e.getMessage(), e);
- // // prd: 上传发票为假发票时,提示:该发票有疑问,请联系财务人员
- // String message = e.getMessage();
- // // ppExt: 已经是新版本接口, 过滤提示 [官方答复: 提示不会检测您是否使用的是新版,所有的用户都会提示, 忽略即可]
- // if (message.contains("温馨提示")) {
- // message = message.split("温馨提示")[0];
- // }
- // if (message.contains("发票不存在")) {
- // message = "有疑问,请联系财务人员";
- // }
- // McException.exceptionAccess(serial + message);
- // }
- // }
- }));
- return McR.success();
- }
- /// url压缩转base64
- @SneakyThrows
- private String imageUrlConvertBase64(String imageUrl) {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- // scale(比例), outputQuality(质量)
- Thumbnails.fromURLs(Arrays.asList(new URL(imageUrl))).scale(0.5f).outputQuality(0.25f).toOutputStream(out);
- InputStream inputStream = new ByteArrayInputStream(out.toByteArray());
- //转换为base64
- byte[] bytes = IOUtils.toByteArray(inputStream);
- return Base64.getEncoder().encodeToString(bytes);
- }
- private static String guyuanNameRepalce(String name) {
- name=name.replaceAll(" ","");
- if (name.contains("谷元")) {
- return UtilString.replaceBracketIsWhole(name);
- } else {
- return UtilString.replaceBracketIsSemiangle(name);
- }
- }
- @Autowired
- private FilePath filePath;
- /// PDF压缩转base64
- @SneakyThrows
- private String pdfUrlConvertBase64(String pdfUrl) {
- String fileName = "tmp_" + new Date().getTime() + ".pdf";
- // 下载文件
- File file = UtilFile.mkdirIfNot(fileName, filePath.getPath().getTmp());
- UtilHttp.doDownload(pdfUrl, file);
- // PDF压缩
- PdfDocument doc = new PdfDocument(); // 创建PdfDocument类的对象
- doc.loadFromFile(file.getAbsolutePath()); // 加载PDF文档
- doc.getFileInfo().setIncrementalUpdate(false); // 禁用增量更新
- doc.setCompressionLevel(PdfCompressionLevel.Normal); // 将压缩级别设置为最佳
- // 遍历文档页面
- for (int i = 0; i < doc.getPages().getCount(); i++) {
- PdfPageBase page = doc.getPages().get(i); // 获取指定页面
- PdfImageInfo[] images = page.getImagesInfo(); // 获取每个页面的图像信息集合
- // 遍历集合中的所有项目
- if (images != null && images.length > 0)
- for (int j = 0; j < images.length; j++) {
- PdfImageInfo image = images[j]; // 获取指定图片
- PdfBitmap bp = new PdfBitmap(image.getImage());
- bp.setQuality(30); // 设置压缩质量
- page.replaceImage(j, bp); // 将原始图像替换为压缩图像
- }
- }
- // 将结果文档保存至另一个PDF文档中: 覆盖
- doc.saveToFile(file.getAbsolutePath());
- doc.close();
- // PDF转base64, 无需透出本地文件地址
- String base64 = UtilFile.fileToBase64(file.getAbsolutePath());
- // 删除临时PDF文件
- UtilFile.deleteFile(file.getAbsolutePath());
- return base64;
- }
- private void validateBuyer(String BuyerName, String tips) {
- List<String> corpNames = Arrays.asList(
- "谷元(上海)文化科技有限责任公司",
- "上海爱鱼文化传媒有限公司",
- "上海渔米可禧文化传媒有限公司",
- "上海巧豆文化传媒有限公司",
- "钰鸿文化创意(上海)有限公司",
- "上海攸元文化科技有限公司",
- "上海盈田演出经纪有限公司",
- "上海小蝠文化科技有限公司",
- "沐田居海(厦门)文化传媒有限公司",
- "北京元环文化科技有限责任公司",
- "厦门攸元文化科技有限公司",
- "厦门亨有文化科技有限公司",
- "厦门银雀思汀文化传媒有限公司",
- "上海渝泽信息科技有限公司",
- "厦门神谷飞流影视传媒有限公司",
- "厦门谷钛数字科技有限公司",
- "上海观情科技有限公司",
- "渔米可禧文化传媒(香港)有限公司",
- "杭州渔米可禧文化传媒有限公司");
- McException.assertAccessException(!corpNames.contains(BuyerName), tips + ", 购买方名称不合法!");
- }
- //下载钉钉OA审批单附件
- private void downloadDdFile(String processInstanceId,String fileId,String downloadPath){
- try {
- Map body = new HashMap();
- body.put("processInstanceId",processInstanceId);
- body.put("fileId",fileId);
- DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/spaces/files/urls/download", ddClient.initTokenHeader(), null, body, DDR_New.class);
- //2、执行下载
- Map result = (Map) ddrNew.getResult();
- String downloadUri = UtilMap.getString(result, "downloadUri");
- downloadFile(downloadUri,downloadPath);
- }catch (Exception e){
- throw new RuntimeException(e);
- }
- }
- //文件下载到本地
- private void downloadFile(String downloadUri,String downloadPath){
- try {
- URL url = new URL(downloadUri);
- HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
- int responseCode = httpConn.getResponseCode();
- // 检查HTTP响应代码是否为200
- if (responseCode == HttpURLConnection.HTTP_OK) {
- InputStream inputStream = httpConn.getInputStream();
- FileOutputStream outputStream = new FileOutputStream(downloadPath);
- byte[] buffer = new byte[4096];
- int bytesRead = -1;
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- outputStream.write(buffer, 0, bytesRead);
- }
- outputStream.close();
- inputStream.close();
- } else {
- System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
- }
- httpConn.disconnect();
- }catch (Exception e){
- throw new RuntimeException(e);
- }
- }
- /**
- * 私有化方法:混票识别处理
- * @param data 包含url、size、isPdf的Map参数
- * @return 识别结果
- */
- private McR<Object> processMixedInvoice(Map<String, Object> data) throws TencentCloudSDKException {
- McException.assertParamException_Null(data, "url");
- String image = String.valueOf(data.get("url"));
- log.info("混票识别, 免登地址, {}", image);
- // 非PDF, 且内存大于3M, 压缩后上传
- if (UtilMap.getFloat(data, "size") > 3.0f && !UtilMap.getBoolean(data, "isPdf")) {
- image = imageUrlConvertBase64(image);
- }
- if (UtilMap.getFloat(data, "size") > 6.0f && UtilMap.getBoolean(data, "isPdf")) {
- image = pdfUrlConvertBase64(image);
- }
- List<Map> invoices = (List<Map>) txyInvoice.doRecognizeGeneralInvoice(image).get("MixedInvoiceItems");
- System.out.println("invoices====="+invoices);
- List<String> nos = new ArrayList<>();
- List<McInvoiceDto> result = invoices.stream().map(item -> {
- Map prop = UtilMap.getMap(UtilMap.getMap(item, "SingleInvoiceInfos"), UtilMap.getString(item, "SubType"));
- String no = UtilMap.getString(prop, "Number");
- if (nos.contains(no)) {
- return null;
- }
- nos.add(no);
- String kind = UtilMap.getString(item, "TypeDescription");
- String invoiceName = UtilMap.getString(item, "SubTypeDescription");
- if (kind.equals("全电发票")) {
- if (invoiceName.contains("铁路电子客票")) {
- kind = "火车票";
- } else if (invoiceName.contains("机票行程单")) {
- kind = "机票行程单";
- } else if (invoiceName.contains("专用发票")) {
- kind = "全电专用发票";
- } else {
- kind = "全电普通发票";
- }
- }
- if (kind.equals("增值税发票")) {
- if (invoiceName.contains("区块链电子发票")) {
- kind = "区块链电子发票";
- } else if (invoiceName.contains("增值税专用发票")) {
- kind = "增值税专用发票";
- } else if (invoiceName.contains("增值税普通发票")) {
- kind = "增值税普通发票";
- } else if (invoiceName.contains("增值税电子专用发票")) {
- kind = "增值税电子专用发票";
- } else if (invoiceName.contains("增值税电子普通发票")) {
- kind = "增值税电子普通发票";
- } else {
- kind = "增值税普通发票";
- }
- }
- McInvoiceDto invoiceDto = McInvoiceDto.builder()
- .name(UtilMap.getString(item, "SubTypeDescription"))
- .kindName(kind)
- .kind(UtilMap.getInt(item, "Type"))
- .code(UtilMap.getString(prop, "Code"))
- .serial(UtilMap.getString(prop, "Number"))
- .date(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "Date")))
- .checkCode(UtilMap.getString(prop, "CheckCode"))
- .amount(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Total", "Fare")))
- .tax(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Tax")))
- .excludingTax(UtilNumber.setBigDecimal(UtilMap.getString(prop, "PretaxAmount")))
- .buyerName(StringUtils.isBlank(guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))
- ? "上海能辉科技股份有限公司" : guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))
- .buyerTaxId(StringUtils.isBlank(UtilMap.getString(prop, "BuyerTaxID"))
- ? "" : UtilMap.getString(prop, "BuyerTaxID"))
- .sellerName(guyuanNameRepalce(UtilMap.getString_first(prop, "Seller", "Issuer")))
- .sellerTaxId(UtilMap.getString_first(prop, "SellerTaxID", "AgentCode"))
- .passengerName(UtilMap.getString_first(prop, "Name", "UserName"))
- .seatType(UtilMap.getString(prop, "Seat"))
- .departureTime(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "DateGetOn"))
- + " " + UtilMap.getString(prop, "TimeGetOn"))
- .departurePort(UtilMap.getString_first(prop, "StationGetOn", "Entrance", "Place"))
- .arrivePort(UtilMap.getString_first(prop, "StationGetOff", "Exit"))
- .trainNo(UtilMap.getString_first(prop, "TrainNumber", "LicensePlate"))
- .insuranceCosts(UtilNumber.setBigDecimal(UtilMap.getString(prop, "Insurance")))
- .fuelCosts(UtilNumber.setBigDecimal(UtilMap.getString(prop, "FuelSurcharge")))
- .constructionCosts(UtilNumber.setBigDecimal(UtilMap.getString(prop, "AirDevelopmentFund")))
- .build();
- if ("机票行程单".equals(kind)) {
- invoiceDto.setSellerName(UtilMap.getString_first(prop, "Issuer"));
- invoiceDto.setSellerTaxId(UtilMap.getString_first(prop, "Seller"));
- Map flight = (Map) UtilMap.getList(prop, "FlightItems").get(0);
- invoiceDto.setDepartureTime(UtilString.replaceDateZH_cn(UtilMap.getString(item, "DateGetOn"))
- + " " + UtilMap.getString(prop, "TimeGetOn"));
- invoiceDto.setDeparturePort(UtilMap.getString(flight, "StationGetOn"));
- invoiceDto.setArrivePort(UtilMap.getString(flight, "StationGetOff"));
- invoiceDto.setSeatType(UtilMap.getString(flight, "Seat"));
- }
- if ("出租车发票".equals(item.get("TypeDescription"))) {
- invoiceDto.setDepartureTime(UtilMap.getString(prop, "TimeGetOn")
- + " ~ " + UtilMap.getString(prop, "TimeGetOff"));
- }
- return invoiceDto;
- }).filter(Objects::nonNull).collect(Collectors.toList());
- return McR.success(McInvoiceDto.formatResponse(result));
- }
- }
|