IVController.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. package com.malk.xzkj.controller;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.malk.xzkj.model.McInvoiceDto;
  5. import com.malk.xzkj.model.McInvoiceKind;
  6. import com.malk.xzkj.config.TXYConf;
  7. import com.malk.server.aliwork.YDConf;
  8. import com.malk.server.aliwork.YDParam;
  9. import com.malk.server.common.FilePath;
  10. import com.malk.server.common.McException;
  11. import com.malk.server.common.McR;
  12. import com.malk.server.dingtalk.DDR_New;
  13. import com.malk.service.aliwork.YDClient;
  14. import com.malk.service.aliwork.YDService;
  15. import com.malk.utils.*;
  16. import com.malk.xzkj.service.IvYdService;
  17. import com.malk.xzkj.service.TXYInvoice;
  18. import com.spire.pdf.PdfCompressionLevel;
  19. import com.spire.pdf.PdfDocument;
  20. import com.spire.pdf.PdfPageBase;
  21. import com.spire.pdf.exporting.PdfImageInfo;
  22. import com.spire.pdf.graphics.PdfBitmap;
  23. import com.tencentcloudapi.common.exception.TencentCloudSDKException;
  24. import lombok.SneakyThrows;
  25. import lombok.extern.slf4j.Slf4j;
  26. import net.coobird.thumbnailator.Thumbnails;
  27. import org.apache.commons.lang3.StringUtils;
  28. import org.apache.poi.util.IOUtils;
  29. import org.springframework.beans.factory.annotation.Autowired;
  30. import org.springframework.web.bind.annotation.PostMapping;
  31. import org.springframework.web.bind.annotation.RequestBody;
  32. import org.springframework.web.bind.annotation.RequestMapping;
  33. import org.springframework.web.bind.annotation.RestController;
  34. import javax.servlet.http.HttpServletRequest;
  35. import java.io.ByteArrayInputStream;
  36. import java.io.ByteArrayOutputStream;
  37. import java.io.File;
  38. import java.io.InputStream;
  39. import java.math.BigDecimal;
  40. import java.math.RoundingMode;
  41. import java.net.URL;
  42. import java.util.*;
  43. import java.util.stream.Collectors;
  44. /**
  45. * 错误抛出与拦截详见CatchException
  46. */
  47. @Slf4j
  48. @RestController
  49. @RequestMapping("/iv/")
  50. public class IVController {
  51. @Autowired
  52. private TXYInvoice txyInvoice;
  53. @Autowired
  54. private IvYdService ivYdService;
  55. @Autowired
  56. private YDClient ydClient;
  57. /// 优先获取字段, 新版本接口已支持字段返回
  58. private String findValue(List<Map<String, String>> infos, String... names) {
  59. for (String name : names) {
  60. Optional optional = infos.stream().filter(info -> info.get("Name").equals(name)).findAny();
  61. if (optional.isPresent()) {
  62. return String.valueOf(((Map) optional.get()).get("Value"));
  63. }
  64. }
  65. return "";
  66. }
  67. // 兼容历史配置, 格式 (谷元)
  68. private String guyuanNameRepalce(String name) {
  69. if (name.contains("谷元")) {
  70. return UtilString.replaceBracketIsWhole(name);
  71. } else {
  72. return UtilString.replaceBracketIsSemiangle(name);
  73. }
  74. }
  75. /// url压缩转base64
  76. @SneakyThrows
  77. private String imageUrlConvertBase64(String imageUrl) {
  78. ByteArrayOutputStream out = new ByteArrayOutputStream();
  79. // scale(比例), outputQuality(质量)
  80. Thumbnails.fromURLs(Arrays.asList(new URL(imageUrl))).scale(0.5f).outputQuality(0.25f).toOutputStream(out);
  81. InputStream inputStream = new ByteArrayInputStream(out.toByteArray());
  82. //转换为base64
  83. byte[] bytes = IOUtils.toByteArray(inputStream);
  84. return Base64.getEncoder().encodeToString(bytes);
  85. }
  86. @Autowired
  87. private FilePath filePath;
  88. /// PDF压缩转base64
  89. @SneakyThrows
  90. private String pdfUrlConvertBase64(String pdfUrl) {
  91. String fileName = "tmp_" + new Date().getTime() + ".pdf";
  92. // 下载文件
  93. File file = UtilFile.mkdirIfNot(fileName, filePath.getPath().getTmp());
  94. UtilHttp.doDownload(pdfUrl, file);
  95. // PDF压缩
  96. PdfDocument doc = new PdfDocument(); // 创建PdfDocument类的对象
  97. doc.loadFromFile(file.getAbsolutePath()); // 加载PDF文档
  98. doc.getFileInfo().setIncrementalUpdate(false); // 禁用增量更新
  99. doc.setCompressionLevel(PdfCompressionLevel.Normal); // 将压缩级别设置为最佳
  100. // 遍历文档页面
  101. for (int i = 0; i < doc.getPages().getCount(); i++) {
  102. PdfPageBase page = doc.getPages().get(i); // 获取指定页面
  103. PdfImageInfo[] images = page.getImagesInfo(); // 获取每个页面的图像信息集合
  104. // 遍历集合中的所有项目
  105. if (images != null && images.length > 0)
  106. for (int j = 0; j < images.length; j++) {
  107. PdfImageInfo image = images[j]; // 获取指定图片
  108. PdfBitmap bp = new PdfBitmap(image.getImage());
  109. bp.setQuality(30); // 设置压缩质量
  110. page.replaceImage(j, bp); // 将原始图像替换为压缩图像
  111. }
  112. }
  113. // 将结果文档保存至另一个PDF文档中: 覆盖
  114. doc.saveToFile(file.getAbsolutePath());
  115. doc.close();
  116. // PDF转base64, 无需透出本地文件地址
  117. String base64 = UtilFile.fileToBase64(file.getAbsolutePath());
  118. // 删除临时PDF文件
  119. UtilFile.deleteFile(file.getAbsolutePath());
  120. return base64;
  121. }
  122. // prd 校验发票抬头, 购买方范围
  123. private void validateBuyer(String BuyerName, String tips) {
  124. // List<String> corpNames = Arrays.asList(
  125. // "珠海金魁新能源科技有限公司",
  126. // "珠海能魁新能源科技有限公司",
  127. // "珠海创伟新能源有限公司",
  128. // "河南能辉绿电科技有限公司",
  129. // "河南省绿色生态新能源科技有限公司",
  130. // "贵州能辉智慧能源科技有限公司",
  131. // "上海能辉科技股份有限公司",
  132. // "浙江数实通信息技术有限公司");
  133. // McException.assertAccessException(!corpNames.contains(BuyerName), tips + ", 购买方名称不合法!");
  134. }
  135. /**
  136. * 混票识别 [新版本]
  137. */
  138. @PostMapping("invoice-iv2")
  139. McR invoice_iv2(@RequestBody Map<String, String> data) throws TencentCloudSDKException {
  140. McException.assertParamException_Null(data, "url");
  141. String image = ydClient.convertTemporaryUrl(data.get("url"),6000);
  142. log.info("混票识别, 免登地址, {}", image);
  143. // 非PDF, 且内存大于3M, 压缩后上传
  144. if (UtilMap.getFloat(data, "size") > 3.0f && !UtilMap.getBoolean(data, "isPdf")) {
  145. image = imageUrlConvertBase64(image);
  146. }
  147. if (UtilMap.getFloat(data, "size") > 6.0f && UtilMap.getBoolean(data, "isPdf")) {
  148. image = pdfUrlConvertBase64(image);
  149. }
  150. List<Map> invoices = (List<Map>) txyInvoice.doRecognizeGeneralInvoice(image).get("MixedInvoiceItems");
  151. List<String> nos=new ArrayList<>();
  152. List<McInvoiceDto> result = invoices.stream().map(item -> {
  153. Map prop = UtilMap.getMap(UtilMap.getMap(item, "SingleInvoiceInfos"), UtilMap.getString(item, "SubType"));
  154. // 2025.5.12 去除小计金额,并去除发票编号重复数据
  155. String no=UtilMap.getString(prop, "Number");
  156. if(nos.contains(no)){
  157. return null;
  158. }
  159. nos.add(no);
  160. String kind = UtilMap.getString(item, "TypeDescription");
  161. String invoiceName = UtilMap.getString(item, "SubTypeDescription");
  162. if (kind.equals("全电发票")) {
  163. kind = invoiceName.contains("铁路电子客票")?"火车票":invoiceName.contains("专用发票") ? "全电专用发票" : "全电普通发票";
  164. }
  165. if (kind.equals("增值税发票")) {
  166. kind = invoiceName.contains("增值税专用发票") ? "增值税专用发票" : "增值税普通发票";
  167. if (invoiceName.contains("增值税电子")) {
  168. kind = invoiceName.contains("专用发票") ? "增值税电子专用发票" : "增值税电子普通发票";
  169. }
  170. }
  171. // ppExt: 通用字段定义
  172. McInvoiceDto invoiceDto = McInvoiceDto.builder()
  173. .name(UtilMap.getString(item, "SubTypeDescription"))
  174. .kindName(kind)
  175. .kind(UtilMap.getInt(item, "Type"))
  176. .code(UtilMap.getString(prop, "Code"))
  177. .serial(UtilMap.getString(prop, "Number"))
  178. .date(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "Date")))
  179. .checkCode(UtilMap.getString(prop, "CheckCode"))
  180. // ppExt: 多明细行时, 优先取值合计 [全电票返回了subTotal字段, 但值为空] // 2025.5.12 去除小计金额,并去除发票编号重复数据
  181. .amount(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Total", "Fare"))) // "SubTotal",
  182. .tax(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Tax"))) // "SubTax",
  183. .excludingTax(UtilNumber.setBigDecimal(UtilMap.getString(prop, "PretaxAmount")))
  184. .buyerName(StringUtils.isBlank(guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))?"":guyuanNameRepalce(UtilMap.getString(prop, "Buyer")))
  185. // ppExt: 中央非税未返回税号官方说明: 非税发票理论是没有税号的,图片中属于信用代码
  186. .buyerTaxId(StringUtils.isBlank(UtilMap.getString(prop, "BuyerTaxID"))?"": UtilMap.getString(prop, "BuyerTaxID"))
  187. .sellerName(guyuanNameRepalce(UtilMap.getString_first(prop, "Seller", "Issuer"))) // 行程单: 填开单位
  188. .sellerTaxId(UtilMap.getString_first(prop, "SellerTaxID", "AgentCode")) // 行程单: 销售单位代号
  189. .passengerName(UtilMap.getString_first(prop, "Name", "UserName")) // 火车票, 行程单
  190. // 交通出行
  191. .seatType(UtilMap.getString(prop, "Seat"))
  192. .departureTime(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"))
  193. .departurePort(UtilMap.getString_first(prop, "StationGetOn", "Entrance", "Place")) // 火车票: 出发车站, 过路过桥费: 入口, 出租车: 发票所在地
  194. .arrivePort(UtilMap.getString_first(prop, "StationGetOff", "Exit")) // 行程单, 火车票: 到达车站, 过路过桥费: 出口
  195. .trainNo(UtilMap.getString_first(prop, "TrainNumber", "LicensePlate")) // 火车票: 车次, 出租车: 车牌号
  196. .insuranceCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "Insurance")))) // 行程单: 保险费
  197. .fuelCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "FuelSurcharge")))) // 行程单: 燃油附加费
  198. .constructionCosts(UtilNumber.setBigDecimal((UtilMap.getString(prop, "AirDevelopmentFund")))) // 行程单: 民航发展基金
  199. .build();
  200. // ppExt: 机票行程单, 行程与座位信息在明细内
  201. if("火车票".equals(kind)){
  202. invoiceDto.setTax(calculateTax(invoiceDto.getAmount(), new BigDecimal("0.09"), 2));
  203. invoiceDto.setExcludingTax(invoiceDto.getAmount().subtract(invoiceDto.getTax()));
  204. }
  205. if ("机票行程单".equals(item.get("TypeDescription"))) {
  206. Map flight = (Map) UtilMap.getList(prop, "FlightItems").get(0);
  207. invoiceDto.setDepartureTime(UtilString.replaceDateZH_cn(UtilMap.getString(item, "DateGetOn")) + " " + UtilMap.getString(prop, "TimeGetOn"));
  208. invoiceDto.setDeparturePort(UtilMap.getString(flight, "StationGetOn"));
  209. invoiceDto.setArrivePort(UtilMap.getString(flight, "StationGetOff"));
  210. invoiceDto.setSeatType(UtilMap.getString(flight, "Seat"));
  211. }
  212. if ("出租车发票".equals(item.get("TypeDescription"))) {
  213. // 上下车时间
  214. invoiceDto.setDepartureTime(UtilMap.getString(prop, "TimeGetOn") + " ~ " + UtilMap.getString(prop, "TimeGetOff"));
  215. }
  216. return invoiceDto;
  217. }).filter(item -> item!=null).collect(Collectors.toList());
  218. return McR.success(McInvoiceDto.formatResponse(result));
  219. }
  220. /**
  221. * 计算税额方法
  222. * @param faceValue 票面金额
  223. * @param taxRate 税率(如9%传0.09)
  224. * @param scale 小数位数
  225. * @return 税额
  226. */
  227. public static BigDecimal calculateTax(BigDecimal faceValue, BigDecimal taxRate, int scale) {
  228. if (faceValue == null || taxRate == null) {
  229. throw new IllegalArgumentException("参数不能为null");
  230. }
  231. BigDecimal denominator = BigDecimal.ONE.add(taxRate);
  232. return faceValue.divide(denominator, scale, RoundingMode.HALF_UP)
  233. .multiply(taxRate)
  234. .setScale(scale, RoundingMode.HALF_UP);
  235. }
  236. /**
  237. * 发票查重, 验真
  238. */
  239. @PostMapping("invoice-va")
  240. McR invoice_va(@RequestBody Map data) {
  241. McException.assertParamException_Null(data, "param");
  242. List<McInvoiceDto> invoices = JSON.parseArray(JSON.toJSONString(data.get("param")), McInvoiceDto.class);
  243. log.info("发票查重, 验真, {}", invoices);
  244. invoices.forEach(UtilMc.consumerWithIndex((item, index) -> {
  245. McInvoiceDto dto = (McInvoiceDto) item;
  246. String invoiceNo = dto.getSerial(); // 唯一标识, 发票号码
  247. String serial = "第【" + (index + 1) + "】张发票";
  248. // validateBuyer(dto.getBuyerName(), serial + "有疑问");
  249. McException.assertAccessException(StringUtils.isBlank(invoiceNo), serial + ", 识别结果为空, 请检查!");
  250. YDParam ydParam = YDParam.builder()
  251. .formUuid("FORM-FE4634E6D01745C7B26DC58D049EAADC6RP4")
  252. .searchFieldJson(JSON.toJSONString(UtilMap.map("radioField_liihyrtb, textField_liihyrt8", "否", invoiceNo)))
  253. .build();
  254. List<String> idList = (List<String>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form_id).getData();
  255. if (idList.size() > 0) {
  256. McException.exceptionAccess(serial + "已存在, 请勿重复提交!");
  257. }
  258. List<String> yzType=Arrays.asList("增值税普通发票",
  259. "增值税专用发票",
  260. "增值税电子专用发票",
  261. "增值税电子普通发票",
  262. "全电普通发票",
  263. "全电专用发票");
  264. // prd 仅仅识别 报销 用途的发票
  265. if(!dto.getType().contains("报销")||!yzType.contains(dto.getKindName())){
  266. return;
  267. }
  268. String serialTips = serial + "有疑问";
  269. try {
  270. // ppExt: 识别与验真后抬头对比 [全电票, 新版本识别接口, 返回名称为: 电子发票(普通发票) 不包含全电标识, 发类型为: 全电发票. 注意取值]
  271. Map rsp = txyInvoice.doVatInvoiceVerifyNew(dto.getKindName(), dto.getCode(), invoiceNo, dto.getDate(), String.valueOf(dto.getAmount()), dto.getCheckCode(), String.valueOf(dto.getExcludingTax()), serialTips,dto.getSellerTaxId());
  272. Map invoice = (Map) rsp.get("Invoice");
  273. McException.assertAccessException(!dto.getBuyerName().equals(guyuanNameRepalce(invoice.get("BuyerName").toString())), serialTips + ", 购买方名称不匹配!");
  274. McException.assertAccessException(!dto.getBuyerTaxId().equals(invoice.get("BuyerTaxCode")), serialTips + ", 购买方税号不匹配!");
  275. McException.assertAccessException(!dto.getSellerName().equals(guyuanNameRepalce(invoice.get("SellerName").toString())), serialTips + ", 销售方名称不匹配!");
  276. McException.assertAccessException(!dto.getSellerTaxId().equals(invoice.get("SellerTaxCode")), serialTips + ", 销售方税号不匹配!");
  277. } catch (TencentCloudSDKException e) {
  278. log.error(e.getMessage(), e);
  279. // prd: 上传发票为假发票时,提示:该发票有疑问,请联系财务人员
  280. String message = e.getMessage();
  281. // ppExt: 已经是新版本接口, 过滤提示 [官方答复: 提示不会检测您是否使用的是新版,所有的用户都会提示, 忽略即可]
  282. if (message.contains("温馨提示")) {
  283. message = message.split("温馨提示")[0];
  284. }
  285. if (message.contains("发票不存在")) {
  286. message = "有疑问,请联系财务人员";
  287. }
  288. McException.exceptionAccess(serial + message);
  289. }
  290. }));
  291. return McR.success();
  292. }
  293. /**
  294. * 发票状态更新: 服务注册
  295. */
  296. @PostMapping("invoice-up")
  297. McR invoice_va(HttpServletRequest request) {
  298. Map data = UtilServlet.getParamMap(request);
  299. log.info("发票状态更新: 服务注册, {}", data);
  300. String compId = UtilMap.getString(data, "compId");
  301. String status = UtilMap.getString(data, "status");
  302. // 读取关联表单
  303. String formUUid="";
  304. List<String> formInstanceIds = new ArrayList<>();
  305. if(compId.equals("selectField_lzs0bpk2")){
  306. // 采购表单
  307. formUUid="FORM-B5A7B20013AE4CD09AD87FAB9A3E145FS3P6";
  308. List<Map> associationData = (List<Map>) JSON.parse(UtilMap.getString(data, "multiAssociation"));
  309. formInstanceIds.addAll(associationData.stream().map(form -> UtilMap.getString(form, "instanceId")).collect(Collectors.toList()));
  310. }else{
  311. formUUid="FORM-FE4634E6D01745C7B26DC58D049EAADC6RP4";
  312. List<String> associationForm = (List<String>) JSON.parse(UtilMap.getString(data, "multiAssociation"));
  313. for (String record : associationForm) {
  314. // 解析关联表单
  315. List<Map> associationData = (List<Map>) JSON.parse(record);
  316. formInstanceIds.addAll(associationData.stream().map(form -> UtilMap.getString(form, "instanceId")).collect(Collectors.toList()));
  317. }
  318. }
  319. // 宜搭批量更新
  320. Map update = UtilMap.map(compId, status);
  321. if (compId.equals("selectField_liihyrt6")) {
  322. update.put("radioField_liw7rb2q", "否"); // 提交后, 更新是否退回标识为否
  323. }
  324. // prd 9.10 更新报销单, 关联到发票:: ppExt 宜搭服务注册, 提交规则系统默认字段 [详见 YDService]
  325. ivYdService.operateData(data, update, YDParam.builder()
  326. .formUuid(formUUid)
  327. .formInstanceIdList(formInstanceIds)
  328. .updateFormDataJson(JSON.toJSONString(update))
  329. .build(), YDConf.FORM_OPERATION.multi_update);
  330. return McR.success();
  331. }
  332. /**
  333. * 发票状态更新: 退回提交
  334. */
  335. @PostMapping("invoice-zy")
  336. McR invoice_zy(@RequestBody Map data) {
  337. log.info("发票状态更新: 退回提交, {}", data);
  338. List<String> pre_ids = (List<String>) data.get("pre_ids"); // 释放修改前
  339. List<String> cur_ids = (List<String>) data.get("cur_ids"); // 占用修改后
  340. // [前端调用添加] 退回为监听宜搭dom事件, 先执行接口调用, 才会校验宜搭必填, 过滤无效调用
  341. if (cur_ids.size() == 0) {
  342. return McR.success();
  343. }
  344. Map pre_update = (Map) data.get("pre_update");
  345. Map cur_update = (Map) data.get("cur_update");
  346. // 宜搭批量更新
  347. ydClient.operateData(YDParam.builder()
  348. .formUuid("FORM-FE4634E6D01745C7B26DC58D049EAADC6RP4")
  349. .formInstanceIdList(pre_ids)
  350. .updateFormDataJson(JSON.toJSONString(pre_update))
  351. .build(), YDConf.FORM_OPERATION.multi_update);
  352. ydClient.operateData(YDParam.builder()
  353. .formUuid("FORM-FE4634E6D01745C7B26DC58D049EAADC6RP4")
  354. .formInstanceIdList(cur_ids)
  355. .updateFormDataJson(JSON.toJSONString(cur_update))
  356. .build(), YDConf.FORM_OPERATION.multi_update);
  357. return McR.success();
  358. }
  359. /**
  360. * 全局查询(不匹配子表单)
  361. */
  362. @PostMapping("validate")
  363. McR queryAll(HttpServletRequest request) {
  364. Map<String, ?> param = UtilServlet.getParamMap(request);
  365. log.info("全局查询(不匹配子表单), {}", param);
  366. if (ObjectUtil.isNull(param.get("uniques"))) {
  367. return McR.success();
  368. }
  369. McException.assertParamException_Null(param, "uniques", "formUuid", "compId");
  370. // 容错 - 尾部分号的空格会被输入框忽略
  371. String[] uniques = String.valueOf(param.get("uniques")).replace("; ", ";").split(";");
  372. for (String val : uniques) {
  373. // 查重校验: 单张发票唯一标识 + 审批已通过 / 审批中
  374. List<Map> conditions = new ArrayList<>();
  375. Map unique = new HashMap();
  376. unique.put("key", param.get("compId"));
  377. unique.put("value", val.split(": ")[1]);
  378. unique.put("type", "TEXT");
  379. unique.put("operator", "like");
  380. unique.put("componentName", "TextField");
  381. conditions.add(unique);
  382. Map approve = new HashMap();
  383. approve.put("key", "processApprovedResult");
  384. approve.put("value", new String[]{"agree"});
  385. approve.put("type", "ARRAY");
  386. approve.put("operator", "in");
  387. approve.put("componentName", "SelectField");
  388. conditions.add(approve);
  389. YDParam ydParam = YDParam.builder()
  390. .formUuid(String.valueOf(param.get("formUuid")))
  391. .searchCondition(JSON.toJSONString(conditions))
  392. .build();
  393. DDR_New ddr_new = ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_list);
  394. log.info("审批通过匹配结果, {}, {}", ddr_new.getTotalCount(), ddr_new.getData());
  395. if (ddr_new.getTotalCount() > 0) {
  396. return McR.errorAccess("发票已被使用, 请勿重复提交!");
  397. }
  398. conditions.remove(approve);
  399. Map status = new HashMap();
  400. status.put("key", "processInstanceStatus");
  401. status.put("value", new String[]{"RUNNING"});
  402. status.put("type", "ARRAY");
  403. status.put("operator", "in");
  404. status.put("componentName", "SelectField");
  405. conditions.add(status);
  406. ydParam.setSearchCondition(JSON.toJSONString(conditions));
  407. ddr_new = ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_list);
  408. log.info("审批通过匹配结果, {}, {}", ddr_new.getTotalCount(), ddr_new.getData());
  409. if (ddr_new.getTotalCount() > 0) {
  410. return McR.errorAccess("发票已在流程中, 请勿重复提交!");
  411. }
  412. }
  413. return McR.success();
  414. }
  415. @PostMapping("test")
  416. McR test() {
  417. // List<Map> process = (List<Map>) ydClient.queryData(YDParam.builder()
  418. // .formUuid("FE4634E6D01745C7B26DC58D049EAADC6RP4")
  419. // .formInstId("FINST-NGA66WA1FV4EB7QJC3OATA3EV8MK35Z9COEMLFR22")
  420. // .build(), YDConf.FORM_QUERY.retrieve_id).getData();
  421. List<Map> process = (List<Map>) ydClient.queryData(YDParam.builder()
  422. .formUuid("FORM-0IA66C71F6NBAETREO8DE9SSN43D3YIZ0AYILC")
  423. .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lmewsobs", "Y16668919W4E4FHQ6123ADDHB8XK3S709YEMLXWF")))
  424. .build(), YDConf.FORM_QUERY.retrieve_search_form).getData();
  425. return McR.success();
  426. }
  427. }