|
@@ -3,6 +3,7 @@ package com.malk.lilin.Service.impl;
|
|
|
|
|
|
import cn.hutool.crypto.SecureUtil;
|
|
import cn.hutool.crypto.SecureUtil;
|
|
|
|
|
|
|
|
+import com.alibaba.excel.util.StringUtils;
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
@@ -324,10 +325,10 @@ public class LiLinServiceImpl implements LiLinService {
|
|
.build(), YDConf.FORM_OPERATION.multi_update);
|
|
.build(), YDConf.FORM_OPERATION.multi_update);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } catch(Exception e){
|
|
|
|
- log.error("更新主表单或子表单状态时出错", e);
|
|
|
|
- return McR.errorParam("更新失败");
|
|
|
|
- }
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("更新主表单或子表单状态时出错", e);
|
|
|
|
+ return McR.errorParam("更新失败");
|
|
|
|
+ }
|
|
|
|
|
|
return McR.success();
|
|
return McR.success();
|
|
|
|
|
|
@@ -629,329 +630,606 @@ public class LiLinServiceImpl implements LiLinService {
|
|
Map params = new HashMap<>();
|
|
Map params = new HashMap<>();
|
|
// mapAll.put("securityCode", securityCode);
|
|
// mapAll.put("securityCode", securityCode);
|
|
mapAll.put("securityCode", securityCode);
|
|
mapAll.put("securityCode", securityCode);
|
|
- String response = UtilHttp.doPost(url, headers, null,null,mapAll);//批量制单
|
|
|
|
|
|
+ String response = UtilHttp.doPost(url, headers, null, null, mapAll);//批量制单
|
|
log.info("response:{}", response);
|
|
log.info("response:{}", response);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public McR lilinZD(Map<String, Object> map) throws IOException {
|
|
public McR lilinZD(Map<String, Object> map) throws IOException {
|
|
-// String formInstanceId = String.valueOf(map.get("formInstanceId"));
|
|
|
|
-// log.info("formInstanceId:{}", formInstanceId);
|
|
|
|
-// //根据实例ID获取表单数据
|
|
|
|
-// Map data = (Map) ydClient.queryData(YDParam.builder().formInstId(formInstanceId)
|
|
|
|
-// .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
|
|
|
|
-// .userId(ddConf.getOperator()).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
-// log.info("data:{}", data);
|
|
|
|
-// String instructionId = String.valueOf(data.get("serialNumberField_m9ze3rjd"));//电子凭证号
|
|
|
|
-// String totalTrxNumber = String.valueOf(data.get("serialNumberField_m9ze3rjd"));//批量转账总流水号
|
|
|
|
- String totalTrxNumber = String.valueOf(map.get("totalTrxNumber"));//批量转账总流水号
|
|
|
|
- String source = "OA";//来源
|
|
|
|
-// String note = String.valueOf(data.get("textField_m9ze3rk3"));//付款用途
|
|
|
|
-// String toAccountCode = String.valueOf(data.get("textField_m9ze3rjs"));//收款账号
|
|
|
|
-// String toAccountName = String.valueOf(data.get("textField_m9ze3rjl"));//收款账户名
|
|
|
|
-// String toBank = String.valueOf(data.get("textField_m9ze3rjr"));//收款账户所在银行支行
|
|
|
|
-// String fromAccountCode = String.valueOf(data.get("textField_mdfnuyl9"));//付款账号
|
|
|
|
-// String fromAccountName = String.valueOf(data.get("textField_m9ze3rj8"));//付款账户名
|
|
|
|
-// String payAmount = String.valueOf(data.get("numberField_m9ze3rk4"));//转账金额
|
|
|
|
-// // String toAccountType = String.valueOf(data.get("selectField_m9ze3rjf"));//收款账户所在银行支行
|
|
|
|
-// String xmbh = String.valueOf(data.get("textField_madmzxce"));
|
|
|
|
-// String xmmc = String.valueOf(data.get("textField_mayubz25"));
|
|
|
|
-// String projectInfo = xmbh + "-" + xmmc;//项目信息
|
|
|
|
-// HashMap metaJson1 = new HashMap();
|
|
|
|
-// metaJson1.put("projectInfo", projectInfo);
|
|
|
|
-// String metaJson = JSON.toJSONString(metaJson1);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// List<Map<String, Object>> tableField = (List<Map<String, Object>>) data.get("tableField_m9m8zhyy");
|
|
|
|
- List<Map<String, Object>> tableField = new ArrayList<>();
|
|
|
|
-
|
|
|
|
- Map<String, Object> data1 = new HashMap<>();
|
|
|
|
- data1.put("trxNumber", "FK20250723123");
|
|
|
|
- data1.put("fromAccountCode", "755915704010801");
|
|
|
|
- data1.put("fromAccountName", "企业网银新20161341");
|
|
|
|
- data1.put("toAccountCode", "6214831150131511");
|
|
|
|
- data1.put("toAccountType", "0");
|
|
|
|
- data1.put("toAccountName", "吴极客");
|
|
|
|
- data1.put("payAmount", "1.00");
|
|
|
|
- data1.put("uses", "这是一个测试用途");
|
|
|
|
-// data1.put("instructionId", "F00000123");
|
|
|
|
|
|
+ String formInstanceId = String.valueOf(map.get("formInstanceId"));
|
|
|
|
+ log.info("formInstanceId:{}", formInstanceId);
|
|
|
|
|
|
- Map<String, Object> data2 = new HashMap<>();
|
|
|
|
- data2.put("trxNumber", "FK20250723121");
|
|
|
|
- data2.put("fromAccountCode", "755915704010801");
|
|
|
|
- data2.put("fromAccountName", "企业网银新20161341");
|
|
|
|
- data2.put("toAccountCode", "6214831150131511");
|
|
|
|
- data2.put("toAccountType", "0");
|
|
|
|
- data2.put("toAccountName", "吴极客");
|
|
|
|
- data2.put("payAmount", "1.00");
|
|
|
|
- data2.put("uses", "这是一个测试用途");
|
|
|
|
-// data2.put("instructionId", "F00000123");
|
|
|
|
|
|
+ // 获取表单数据
|
|
|
|
+ Map data = (Map) ydClient.queryData(YDParam.builder()
|
|
|
|
+ .formInstId(formInstanceId)
|
|
|
|
+ .appType(ydConf.getAppType())
|
|
|
|
+ .systemToken(ydConf.getSystemToken())
|
|
|
|
+ .userId(ddConf.getOperator())
|
|
|
|
+ .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
|
|
-// 添加到集合
|
|
|
|
- tableField.add(data1);
|
|
|
|
- tableField.add(data2);
|
|
|
|
- String totalRecord = String.valueOf(tableField.size());//总笔数
|
|
|
|
-//
|
|
|
|
-// List<Map<String, Object>> list = new ArrayList<>();
|
|
|
|
-// for (int i = 0; i < tableField.size(); i++) {
|
|
|
|
-//
|
|
|
|
-// Map<String, Object> tableField1 = tableField.get(i);
|
|
|
|
-// String ltrxNumber = String.valueOf(tableField1.get("textField_m9ze3rjt"));
|
|
|
|
-// String lfromAccountCode = String.valueOf(tableField1.get("textField_m9ze3rjv"));
|
|
|
|
-// String lfromAccountName = String.valueOf(tableField1.get("selectField_m9ze3rjx"));
|
|
|
|
-// String ltoAccountCode = String.valueOf(tableField1.get("selectField_m9ze3rjx"));
|
|
|
|
-// String ltoAccountType = String.valueOf(tableField1.get("selectField_m9ze3rjx"));
|
|
|
|
-// String ltoAccountName = String.valueOf(tableField1.get("selectField_m9ze3rjx"));
|
|
|
|
-// String lpayAmount = String.valueOf(tableField1.get("selectField_m9ze3rjx"));
|
|
|
|
-// String luses = String.valueOf(tableField1.get("selectField_m9ze3rjx"));
|
|
|
|
-// HashMap<String, Object> tableField2 = new HashMap<>();
|
|
|
|
-// tableField2.put("trxNumber", ltrxNumber);
|
|
|
|
-// tableField2.put("fromAccountCode", lfromAccountCode);
|
|
|
|
-// tableField2.put("fromAccountName", lfromAccountName);
|
|
|
|
-// tableField2.put("toAccountCode", ltoAccountCode);
|
|
|
|
-// tableField2.put("toAccountType", ltoAccountType);
|
|
|
|
-// tableField2.put("toAccountName", ltoAccountName);
|
|
|
|
-// tableField2.put("payAmount", lpayAmount);
|
|
|
|
-// tableField2.put("uses", luses);
|
|
|
|
-// list.add(tableField2);
|
|
|
|
-// }
|
|
|
|
- String securityCode = String.valueOf(token().getData());
|
|
|
|
- HashMap mapAll = new HashMap<>();
|
|
|
|
- mapAll.put("totalRecord", totalRecord);
|
|
|
|
- mapAll.put("list", JSONObject.toJSONString(tableField));
|
|
|
|
- mapAll.put("totalTrxNumber", totalTrxNumber);
|
|
|
|
- mapAll.put("source", source);
|
|
|
|
- mapAll.put("securityCode", securityCode);
|
|
|
|
|
|
+ log.info("form data: {}", data);
|
|
|
|
|
|
- String url = "https://openapi.xencio.com/sandbox/cfa/api/payment/batchTransfer";
|
|
|
|
|
|
+ // 主表字段(复用)
|
|
|
|
+ String fklx = String.valueOf(data.get("selectField_m9ze3rjf")); // 付款类型
|
|
|
|
+ String note = String.valueOf(data.get("textField_m9ze3rk3")); // 付款用途
|
|
|
|
+ String toAccountCode = String.valueOf(data.get("textField_m9ze3rjs")); // 收款账号
|
|
|
|
+ String toAccountName = String.valueOf(data.get("textField_m9ze3rjl")); // 收款户名
|
|
|
|
+ String toBank = String.valueOf(data.get("textField_m9ze3rjr")); // 收款银行支行
|
|
|
|
+ String fromAccountCode = String.valueOf(data.get("textField_mdfnuyl9")); // 付款账号
|
|
|
|
+ String fromAccountName = String.valueOf(data.get("textField_m9ze3rj8")); // 付款户名
|
|
|
|
|
|
- Map headers = new HashMap<>();
|
|
|
|
|
|
+ // 公共参数
|
|
|
|
+ String securityCode = String.valueOf(token().getData());
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
headers.put("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a");
|
|
headers.put("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a");
|
|
- headers.put("content-Type", "application/x-www-form-urlencoded");
|
|
|
|
-// Map params = new HashMap<>();
|
|
|
|
|
|
+ headers.put("Content-Type", "application/x-www-form-urlencoded");
|
|
|
|
+ String url = "https://openapi.xencio.com/sandbox/cfa/api/payment/transfer";
|
|
|
|
+
|
|
|
|
+ // 判断是否为物流付款单
|
|
|
|
+ if ("物流付款单".equals(fklx)) {
|
|
|
|
+ // 是物流付款单:遍历子表,每行发起一次支付
|
|
|
|
+ List<Map<String, Object>> tableField = (List<Map<String, Object>>) data.get("tableField_m986c5os");
|
|
|
|
+ if (tableField == null || tableField.isEmpty()) {
|
|
|
|
+ log.warn("物流付款单但子表为空,formInstanceId: {}", formInstanceId);
|
|
|
|
+ return McR.errorParam("子表数据为空");
|
|
|
|
+ }
|
|
|
|
|
|
- String response = UtilHttp.doPost(url, headers, null, null, mapAll);//批量制单
|
|
|
|
- log.info("response:{}", response);
|
|
|
|
|
|
+ for (Map<String, Object> row : tableField) {
|
|
|
|
+ String instructionId = String.valueOf(row.get("textField_mdnuob9a")); // 子表电子凭证号
|
|
|
|
+ String xmmc = String.valueOf(row.get("textField_m9lfmh1o")); // 项目名称
|
|
|
|
+ String xmbh = String.valueOf(row.get("textField_m9lfmh1p")); // 项目编号
|
|
|
|
+ String payAmount = String.valueOf(row.get("numberField_m8yf6gn1")); // 子表金额
|
|
|
|
+
|
|
|
|
+ // 构建 projectInfo
|
|
|
|
+ String projectInfo = xmbh + "-" + xmmc;
|
|
|
|
+ Map<String, Object> metaJson1 = new HashMap<>();
|
|
|
|
+ metaJson1.put("projectInfo", projectInfo);
|
|
|
|
+ String metaJson = JSON.toJSONString(metaJson1);
|
|
|
|
+
|
|
|
|
+ // 组装请求参数
|
|
|
|
+ Map<String, Object> mapAll = new HashMap<>();
|
|
|
|
+ mapAll.put("instructionId", instructionId);
|
|
|
|
+ mapAll.put("fromAccountCode", fromAccountCode);
|
|
|
|
+ mapAll.put("fromAccountName", fromAccountName);
|
|
|
|
+ mapAll.put("toAccountCode", toAccountCode);
|
|
|
|
+ mapAll.put("toAccountName", toAccountName);
|
|
|
|
+ mapAll.put("payAmount", payAmount);
|
|
|
|
+ mapAll.put("note", note);
|
|
|
|
+ mapAll.put("toBank", toBank);
|
|
|
|
+ mapAll.put("securityCode", securityCode);
|
|
|
|
+ mapAll.put("metaJson", metaJson);
|
|
|
|
+
|
|
|
|
+ // 发起支付
|
|
|
|
+ String response = UtilHttp.doPost(url, headers, null, null, mapAll);
|
|
|
|
+ log.info("物流付款单 - 支付成功 [凭证号: {}, 金额: {}], 响应: {}", instructionId, payAmount, response);
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ } else {
|
|
|
|
+ // 不是物流付款单:使用主表字段,发起一次支付
|
|
|
|
+ String instructionId = String.valueOf(data.get("serialNumberField_m9ze3rjd")); // 主表电子凭证号
|
|
|
|
+ String payAmount = String.valueOf(data.get("numberField_m9ze3rk4")); // 主表金额
|
|
|
|
+ String xmbh = String.valueOf(data.get("textField_madmzxce"));
|
|
|
|
+ String xmmc = String.valueOf(data.get("textField_mayubz25"));
|
|
|
|
+ String projectInfo = xmbh + "-" + xmmc;
|
|
|
|
+
|
|
|
|
+ Map<String, Object> metaJson1 = new HashMap<>();
|
|
|
|
+ metaJson1.put("projectInfo", projectInfo);
|
|
|
|
+ String metaJson = JSON.toJSONString(metaJson1);
|
|
|
|
+
|
|
|
|
+ Map<String, Object> mapAll = new HashMap<>();
|
|
|
|
+ mapAll.put("instructionId", instructionId);
|
|
|
|
+ mapAll.put("fromAccountCode", fromAccountCode);
|
|
|
|
+ mapAll.put("fromAccountName", fromAccountName);
|
|
|
|
+ mapAll.put("toAccountCode", toAccountCode);
|
|
|
|
+ mapAll.put("toAccountName", toAccountName);
|
|
|
|
+ mapAll.put("payAmount", payAmount);
|
|
|
|
+ mapAll.put("note", note);
|
|
|
|
+ mapAll.put("toBank", toBank);
|
|
|
|
+ mapAll.put("securityCode", securityCode);
|
|
|
|
+ mapAll.put("metaJson", metaJson);
|
|
|
|
+
|
|
|
|
+ String response = UtilHttp.doPost(url, headers, null, null, mapAll);
|
|
|
|
+ log.info("非物流付款单 - 支付成功 [凭证号: {}, 金额: {}], 响应: {}", instructionId, payAmount, response);
|
|
|
|
+ }
|
|
|
|
|
|
-// OkHttpClient client = new OkHttpClient();
|
|
|
|
-//
|
|
|
|
-// MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
|
|
|
|
-// RequestBody body = RequestBody.create(mediaType, "securityCode=" + token().getData() + "&fromAccountCode=" + fromAccountCode + "&fromAccountName=" + fromAccountName + "&toAccountCode=" + toAccountCode + "&toAccountName=" + toAccountName + "&toAccountType=0&toBank=" + toBank + "&payAmount=" + payAmount + "¬e=" + note + "&instructionId=" + instructionId + "&metaJson=" + metaJson);
|
|
|
|
-// Request request = new Request.Builder()
|
|
|
|
-// .url("https://openapi.xencio.com/sandbox/cfa/api/payment/transfer")
|
|
|
|
-// .post(body)
|
|
|
|
-// .addHeader("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a")
|
|
|
|
-// .addHeader("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
-// .build();
|
|
|
|
-//
|
|
|
|
-// Response response = client.newCall(request).execute();
|
|
|
|
-// String jsonstr = response.body().string();
|
|
|
|
-// JSONObject jsonObject = JSONObject.parseObject(jsonstr);
|
|
|
|
-// JSONObject data1 = jsonObject.getJSONObject("data");
|
|
|
|
-// String trxNumber = data1.getString("trxNumber");
|
|
|
|
-
|
|
|
|
-// return McR.success(trxNumber);
|
|
|
|
- return McR.success();
|
|
|
|
|
|
+ return McR.success("处理完成");
|
|
}
|
|
}
|
|
|
|
+//TODO
|
|
|
|
+
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public McR lilinJG(Map<String, Object> map) throws IOException {
|
|
public McR lilinJG(Map<String, Object> map) throws IOException {
|
|
- String formInstanceId = String.valueOf(map.get("formInstanceId"));
|
|
|
|
- log.info("formInstanceId:{}", formInstanceId);
|
|
|
|
- //根据实例ID获取表单数据
|
|
|
|
- Map data = (Map) ydClient.queryData(YDParam.builder().formInstId(formInstanceId)
|
|
|
|
- .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
|
|
|
|
- .userId(ddConf.getOperator()).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
- log.info("data:{}", data);
|
|
|
|
- String instructionId = String.valueOf(data.get("serialNumberField_m9ze3rjd"));//表单流水号
|
|
|
|
-// String instructionId = String.valueOf(map.get("instructionId"));//表单流水号
|
|
|
|
-
|
|
|
|
- String url = "https://openapi.xencio.com/sandbox/cfa/api/payment/batchTransferStatus";
|
|
|
|
- String securityCode = String.valueOf(token().getData());
|
|
|
|
|
|
+ // 1. 查询所有需要处理的单据(状态为“已审批待付款”或“已审批部分付款”)
|
|
|
|
+ List<Map> list = (List<Map>) ydClient.queryData(YDParam.builder()
|
|
|
|
+ .formUuid("FORM-1A612AA91BAC467CB9823B6CB92491152WZH")
|
|
|
|
+ .searchFieldJson(JSONObject.toJSONString(Arrays.asList(
|
|
|
|
+ new YDSearch("selectField_ma0w9yrb",
|
|
|
|
+ Arrays.asList("已审批待付款", "已审批部分付款"),
|
|
|
|
+ "SelectField",
|
|
|
|
+ YDSearch.Type.RADIO_FIELD,
|
|
|
|
+ YDSearch.Operator.CONTAINS)
|
|
|
|
+ )))
|
|
|
|
+ .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
|
|
|
|
+
|
|
|
|
+ if (list == null || list.isEmpty()) {
|
|
|
|
+ log.info("没有找到需要处理的单据");
|
|
|
|
+ return McR.success("无待处理数据");
|
|
|
|
+ }
|
|
|
|
|
|
- Map headers = new HashMap<>();
|
|
|
|
|
|
+ log.info("共查询到 {} 条待处理单据", list.size());
|
|
|
|
|
|
- headers.put("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a");
|
|
|
|
- headers.put("content-Type", "application/x-www-form-urlencoded");
|
|
|
|
|
|
+ // 公共参数提前准备(安全码、URL、请求头等)
|
|
|
|
+ String url = "https://openapi.xencio.com/sandbox/cfa/api/payment/transferStatus";
|
|
|
|
+ String securityCode = String.valueOf(token().getData());
|
|
|
|
|
|
- Map params = new HashMap<>();
|
|
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
+ headers.put("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a");
|
|
|
|
+ headers.put("Content-Type", "application/x-www-form-urlencoded");
|
|
|
|
|
|
|
|
+ Map<String, Object> params = new HashMap<>();
|
|
params.put("securityCode", securityCode);
|
|
params.put("securityCode", securityCode);
|
|
- params.put("totalTrxNumber", instructionId);
|
|
|
|
- String response1 = UtilHttp.doGet(url, headers, params);//批量结果
|
|
|
|
- JSONObject jsonObject = JSONObject.parseObject(response1);
|
|
|
|
- JSONObject data1 = jsonObject.getJSONObject("data");
|
|
|
|
- String message = data1.getString("message");
|
|
|
|
-// OkHttpClient client = new OkHttpClient();
|
|
|
|
-// Request request = new Request.Builder()
|
|
|
|
-// .url("https://openapi.xencio.com/sandbox/cfa/api/payment/transferStatus?securityCode=" + token().getData() + "&trxNumber=" + instructionId)
|
|
|
|
-// .get()
|
|
|
|
-// .addHeader("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a")
|
|
|
|
-// .addHeader("content-type", "application/x-www-form-urlencoded")
|
|
|
|
-// .build();
|
|
|
|
-// Response response = client.newCall(request).execute();
|
|
|
|
-// String jsonstr = response.body().string();
|
|
|
|
-// JSONObject jsonObject = JSONObject.parseObject(jsonstr);
|
|
|
|
-// JSONObject data1 = jsonObject.getJSONObject("data");
|
|
|
|
-// String message = data1.getString("message");
|
|
|
|
-// if (message.contains("成功")) {
|
|
|
|
-// ydClient.operateData(YDParam.builder().formInstanceId(formInstanceId)
|
|
|
|
-// .updateFormDataJson(JSON.toJSONString(UtilMap.map("selectField_ma0w9yrb", "已审批已付款")))
|
|
|
|
-// .build(), YDConf.FORM_OPERATION.update);
|
|
|
|
-// }
|
|
|
|
- return McR.success(response1);
|
|
|
|
|
|
+
|
|
|
|
+ int successCount = 0;
|
|
|
|
+ int failCount = 0;
|
|
|
|
+ List<String> failedIds = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ // 2. 遍历 list,逐个执行原 lilinJG 中的处理逻辑
|
|
|
|
+ for (Map item : list) {
|
|
|
|
+ String formInstanceId = String.valueOf(item.get("formInstanceId"));
|
|
|
|
+ if (formInstanceId == null || "null".equals(formInstanceId.trim()) || formInstanceId.trim().isEmpty()) {
|
|
|
|
+ log.warn("跳过无效的 formInstanceId: {}", item.get("formInstanceId"));
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ log.info("开始处理单据: formInstanceId={}", formInstanceId);
|
|
|
|
+
|
|
|
|
+ // ===== 开始执行原 lilinJG 方法中的核心逻辑 =====
|
|
|
|
+
|
|
|
|
+ // 获取表单数据
|
|
|
|
+ Map data = (Map) ydClient.queryData(YDParam.builder()
|
|
|
|
+ .formInstId(formInstanceId)
|
|
|
|
+ .appType(ydConf.getAppType())
|
|
|
|
+ .systemToken(ydConf.getSystemToken())
|
|
|
|
+ .userId(ddConf.getOperator())
|
|
|
|
+ .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
+
|
|
|
|
+ if (data == null) {
|
|
|
|
+ log.warn("获取表单数据为空,formInstanceId: {}", formInstanceId);
|
|
|
|
+ failCount++;
|
|
|
|
+ failedIds.add(formInstanceId);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ log.info("form data: {}", data);
|
|
|
|
+
|
|
|
|
+ String fklx = String.valueOf(data.get("selectField_m9ze3rjf")); // 付款类型
|
|
|
|
+ String mainInstructionId = String.valueOf(data.get("serialNumberField_m9ze3rjd")); // 主表流水号
|
|
|
|
+
|
|
|
|
+ // ===== 区分处理:是否为物流付款单 =====
|
|
|
|
+ if ("物流付款单".equals(fklx)) {
|
|
|
|
+ // 物流付款单:处理子表
|
|
|
|
+ List<Map<String, Object>> tableField = (List<Map<String, Object>>) data.get("tableField_m986c5os");
|
|
|
|
+ if (tableField == null || tableField.isEmpty()) {
|
|
|
|
+ log.warn("物流付款单但子表为空,formInstanceId: {}", formInstanceId);
|
|
|
|
+ failCount++;
|
|
|
|
+ failedIds.add(formInstanceId);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Map<String, Object>> updatedRows = new ArrayList<>();
|
|
|
|
+ int completedCount = 0;
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < tableField.size(); i++) {
|
|
|
|
+ Map<String, Object> row = new HashMap<>(tableField.get(i)); // 复制原数据用于更新
|
|
|
|
+ String subInstructionId = String.valueOf(row.get("textField_mdnuob9a")); // 子表流水号
|
|
|
|
+
|
|
|
|
+ // 查询子表支付状态
|
|
|
|
+ params.put("instructionId", subInstructionId);
|
|
|
|
+ String response = UtilHttp.doGet(url, headers, params);
|
|
|
|
+ log.info("查询子表支付状态 [instructionId: {}], 响应: {}", subInstructionId, response);
|
|
|
|
+
|
|
|
|
+ JSONObject jsonResponse = JSON.parseObject(response);
|
|
|
|
+ JSONObject dataObj = jsonResponse.getJSONObject("data");
|
|
|
|
+ String message = dataObj != null ? dataObj.getString("message") : "";
|
|
|
|
+
|
|
|
|
+ String status = "未完成";
|
|
|
|
+ if (message != null && message.contains("成功")) {
|
|
|
|
+ status = "已完成";
|
|
|
|
+ completedCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新子表字段:selectField_mdmwfibp
|
|
|
|
+ row.put("selectField_mdmwfibp", status);
|
|
|
|
+ updatedRows.add(row);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 构建要更新的子表数据
|
|
|
|
+ Map<String, Object> updateData = new HashMap<>();
|
|
|
|
+ updateData.put("tableField_m986c5os", updatedRows);
|
|
|
|
+
|
|
|
|
+ // 更新主表状态
|
|
|
|
+ String mainStatus;
|
|
|
|
+ if (completedCount == 0) {
|
|
|
|
+ mainStatus = "已审批待付款";
|
|
|
|
+ } else if (completedCount == updatedRows.size()) {
|
|
|
|
+ mainStatus = "已审批已付款";
|
|
|
|
+ } else {
|
|
|
|
+ mainStatus = "已审批部分付款";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ updateData.put("selectField_ma0w9yrb", mainStatus);
|
|
|
|
+
|
|
|
|
+ // 提交更新
|
|
|
|
+ ydClient.operateData(YDParam.builder()
|
|
|
|
+ .formInstanceId(formInstanceId)
|
|
|
|
+ .updateFormDataJson(JSON.toJSONString(updateData))
|
|
|
|
+ .build(), YDConf.FORM_OPERATION.update);
|
|
|
|
+
|
|
|
|
+ log.info("【物流】状态更新完成,主表状态: {}", mainStatus);
|
|
|
|
+ successCount++;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ // 非物流付款单:主表单处理
|
|
|
|
+ if (mainInstructionId == null || mainInstructionId.isEmpty()) {
|
|
|
|
+ log.warn("主表流水号为空,formInstanceId: {}", formInstanceId);
|
|
|
|
+ failCount++;
|
|
|
|
+ failedIds.add(formInstanceId);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ params.put("instructionId", mainInstructionId);
|
|
|
|
+ String response = UtilHttp.doGet(url, headers, params);
|
|
|
|
+ log.info("查询主表支付状态 [instructionId: {}], 响应: {}", mainInstructionId, response);
|
|
|
|
+
|
|
|
|
+ JSONObject jsonResponse = JSON.parseObject(response);
|
|
|
|
+ JSONObject dataObj = jsonResponse.getJSONObject("data");
|
|
|
|
+ String message = dataObj != null ? dataObj.getString("message") : "";
|
|
|
|
+
|
|
|
|
+ if (message != null && message.contains("成功")) {
|
|
|
|
+ // 更新主表状态为“已审批已付款”
|
|
|
|
+ ydClient.operateData(YDParam.builder()
|
|
|
|
+ .formInstanceId(formInstanceId)
|
|
|
|
+ .updateFormDataJson(JSON.toJSONString(
|
|
|
|
+ UtilMap.map("selectField_ma0w9yrb", "已审批已付款")))
|
|
|
|
+ .build(), YDConf.FORM_OPERATION.update);
|
|
|
|
+ log.info("【非物流】支付成功,已更新状态");
|
|
|
|
+ successCount++;
|
|
|
|
+ } else {
|
|
|
|
+ log.info("【非物流】支付未成功,状态未更新");
|
|
|
|
+ failCount++;
|
|
|
|
+ failedIds.add(formInstanceId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // ===== 单条处理结束 =====
|
|
|
|
+
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("处理单据失败: formInstanceId={}", formInstanceId, e);
|
|
|
|
+ failCount++;
|
|
|
|
+ failedIds.add(formInstanceId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 3. 返回批量处理结果
|
|
|
|
+ return McR.success("批量状态同步完成");
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
- public McR lilinLS(Map<String, Object> map) throws IOException {
|
|
|
|
- String accountNo = String.valueOf(map.get("accountNo"));
|
|
|
|
- OkHttpClient client = new OkHttpClient();
|
|
|
|
- String dayFromId = LocalDate.now().minusDays(3).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
|
|
|
|
+ public McR lilinLS(Map<String, Object> map) {
|
|
|
|
+// String accountNo = String.valueOf(map.get("accountNo"));
|
|
|
|
+ String accountNo = "888001";
|
|
|
|
+ if (accountNo == null || accountNo.trim().isEmpty()) {
|
|
|
|
+ return McR.errorParam("accountNo 不能为空");
|
|
|
|
+ }
|
|
|
|
+ accountNo = accountNo.trim();
|
|
|
|
+
|
|
|
|
+ log.info("开始对账单同步,accountNo: {}", accountNo);
|
|
|
|
+
|
|
|
|
+ // 准备时间范围
|
|
|
|
+ String dayFromId = LocalDate.now().minusDays(10).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
String dayToId = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
String dayToId = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
|
|
|
|
|
|
+ // 获取 token 一次
|
|
|
|
+ String securityCode;
|
|
|
|
+ try {
|
|
|
|
+ securityCode = String.valueOf(token().getData());
|
|
|
|
+ if (securityCode == null || securityCode.isEmpty()) {
|
|
|
|
+ log.error("获取 securityCode 失败");
|
|
|
|
+ return McR.errorParam("安全码获取失败");
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("调用 token() 异常", e);
|
|
|
|
+ return McR.errorParam("认证信息获取失败");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 构建 POST 请求体
|
|
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
|
|
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
|
|
- RequestBody body = RequestBody.create(mediaType, "securityCode=" + token().getData() + "&accountNo=" + accountNo + "&dayFromId=" + dayFromId + "&dayToId=" + dayToId + "&instructionIdFlag=1&pageNow=1&pageSize=20");
|
|
|
|
|
|
+ String requestBodyStr = "securityCode=" + securityCode +
|
|
|
|
+ "&accountNo=" + accountNo +
|
|
|
|
+ "&dayFromId=" + dayFromId +
|
|
|
|
+ "&dayToId=" + dayToId +
|
|
|
|
+ "&instructionIdFlag=1" +
|
|
|
|
+ "&pageNow=1" +
|
|
|
|
+ "&trxFlag=R" +
|
|
|
|
+ "&pageSize=20";
|
|
|
|
+
|
|
|
|
+ RequestBody body = RequestBody.create(mediaType, requestBodyStr);
|
|
|
|
+
|
|
Request request = new Request.Builder()
|
|
Request request = new Request.Builder()
|
|
.url("https://openapi.xencio.com/sandbox/cfa/api/bs/list")
|
|
.url("https://openapi.xencio.com/sandbox/cfa/api/bs/list")
|
|
.post(body)
|
|
.post(body)
|
|
.addHeader("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a")
|
|
.addHeader("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a")
|
|
- .addHeader("content-type", "application/x-www-form-urlencoded")
|
|
|
|
|
|
+ .addHeader("content-Type", "application/x-www-form-urlencoded")
|
|
.build();
|
|
.build();
|
|
|
|
|
|
- Response response = client.newCall(request).execute();
|
|
|
|
- String jsonstr = response.body().string();
|
|
|
|
- JSONObject jsonObject = JSONObject.parseObject(jsonstr);
|
|
|
|
- // 获取 data 对象
|
|
|
|
- JSONObject data = jsonObject.getJSONObject("data");
|
|
|
|
- // 获取 searchBankStatementList 数组
|
|
|
|
- JSONArray statementList = data.getJSONArray("searchBankStatementList");
|
|
|
|
- if (statementList == null) {
|
|
|
|
- log.error("响应体为空");
|
|
|
|
- return McR.errorParam("响应体为空");
|
|
|
|
- }
|
|
|
|
- // 用于存储提取的数据
|
|
|
|
- List<Map<String, String>> extractedList = new ArrayList<>();
|
|
|
|
-
|
|
|
|
- // 遍历数组,提取指定字段
|
|
|
|
- for (int i = 0; i < statementList.size(); i++) {
|
|
|
|
- JSONObject item = statementList.getJSONObject(i);
|
|
|
|
-
|
|
|
|
- Map<String, String> extractedItem = new HashMap<>();
|
|
|
|
-
|
|
|
|
- String bankStatementId = item.getString("bankStatementId");
|
|
|
|
- String bankComments = item.getString("bankComments");
|
|
|
|
- String userRemarks = item.getString("userRemarks");//用户备注
|
|
|
|
- String crAmount = item.getString("crAmount");
|
|
|
|
- String userMemo = item.getString("userMemo");
|
|
|
|
- String transFlag = item.getString("transFlag");
|
|
|
|
- String catalogName = item.getString("catalogName");
|
|
|
|
- String trxDate = item.getString("trxDate");
|
|
|
|
- long timestamp = LocalDateTime.parse(item.getString("trxDate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
|
|
|
- extractedItem.put("bankStatementId", bankStatementId);
|
|
|
|
- extractedItem.put("bankComments", bankComments);
|
|
|
|
- extractedItem.put("crAmount", crAmount);
|
|
|
|
- extractedItem.put("trxDate", trxDate);
|
|
|
|
- extractedItem.put("userRemarks", userRemarks);
|
|
|
|
- extractedItem.put("customerName", item.getString("customerName"));
|
|
|
|
-
|
|
|
|
- extractedList.add(extractedItem);
|
|
|
|
- List<Map> list = (List<Map>) ydClient.queryData(YDParam.builder().formUuid("FORM-AC0D84A40AD64E469C6AC6D049931C22IDO8").appType("APP_V25MK3XKODKB02UVTGSH")
|
|
|
|
- .systemToken("IQC66GC1L5TW5HKF6SX645RC4AXG2CFGQOMCMOQ4").searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mdh05xw6", bankStatementId)))
|
|
|
|
- .build(),
|
|
|
|
- YDConf.FORM_QUERY.retrieve_list_all).getData();
|
|
|
|
- if (list == null || list.isEmpty()) {
|
|
|
|
- Map formData = new HashMap();
|
|
|
|
- formData.put("dateField_m8yeduje", timestamp);
|
|
|
|
- formData.put("dateField_mbg6gyre", timestamp);
|
|
|
|
- formData.put("numberField_m9ibr418", crAmount);
|
|
|
|
- formData.put("textField_mdh05xw6", bankStatementId);
|
|
|
|
- formData.put("textField_m9ibr419", userRemarks);
|
|
|
|
- formData.put("textField_mdh51nxq", userMemo);
|
|
|
|
- formData.put("textField_mdh51nxr", transFlag);
|
|
|
|
- formData.put("textField_mdh51nxs", catalogName);
|
|
|
|
- ydClient.operateData(YDParam.builder()
|
|
|
|
- .formUuid("FORM-AC0D84A40AD64E469C6AC6D049931C22IDO8")
|
|
|
|
- .processCode("TPROC--K8C66U6152SW46P3DKE38BFVC2AA3HQGQOMCM13")
|
|
|
|
- .formDataJson(JSON.toJSONString(formData))
|
|
|
|
- .userId("3044156512693449078")
|
|
|
|
- .build(), YDConf.FORM_OPERATION.start);
|
|
|
|
|
|
+ OkHttpClient client = new OkHttpClient();
|
|
|
|
+
|
|
|
|
+ Response response = null;
|
|
|
|
+ try {
|
|
|
|
+ response = client.newCall(request).execute();
|
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
|
+ log.error("银行接口调用失败,HTTP状态码: {}", response.code());
|
|
|
|
+ return McR.errorParam("接口调用失败: " + response.code());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ String jsonStr = response.body().string();
|
|
|
|
+ log.debug("银行接口响应原始数据: {}", jsonStr);
|
|
|
|
|
|
|
|
+ JSONObject jsonObject = JSON.parseObject(jsonStr);
|
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
|
+ if (data == null) {
|
|
|
|
+ log.error("响应中缺少 'data' 字段");
|
|
|
|
+ return McR.errorParam("响应数据格式错误:缺少 data");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ JSONArray statementList = data.getJSONArray("searchBankStatementList");
|
|
|
|
+ if (statementList == null || statementList.isEmpty()) {
|
|
|
|
+ log.info("银行接口返回空列表,accountNo: {}", accountNo);
|
|
|
|
+ return McR.success("无对账单数据");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Map<String, String>> extractedList = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < statementList.size(); i++) {
|
|
|
|
+ JSONObject item = statementList.getJSONObject(i);
|
|
|
|
+ if (item == null) continue;
|
|
|
|
+
|
|
|
|
+ Map<String, String> extractedItem = new HashMap<>();
|
|
|
|
+ String bankStatementId = getStringValue(item, "bankStatementId");
|
|
|
|
+ String bankComments = getStringValue(item, "bankComments");
|
|
|
|
+ String crAmount = getStringValue(item, "crAmount");
|
|
|
|
+ String trxDate = getStringValue(item, "trxDate");
|
|
|
|
+ String userRemarks = getStringValue(item, "userRemarks");
|
|
|
|
+ String userMemo = getStringValue(item, "userMemo");
|
|
|
|
+ String transFlag = getStringValue(item, "transFlag");
|
|
|
|
+ String catalogName = getStringValue(item, "catalogName");
|
|
|
|
+ String customerName = getStringValue(item, "customerName");
|
|
|
|
+
|
|
|
|
+ // 提取时间戳
|
|
|
|
+ Long timestamp = null;
|
|
|
|
+ if (trxDate != null && !trxDate.isEmpty()) {
|
|
|
|
+ try {
|
|
|
|
+ timestamp = LocalDateTime.parse(trxDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
|
+ .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.warn("日期解析失败: {}", trxDate);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 填充提取数据
|
|
|
|
+ extractedItem.put("bankStatementId", bankStatementId);
|
|
|
|
+ extractedItem.put("bankComments", bankComments);
|
|
|
|
+ extractedItem.put("crAmount", crAmount);
|
|
|
|
+ extractedItem.put("trxDate", trxDate);
|
|
|
|
+ extractedItem.put("userRemarks", userRemarks);
|
|
|
|
+ extractedItem.put("customerName", customerName);
|
|
|
|
+ extractedList.add(extractedItem);
|
|
|
|
+
|
|
|
|
+ // ===== 查询是否已存在 =====
|
|
|
|
+ boolean exists = false;
|
|
|
|
+ try {
|
|
|
|
+ List<Map> list = (List<Map>) ydClient.queryData(
|
|
|
|
+ YDParam.builder()
|
|
|
|
+ .formUuid("FORM-AC0D84A40AD64E469C6AC6D049931C22IDO8")
|
|
|
|
+ .appType("APP_V25MK3XKODKB02UVTGSH")
|
|
|
|
+ .systemToken("IQC66GC1L5TW5HKF6SX645RC4AXG2CFGQOMCMOQ4")
|
|
|
|
+ .searchCondition(JSON.toJSONString(UtilMap.map("textField_mdh05xw6", bankStatementId)))
|
|
|
|
+ .build(),
|
|
|
|
+ YDConf.FORM_QUERY.retrieve_list_all
|
|
|
|
+ ).getData();
|
|
|
|
+
|
|
|
|
+ exists = list != null && !list.isEmpty();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("查询宜搭系统失败,bankStatementId: {}", bankStatementId, e);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // ===== 若不存在则创建 =====
|
|
|
|
+ if (!exists && bankStatementId != null && !bankStatementId.isEmpty()) {
|
|
|
|
+ try {
|
|
|
|
+ Map<String, Object> formData = new HashMap<>();
|
|
|
|
+ formData.put("dateField_m8yeduje", timestamp != null ? timestamp : System.currentTimeMillis());
|
|
|
|
+ formData.put("dateField_mbg6gyre", timestamp != null ? timestamp : System.currentTimeMillis());
|
|
|
|
+ formData.put("numberField_m9ibr418", crAmount);
|
|
|
|
+ formData.put("employeeField_m8yeduj3", Arrays.asList("275412081437800471"));
|
|
|
|
+ formData.put("textField_mdh05xw6", bankStatementId);
|
|
|
|
+ formData.put("textField_m9ibr419", userRemarks);
|
|
|
|
+ formData.put("textField_mdh51nxq", userMemo);
|
|
|
|
+ formData.put("textField_mdh51nxr", transFlag);
|
|
|
|
+ formData.put("textField_mdh51nxs", catalogName);
|
|
|
|
+
|
|
|
|
+ ydClient.operateData(YDParam.builder()
|
|
|
|
+ .formUuid("FORM-AC0D84A40AD64E469C6AC6D049931C22IDO8")
|
|
|
|
+ .processCode("TPROC--K8C66U6152SW46P3DKE38BFVC2AA3HQGQOMCM13")
|
|
|
|
+ .formDataJson(JSON.toJSONString(formData))
|
|
|
|
+ .userId("275412081437800471")
|
|
|
|
+ .build(), YDConf.FORM_OPERATION.start);
|
|
|
|
+
|
|
|
|
+ log.info("成功创建对账记录: bankStatementId={}", bankStatementId);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("创建对账记录失败: bankStatementId={}", bankStatementId, e);
|
|
|
|
+ }
|
|
|
|
+ } else if (exists) {
|
|
|
|
+ log.debug("记录已存在,跳过: bankStatementId={}", bankStatementId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ log.info("对账单同步完成,共处理 {} 条", extractedList.size());
|
|
|
|
+ return McR.success("同步完成"); // 可改为返回统计信息
|
|
|
|
+
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ log.error("网络IO异常", e);
|
|
|
|
+ return McR.errorParam("网络请求失败: " + e.getMessage());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("未知异常", e);
|
|
|
|
+ return McR.errorParam("处理过程发生错误: " + e.getMessage());
|
|
|
|
+ } finally {
|
|
|
|
+ // 确保 response 被关闭
|
|
|
|
+ if (response != null) {
|
|
|
|
+ try {
|
|
|
|
+ response.close();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.warn("关闭 response 失败", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
- return McR.success(extractedList);
|
|
|
|
|
|
+ // 工具方法:安全获取字符串值
|
|
|
|
+ private String getStringValue(JSONObject json, String key) {
|
|
|
|
+ Object value = json.get(key);
|
|
|
|
+ return value == null ? "" : value.toString();
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public McR lilinLSCF(Map<String, Object> map) throws IOException {
|
|
public McR lilinLSCF(Map<String, Object> map) throws IOException {
|
|
String formInstanceId = String.valueOf(map.get("formInstanceId"));
|
|
String formInstanceId = String.valueOf(map.get("formInstanceId"));
|
|
|
|
+ if (formInstanceId == null || formInstanceId.trim().isEmpty()) {
|
|
|
|
+ return McR.errorParam("formInstanceId 不能为空");
|
|
|
|
+ }
|
|
|
|
+ log.info("开始处理对账单拆分,formInstanceId: {}", formInstanceId);
|
|
|
|
|
|
- // 查询数据
|
|
|
|
- Map data = (Map) ydClient.queryData(YDParam.builder()
|
|
|
|
- .formInstId(formInstanceId)
|
|
|
|
- .appType(ydConf.getAppType())
|
|
|
|
- .systemToken(ydConf.getSystemToken())
|
|
|
|
- .userId(ddConf.getOperator())
|
|
|
|
- .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
|
|
+ String bankStatementIdStr = String.valueOf(map.get("bankStatementId"));
|
|
|
|
+ if (bankStatementIdStr == null || bankStatementIdStr.trim().isEmpty()) {
|
|
|
|
+ return McR.errorParam("bankStatementId 不能为空");
|
|
|
|
+ }
|
|
|
|
|
|
- // 初始化 body
|
|
|
|
- HashMap body = new HashMap<>();
|
|
|
|
|
|
+ // 查询表单数据
|
|
|
|
+ Map data;
|
|
|
|
+ try {
|
|
|
|
+ data = (Map) ydClient.queryData(YDParam.builder()
|
|
|
|
+ .formInstId(formInstanceId)
|
|
|
|
+ .appType(ydConf.getAppType())
|
|
|
|
+ .systemToken(ydConf.getSystemToken())
|
|
|
|
+ .userId(ddConf.getOperator())
|
|
|
|
+ .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("查询宜搭表单失败,formInstanceId: {}", formInstanceId, e);
|
|
|
|
+ return McR.errorParam("查询表单数据失败");
|
|
|
|
+ }
|
|
|
|
|
|
- // 获取必要的字段值
|
|
|
|
- String bankStatementId = String.valueOf(map.get("bankStatementId"));
|
|
|
|
- String userMemo = String.valueOf(data.get("textField_mdh51nxq"));
|
|
|
|
- String transFlag = String.valueOf(data.get("textField_mdh51nxr"));
|
|
|
|
- String catalogName = String.valueOf(data.get("textField_mdh51nxs"));
|
|
|
|
|
|
+ if (data == null) {
|
|
|
|
+ log.warn("表单数据为空,formInstanceId: {}", formInstanceId);
|
|
|
|
+ return McR.errorParam("表单数据为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 提取字段(安全获取)
|
|
|
|
+ String userMemo = getStringValue(data, "textField_mdh51nxq");
|
|
|
|
+ String transFlag = getStringValue(data, "textField_mdh51nxr");
|
|
|
|
+ String catalogName = getStringValue(data, "textField_mdh51nxs");
|
|
|
|
|
|
- // 处理表格字段
|
|
|
|
|
|
+ // 处理子表数据
|
|
List<Map<String, Object>> tableField = (List<Map<String, Object>>) data.get("tableField_m9m8zhyy");
|
|
List<Map<String, Object>> tableField = (List<Map<String, Object>>) data.get("tableField_m9m8zhyy");
|
|
- ArrayList<Object> subBankStatementList = new ArrayList<>();
|
|
|
|
|
|
+ List<Map<String, Object>> subBankStatementList = new ArrayList<>();
|
|
|
|
|
|
if (tableField != null && !tableField.isEmpty()) {
|
|
if (tableField != null && !tableField.isEmpty()) {
|
|
for (int i = 0; i < tableField.size(); i++) {
|
|
for (int i = 0; i < tableField.size(); i++) {
|
|
- Map<String, Object> map1 = tableField.get(i);
|
|
|
|
- Map<String, Object> newMap = new HashMap<>();
|
|
|
|
-
|
|
|
|
- int itemIndex = i + 1;
|
|
|
|
- BigDecimal amount = getAmountFromMap(map1, "numberField_m9u2a5tf");
|
|
|
|
- String projectInfo = String.valueOf(map1.get("textField_m8yedujm"));
|
|
|
|
-
|
|
|
|
- newMap.put("itemIndex", itemIndex);
|
|
|
|
- newMap.put("amount", amount.doubleValue()); // 转换为 double 类型
|
|
|
|
- newMap.put("projectInfo", projectInfo);
|
|
|
|
- newMap.put("userMemo", userMemo);
|
|
|
|
- newMap.put("transFlag", transFlag);
|
|
|
|
- newMap.put("catalogName", catalogName);
|
|
|
|
-
|
|
|
|
- subBankStatementList.add(newMap);
|
|
|
|
|
|
+ Map<String, Object> row = tableField.get(i);
|
|
|
|
+ if (row == null) continue;
|
|
|
|
+
|
|
|
|
+ Map<String, Object> newItem = new HashMap<>();
|
|
|
|
+ newItem.put("itemIndex", i + 1);
|
|
|
|
+ newItem.put("amount", getAmountFromMap(row, "numberField_m9u2a5tf").doubleValue());
|
|
|
|
+ newItem.put("projectInfo", getStringValue(row, "textField_m9i9k5cl")+"-"+getStringValue(row, "textField_m8yedujm"));
|
|
|
|
+ newItem.put("userMemo", userMemo);
|
|
|
|
+ newItem.put("trxFlag", transFlag);
|
|
|
|
+ newItem.put("catalogName", catalogName);
|
|
|
|
+
|
|
|
|
+ subBankStatementList.add(newItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // 构建请求体
|
|
|
|
- body.put("subBankStatementList", subBankStatementList);
|
|
|
|
- body.put("bankStatementId", Integer.parseInt(bankStatementId)); // 需要转换为 integer 类型
|
|
|
|
|
|
+ // 构建主请求体
|
|
|
|
+ Map<String, Object> requestBody = new HashMap<>();
|
|
|
|
+ try {
|
|
|
|
+ requestBody.put("bankStatementId", Integer.parseInt(bankStatementIdStr));
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
+ log.error("bankStatementId 格式错误: {}", bankStatementIdStr);
|
|
|
|
+ return McR.errorParam("bankStatementId 必须为整数");
|
|
|
|
+ }
|
|
|
|
+ requestBody.put("subBankStatementList", subBankStatementList);
|
|
|
|
|
|
- // 发送 POST 请求
|
|
|
|
|
|
+ // 请求参数
|
|
String url = "https://openapi.xencio.com/sandbox/cfa/api/sub/bs/splitBankStatement";
|
|
String url = "https://openapi.xencio.com/sandbox/cfa/api/sub/bs/splitBankStatement";
|
|
String securityCode = String.valueOf(token().getData());
|
|
String securityCode = String.valueOf(token().getData());
|
|
- Map headers = new HashMap<>();
|
|
|
|
|
|
+ if (securityCode == null || securityCode.isEmpty()) {
|
|
|
|
+ log.error("获取 securityCode 失败");
|
|
|
|
+ return McR.errorParam("认证失败");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
headers.put("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a");
|
|
headers.put("x-xencio-client-id", "4d9414e89bc24b0d89b678d9f20bc56a");
|
|
- Map params = new HashMap<>();
|
|
|
|
- params.put("securityCode", securityCode);
|
|
|
|
- String response = UtilHttp.doPost(url, headers, params, body);
|
|
|
|
- JSONObject jsonObject = JSON.parseObject(response);
|
|
|
|
|
|
|
|
- // 获取 subBankStatementList
|
|
|
|
- JSONArray subBankStatementList1 = jsonObject
|
|
|
|
- .getJSONObject("data")
|
|
|
|
- .getJSONObject("subBankStatement")
|
|
|
|
- .getJSONArray("subBankStatementList");
|
|
|
|
|
|
+// Map params = new HashMap<>();
|
|
|
|
+ headers.put("securityCode", securityCode);
|
|
|
|
+
|
|
|
|
+ // 第一次调用:拆分对账单
|
|
|
|
+ String response;
|
|
|
|
+ try {
|
|
|
|
+ response = UtilHttp.doPost(url, headers, new HashMap<>(), requestBody);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("调用 splitBankStatement 接口失败", e);
|
|
|
|
+ return McR.errorParam("接口调用失败: splitBankStatement");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ JSONObject jsonResponse;
|
|
|
|
+ try {
|
|
|
|
+ jsonResponse = JSON.parseObject(response);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("响应 JSON 解析失败: {}", response);
|
|
|
|
+ return McR.errorParam("响应格式错误");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 检查响应是否成功(假设返回 { "code": 0, "data": { ... } })
|
|
|
|
+ Integer code = jsonResponse.getInteger("code");
|
|
|
|
+ if (code == null || code != 200) {
|
|
|
|
+ String msg = jsonResponse.getString("msg");
|
|
|
|
+ log.warn("splitBankStatement 接口调用失败,code: {}, msg: {}", code, msg);
|
|
|
|
+ return McR.errorParam("接口返回错误: " + msg);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ JSONObject dataObj = jsonResponse.getJSONObject("data");
|
|
|
|
+ if (dataObj == null) {
|
|
|
|
+ log.warn("响应中缺少 data 字段: {}", response);
|
|
|
|
+ return McR.errorParam("响应数据缺失");
|
|
|
|
+ }
|
|
|
|
|
|
- // 创建集合用于存储结果,每条记录是一个 Map
|
|
|
|
|
|
+ JSONObject subBankStatement = dataObj.getJSONObject("subBankStatement");
|
|
|
|
+ if (subBankStatement == null) {
|
|
|
|
+ log.warn("响应中缺少 subBankStatement 字段");
|
|
|
|
+ return McR.errorParam("拆分结果缺失");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ JSONArray subBankStatementList1 = subBankStatement.getJSONArray("subBankStatementList");
|
|
|
|
+ if (subBankStatementList1 == null || subBankStatementList1.isEmpty()) {
|
|
|
|
+ log.info("拆分结果为空");
|
|
|
|
+ return McR.success("拆分成功,但无明细");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 封装返回结果
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
- // 遍历并封装到 Map 中
|
|
|
|
for (int i = 0; i < subBankStatementList1.size(); i++) {
|
|
for (int i = 0; i < subBankStatementList1.size(); i++) {
|
|
JSONObject item = subBankStatementList1.getJSONObject(i);
|
|
JSONObject item = subBankStatementList1.getJSONObject(i);
|
|
Map<String, Object> mapItem = new HashMap<>();
|
|
Map<String, Object> mapItem = new HashMap<>();
|
|
@@ -959,27 +1237,61 @@ public class LiLinServiceImpl implements LiLinService {
|
|
mapItem.put("projectInfo", item.getString("projectInfo"));
|
|
mapItem.put("projectInfo", item.getString("projectInfo"));
|
|
result.add(mapItem);
|
|
result.add(mapItem);
|
|
}
|
|
}
|
|
- for (int i = 0; i < result.size(); i++) {
|
|
|
|
- Map<String, Object> stringObjectMap = result.get(i);
|
|
|
|
|
|
|
|
- String url1 = "https://openapi.xencio.com/sandbox/cfa/api/sub/bs/updateProjectInfo";
|
|
|
|
|
|
+ int successCount = 0, failCount = 0;
|
|
|
|
+ String updateUrl = "https://openapi.xencio.com/sandbox/cfa/api/sub/bs/updateProjectInfo";
|
|
|
|
|
|
- String response1 = UtilHttp.doPost(url1, headers, params, stringObjectMap);
|
|
|
|
|
|
+ for (Map<String, Object> item : result) {
|
|
|
|
+ try {
|
|
|
|
+ String updateResponse = UtilHttp.doPost(updateUrl, headers, new HashMap<>(), item);
|
|
|
|
+ // 可选:判断 updateResponse 是否成功
|
|
|
|
+ successCount++;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("更新 projectInfo 失败,id: {}", item.get("id"), e);
|
|
|
|
+ failCount++;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- // 返回结果
|
|
|
|
- return McR.success(result); // 假设 McR.success 是一个返回成功响应的方法
|
|
|
|
|
|
+
|
|
|
|
+ log.info("拆分完成,共 {} 条,更新成功 {},失败 {}", result.size(), successCount, failCount);
|
|
|
|
+
|
|
|
|
+ // 返回结果(可附加统计)
|
|
|
|
+ return McR.success(result);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 工具方法:安全获取字符串
|
|
|
|
+ private String getStringValue(Map data, String key) {
|
|
|
|
+ Object val = data.get(key);
|
|
|
|
+ return val == null ? "" : val.toString().trim();
|
|
}
|
|
}
|
|
|
|
|
|
- // 工具方法:从 Map 中安全地获取 BigDecimal 类型的金额
|
|
|
|
|
|
+ // 工具方法:安全获取金额(默认 0)
|
|
private static BigDecimal getAmountFromMap(Map<String, Object> map, String key) {
|
|
private static BigDecimal getAmountFromMap(Map<String, Object> map, String key) {
|
|
Object value = map.get(key);
|
|
Object value = map.get(key);
|
|
- if (value == null) return BigDecimal.ZERO;
|
|
|
|
|
|
+ if (value == null) {
|
|
|
|
+ log.debug("金额字段为空,key: {}", key);
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (value instanceof Number) {
|
|
if (value instanceof Number) {
|
|
- return BigDecimal.valueOf(((Number) value).doubleValue());
|
|
|
|
|
|
+ // 优先处理数值类型
|
|
|
|
+ try {
|
|
|
|
+ return BigDecimal.valueOf(((Number) value).doubleValue());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.warn("Number 转换为 BigDecimal 失败,key: {}, value: {}", key, value, e);
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 尝试字符串解析
|
|
|
|
+ String strValue = value.toString().trim();
|
|
|
|
+ if (strValue.isEmpty()) {
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
+ }
|
|
|
|
+
|
|
try {
|
|
try {
|
|
- return new BigDecimal(value.toString());
|
|
|
|
|
|
+ return new BigDecimal(strValue);
|
|
} catch (NumberFormatException e) {
|
|
} catch (NumberFormatException e) {
|
|
|
|
+ log.warn("金额字符串格式错误,key: {}, value: {}", key, value);
|
|
return BigDecimal.ZERO;
|
|
return BigDecimal.ZERO;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1010,6 +1322,7 @@ public class LiLinServiceImpl implements LiLinService {
|
|
return 0.0;
|
|
return 0.0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
private BigDecimal safeGetBigDecimal(Map formData, String key) {
|
|
private BigDecimal safeGetBigDecimal(Map formData, String key) {
|
|
Object value = formData.get(key);
|
|
Object value = formData.get(key);
|
|
if (value == null) return BigDecimal.ZERO;
|
|
if (value == null) return BigDecimal.ZERO;
|