package com.malk.service.workhours;
import com.alibaba.fastjson.JSON;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McException;
import com.malk.server.dingtalk.DDR_New;
import com.malk.server.workhours.MonthClosingCheckRequest;
import com.malk.server.workhours.MonthClosingConf;
import com.malk.server.workhours.MonthClosingStatusResult;
import com.malk.server.workhours.MonthClosingValidationResult;
import com.malk.server.workhours.WHConf;
import com.malk.service.aliwork.YDClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.function.LongSupplier;
/**
* 月度封账统一校验服务。
*
*
TimeCard、补填、变更与封账流程均调用本服务,避免各业务维护不同口径。
* prd 2026-10-23:页面准入状态改为宜搭原生查询;本服务仍承担后端保存、
* 提交、审批补发及封账校验,不能随旧页面查询接口作废而停用。
*/
@Service
public class MonthClosingService {
private static final int PAGE_SIZE = 100;
private static final int MAX_PAGES = 1000;
private static final String APPROVAL_MONTH_FIELD = "textField_mmd2lv0y";
private static final String SUMMARY_MONTH_FIELD = "textField_mmbffvda";
private static final String SUMMARY_STATUS_IN_APPROVAL = "审批中";
private static final String REPAIR_SUMMARY_STATUS_PARTIAL = "部分成功";
private static final String WRITE_BACK_SUCCESS = "全部成功";
private static final String STATUS_CLOSED = "封账";
private static final String STATUS_REOPENED = "启封";
private static final long CLOSING_STATUS_CACHE_MILLIS = 5 * 60 * 1000L;
private static final ZoneId BUSINESS_ZONE = ZoneId.of("Asia/Shanghai");
private static final DateTimeFormatter MONTH_FORMATTER =
DateTimeFormatter.ofPattern("uuuuMM").withResolverStyle(ResolverStyle.STRICT);
private final ConcurrentMap> closingStatusRequests =
new ConcurrentHashMap<>();
private final ConcurrentMap closingStatusCache =
new ConcurrentHashMap<>();
private LongSupplier currentTimeMillis = System::currentTimeMillis;
@Autowired
private YDClient ydClient;
@Autowired
private WHConf whConf;
@Autowired
private MonthClosingConf closingConf;
/**
* 查询目标月份是否已封账。
*
* @param request 月份请求
* @return 已审批封账与进行中封账数量
*/
public MonthClosingStatusResult status(MonthClosingCheckRequest request) {
String monthText = validateRequest(request);
return queryClosingStatusCached(monthText);
}
/**
* 一次读取全部封账流程,预热实际封账月份、当前月和上月的五分钟缓存。
*
* @deprecated prd 2026-10-23:旧页面查询预热功能作废,对应定时任务已关闭。
* 仅保留历史方法兼容,不再自动调用;业务按需缓存及并发合并保持原样。
* @return 本次写入缓存的月份数量
*/
@Deprecated
public int warmUpClosingStatusCache() {
List