|
@@ -13,6 +13,7 @@ import com.malk.utils.UtilMap;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -125,6 +126,7 @@ public class ApprovalWriteBackService {
|
|
|
* @param result 审批结果:0=拒绝/撤销,1=同意
|
|
* @param result 审批结果:0=拒绝/撤销,1=同意
|
|
|
* @return 回写结果统计
|
|
* @return 回写结果统计
|
|
|
*/
|
|
*/
|
|
|
|
|
+ @Async
|
|
|
public ApprovalWriteBackResult writeBack(String formInstanceId, int result) {
|
|
public ApprovalWriteBackResult writeBack(String formInstanceId, int result) {
|
|
|
McException.assertAccessException(StringUtils.isBlank(formInstanceId), "实例ID不能为空");
|
|
McException.assertAccessException(StringUtils.isBlank(formInstanceId), "实例ID不能为空");
|
|
|
|
|
|
|
@@ -209,6 +211,12 @@ public class ApprovalWriteBackService {
|
|
|
executor.shutdown();
|
|
executor.shutdown();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 6. 同步状态汇总(syncTotal=分组数;failCount=失败组数;status=成功/部分成功/失败)
|
|
|
|
|
+ int syncTotal = groups.size();
|
|
|
|
|
+ int failCount = failRecords.get();
|
|
|
|
|
+ String syncStatus = (syncTotal == 0 || failCount == 0) ? "成功"
|
|
|
|
|
+ : (failCount < syncTotal ? "部分成功" : "失败");
|
|
|
|
|
+
|
|
|
ApprovalWriteBackResult stats = ApprovalWriteBackResult.builder()
|
|
ApprovalWriteBackResult stats = ApprovalWriteBackResult.builder()
|
|
|
.formType(isOther ? "其他工时审批" : "工时审批")
|
|
.formType(isOther ? "其他工时审批" : "工时审批")
|
|
|
.formInstanceId(formInstanceId)
|
|
.formInstanceId(formInstanceId)
|
|
@@ -218,12 +226,53 @@ public class ApprovalWriteBackService {
|
|
|
.hitRecords(hitRecords.get())
|
|
.hitRecords(hitRecords.get())
|
|
|
.updatedRows(updatedRows.get())
|
|
.updatedRows(updatedRows.get())
|
|
|
.missRows(missRows.get())
|
|
.missRows(missRows.get())
|
|
|
- .failRecords(failRecords.get())
|
|
|
|
|
|
|
+ .failRecords(failCount)
|
|
|
|
|
+ .syncStatus(syncStatus)
|
|
|
|
|
+ .syncTotal(syncTotal)
|
|
|
|
|
+ .failCount(failCount)
|
|
|
.build();
|
|
.build();
|
|
|
log.info("[审批回写] 完成 {}", stats);
|
|
log.info("[审批回写] 完成 {}", stats);
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 延迟 2s 等宜搭审批结束的内部同步索引/锁释放,再回写审批单同步字段,避免触发同步锁失败
|
|
|
|
|
+ sleep(2000);
|
|
|
|
|
+ writebackSyncFields(isOther, formInstanceId, syncStatus, syncTotal, failCount);
|
|
|
|
|
+
|
|
|
return stats;
|
|
return stats;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 把同步状态/同步总数/失败数量回写到原审批单(fieldId 走 WHConf 配置)
|
|
|
|
|
+ * fixme 三个 fieldId 任一为空则跳过该类别回写,允许业务方分阶段在宜搭后台建字段
|
|
|
|
|
+ */
|
|
|
|
|
+ private void writebackSyncFields(boolean isOther, String formInstanceId,
|
|
|
|
|
+ String syncStatus, int syncTotal, int failCount) {
|
|
|
|
|
+ String statusField = isOther ? whConf.getOtherApprovalSyncStatusField() : whConf.getApprovalSyncStatusField();
|
|
|
|
|
+ String totalField = isOther ? whConf.getOtherApprovalSyncTotalField() : whConf.getApprovalSyncTotalField();
|
|
|
|
|
+ String failField = isOther ? whConf.getOtherApprovalSyncFailField() : whConf.getApprovalSyncFailField();
|
|
|
|
|
+ if (StringUtils.isAnyBlank(statusField, totalField, failField)) {
|
|
|
|
|
+ log.info("[审批回写] 跳过审批单同步字段回写(配置未启用) isOther={} formInstanceId={}", isOther, formInstanceId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ Map<String, Object> sync = new HashMap<>();
|
|
|
|
|
+ sync.put(statusField, syncStatus);
|
|
|
|
|
+ sync.put(totalField, syncTotal);
|
|
|
|
|
+ sync.put(failField, failCount);
|
|
|
|
|
+ ydClient.operateData(YDParam.builder()
|
|
|
|
|
+ .appType(whConf.getYidaAppType())
|
|
|
|
|
+ .systemToken(whConf.getYidaSystemToken())
|
|
|
|
|
+ .formInstanceId(formInstanceId)
|
|
|
|
|
+ .updateFormDataJson(JSON.toJSONString(sync))
|
|
|
|
|
+ .ignoreEmpty(false)
|
|
|
|
|
+ .useLatestVersion(true)
|
|
|
|
|
+ .build(), YDConf.FORM_OPERATION.update);
|
|
|
|
|
+ log.info("[审批回写] 审批单同步字段已回写 isOther={} formInstanceId={} status={} total={} fail={}",
|
|
|
|
|
+ isOther, formInstanceId, syncStatus, syncTotal, failCount);
|
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
|
+ log.error("[审批回写] 审批单同步字段回写失败 isOther={} formInstanceId={}", isOther, formInstanceId, ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 处理单条汇总表日记录
|
|
* 处理单条汇总表日记录
|
|
|
*
|
|
*
|
|
@@ -378,20 +427,28 @@ public class ApprovalWriteBackService {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 子表取数控制:主表详情已内联返回子表时,行数 <50 视为完整直接用;
|
|
* 子表取数控制:主表详情已内联返回子表时,行数 <50 视为完整直接用;
|
|
|
- * ==50(可能被宜搭截断)或内联缺失,才调 {@link YDService#queryDetails} 递归取全,避免无效请求。
|
|
|
|
|
|
|
+ * ==50(可能被宜搭截断)才调 {@link YDService#queryDetails} 递归取全,避免无效请求。
|
|
|
* 复用 ydService 封装,不重复造分页轮子。
|
|
* 复用 ydService 封装,不重复造分页轮子。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * fixme inlineRows==null 表示审批单不含该子表(如其他工时审批单无 BILLABLE/NON_BILLABLE,或工时审批单某一子表未填):
|
|
|
|
|
+ * 直接返回空 list,不再调 queryDetails——基座 _queryDetails 对宜搭返回 data=null 的空子表查询会触发
|
|
|
|
|
+ * ArrayList.addAll(null) NPE。queryDetails 返回 null 同样兜底空 list。
|
|
|
*/
|
|
*/
|
|
|
private List<Map> resolveDetailRows(String formInstanceId, String tableId, List<Map> inlineRows) {
|
|
private List<Map> resolveDetailRows(String formInstanceId, String tableId, List<Map> inlineRows) {
|
|
|
- if (inlineRows != null && inlineRows.size() < 50) {
|
|
|
|
|
|
|
+ if (inlineRows == null) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (inlineRows.size() < 50) {
|
|
|
return inlineRows;
|
|
return inlineRows;
|
|
|
}
|
|
}
|
|
|
- return ydService.queryDetails(YDParam.builder()
|
|
|
|
|
|
|
+ List<Map> full = ydService.queryDetails(YDParam.builder()
|
|
|
.appType(whConf.getYidaAppType())
|
|
.appType(whConf.getYidaAppType())
|
|
|
.systemToken(whConf.getYidaSystemToken())
|
|
.systemToken(whConf.getYidaSystemToken())
|
|
|
.formInstanceId(formInstanceId)
|
|
.formInstanceId(formInstanceId)
|
|
|
.tableFieldId(tableId)
|
|
.tableFieldId(tableId)
|
|
|
.pageNumber(1)
|
|
.pageNumber(1)
|
|
|
.build());
|
|
.build());
|
|
|
|
|
+ return full != null ? full : Collections.emptyList();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|