package easydo.technology.service;

import easydo.technology.components.JdbcClient;
import easydo.technology.enums.MESEnum;
import easydo.technology.exception.BizException;
import easydo.technology.model.*;
import easydo.technology.utils.StringUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@Service
public class FlowNoService {
    private static final DateTimeFormatter DFY_MD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DFY_MD_2 = DateTimeFormatter.ofPattern("yyyyMMdd");

    @Resource
    private JdbcClient jdbcClient;
    @Resource
    private DataSource dataSource;

    // 为每个类定义独立的私有锁，实现细粒度并发控制 (Warehouse 锁 Warehouse)
    private final Object warehouseLock = new Object();
    private final Object qualityLock = new Object();
    private final Object processStageLock = new Object();
    private final Object processRouteLock = new Object();
    private final Object productMaterialLock = new Object();
    private final Object customerLock = new Object();
    private final Object productBomLock = new Object();
    private final Object salePlanLock = new Object();
    private final Object purchasePlanLock = new Object();
    private final Object outsourcingPlanLock = new Object();
    private final Object productPlanLock = new Object();
    private final Object purchaseOrderLock = new Object();
    private final Object productOrderLock = new Object();
    private final Object productOrderDispatchLock = new Object();
    private final Object materialRequisitionLock = new Object();


    /**
     * 生成仓库编码 (Warehouse) - 独立解耦实现
     */
    public String generateWarehouseCode(Warehouse model, Connection connection) throws Exception {
        synchronized (warehouseLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, Warehouse.class, connection);
                if (count > 0) {
                    throw new BizException("仓库编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_WAREHOUSE.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置仓库流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_WAREHOUSE.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, Warehouse.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成质检方案编码 (QualityInspectProgram) - 独立解耦实现
     */
    public String generateQualityCode(QualityInspectProgram model, Connection connection) throws Exception {
        synchronized (qualityLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, QualityInspectProgram.class, connection);
                if (count > 0) {
                    throw new BizException("质检编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_QUALITY_INSPECT_PROGRAM.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置质检流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_QUALITY_INSPECT_PROGRAM.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, QualityInspectProgram.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成工序管理编码 (ProcessStage) - 独立解耦实现
     */
    public String generateProcessStageCode(ProcessStage model, Connection connection) throws Exception {
        synchronized (processStageLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProcessStage.class, connection);
                if (count > 0) {
                    throw new BizException("工序编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PROCESS_STAGE.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置工序流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PROCESS_STAGE.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProcessStage.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成工艺路线编码 (ProcessRoute) - 独立解耦实现
     */
    public String generateProcessRouteCode(ProcessRoute model, Connection connection) throws Exception {
        synchronized (processRouteLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProcessRoute.class, connection);
                if (count > 0) {
                    throw new BizException("工艺路线编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PROCESS_ROUTE.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置工艺路线流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PROCESS_ROUTE.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProcessRoute.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成物料编码 (ProductMaterial) - 独立解耦实现
     */
    public String generateProductMaterialCode(ProductMaterial model, Connection connection) throws Exception {
        synchronized (productMaterialLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductMaterial.class, connection);
                if (count > 0) {
                    throw new BizException("物料编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PRODUCT_MATERIAL.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置物料流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PRODUCT_MATERIAL.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductMaterial.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成客户编码 (Customer) - 独立解耦实现
     */
    public String generateCustomerCode(Customer model, Connection connection) throws Exception {
        synchronized (customerLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, Customer.class, connection);
                if (count > 0) {
                    throw new BizException("客户编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_CUSTOMER.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置客户流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_CUSTOMER.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, Customer.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成物料BOM编码 (ProductBom) - 独立解耦实现
     */
    public String generateProductBomCode(ProductBom model, Connection connection) throws Exception {
        synchronized (productBomLock) {
            String manualCode = model.getBomCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("bomCode", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductBom.class, connection);
                if (count > 0) {
                    throw new BizException("BOM编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PRODUCT_BOM.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置物料BOM流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PRODUCT_BOM.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("bomCode", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductBom.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成销售计划编码 (SalePlan) - 独立解耦实现
     */
    public String generateSalePlanCode(SalePlan model, Connection connection) throws Exception {
        synchronized (salePlanLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, SalePlan.class, connection);
                if (count > 0) {
                    throw new BizException("销售计划编号已存在: " + manualCode);
                }
                return manualCode;
            }
            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_SALE_PLAN.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置销售计划流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_SALE_PLAN.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, SalePlan.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成生产计划编码 (ProductPlan) - 独立解耦实现
     */
    public String generateProductPlanCode(ProductPlan model, Connection connection) throws Exception {
        synchronized (productPlanLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductPlan.class, connection);
                if (count > 0) {
                    throw new BizException("生产计划编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PRODUCT_PLAN.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置生产计划流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PRODUCT_PLAN.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductPlan.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成采购计划编码 (PurchasePlan) - 独立解耦实现
     */
    public String generatePurchasePlanCode(PurchasePlan model, Connection connection) throws Exception {
        synchronized (purchasePlanLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, PurchasePlan.class, connection);
                if (count > 0) {
                    throw new BizException("采购计划编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PURCHASE_PLAN.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置采购计划流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PURCHASE_PLAN.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, PurchasePlan.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成委外计划编码 (OutsourcingPlan) - 独立解耦实现
     */
    public String generateOutsourcingPlanCode(OutsourcingPlan model, Connection connection) throws Exception {
        synchronized (outsourcingPlanLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, OutsourcingPlan.class, connection);
                if (count > 0) {
                    throw new BizException("委外计划编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_OUTSOURCING_PLAN.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置委外计划流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_OUTSOURCING_PLAN.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, OutsourcingPlan.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成采购订单编码 (PurchaseOrder) - 独立解耦实现
     */
    public String generatePurchaseOrderCode(PurchaseOrder model, Connection connection) throws Exception {
        synchronized (purchaseOrderLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, PurchaseOrder.class, connection);
                if (count > 0) {
                    throw new BizException("采购订单编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PURCHASE_ORDER.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置采购订单流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PURCHASE_ORDER.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, PurchaseOrder.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成工单编码 (ProductOrder) - 独立解耦实现
     */
    public String generateProductOrderCode(ProductOrder model, Connection connection) throws Exception {
        synchronized (productOrderLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductOrder.class, connection);
                if (count > 0) {
                    throw new BizException("工单编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PRODUCT_ORDER.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置工单流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PRODUCT_ORDER.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductOrder.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成派工单编码 (ProductOrderDispatch) - 独立解耦实现
     */
    public String generateProductOrderDispatchCode(ProductOrderDispatch model, Connection connection) throws Exception {
        synchronized (productOrderDispatchLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductOrderDispatch.class, connection);
                if (count > 0) {
                    throw new BizException("派工单编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_PRODUCT_ORDER_DISPATCH.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置派工单流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_PRODUCT_ORDER_DISPATCH.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, ProductOrderDispatch.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 生成领料单编码 (MaterialRequisition) - 独立解耦实现
     */
    public String generateMaterialRequisitionCode(MaterialRequisition model, Connection connection) throws Exception {
        synchronized (materialRequisitionLock) {
            String manualCode = model.getCode();
            String tenantId = model.getTenantId();
            if (StringUtil.isNotEmpty(manualCode)) {
                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", manualCode);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, MaterialRequisition.class, connection);
                if (count > 0) {
                    throw new BizException("领料单编号已存在: " + manualCode);
                }
                return manualCode;
            }

            while (true) {
                FlowNo flowNo = new FlowNo();
                flowNo.setType(MESEnum.FLOW_NO_TYPE_MATERIAL_REQUISITION.getValue());
                flowNo.setTenantId(tenantId);
                flowNo = jdbcClient.getJdbcModel(flowNo, connection);
                if (flowNo == null) throw new BizException("未配置领料单流水号规则");

                String currDate = DFY_MD.format(LocalDateTime.now());
                String currDate2 = DFY_MD_2.format(LocalDateTime.now());
                if (StringUtil.isEmpty(flowNo.getCurrDate()) || !flowNo.getCurrDate().equals(currDate)) {
                    flowNo.setCurrDate(currDate);
                    flowNo.setCurrSeq(1);
                } else {
                    flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
                }

                String no;
                if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + String.format("%06d", flowNo.getCurrSeq());
                } else {
                    no = (flowNo.getPrefix() != null ? flowNo.getPrefix() : "") + currDate2 + String.format("%05d", flowNo.getCurrSeq());
                }
                flowNo.setCurrNo(no);

                Map<String, Object> updateMap = new HashMap<>();
                updateMap.put("type", MESEnum.FLOW_NO_TYPE_MATERIAL_REQUISITION.getValue());
                updateMap.put("tenantId", tenantId);
                jdbcClient.jdbcUpdate(flowNo, updateMap, connection);

                Map<String, Object> checkMap = new HashMap<>();
                checkMap.put("code", no);
                checkMap.put("tenantId", tenantId);
                int count = (int) jdbcClient.getJdbcCountByMap(checkMap, MaterialRequisition.class, connection);
                if (count == 0) return no;
            }
        }
    }

    /**
     * 原始流水号生成方法
     */
    public String getFlowNo(String type, Connection... connections) throws Exception {
        Connection connection = null;
        if (connections.length > 0) {
            connection = connections[0];
        } else {
            connection = dataSource.getConnection();
        }
        try {
            FlowNo flowNo = new FlowNo();
            flowNo.setType(type);
            flowNo = jdbcClient.getJdbcModel(flowNo, connection);

            DateTimeFormatter DFY_MD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            DateTimeFormatter DFY_MD_2 = DateTimeFormatter.ofPattern("yyyyMMdd");
            String currDate = DFY_MD.format(LocalDateTime.now());
            String currDate2 = DFY_MD_2.format(LocalDateTime.now());

            String no;
            if (StringUtil.isNotEmpty(flowNo.getCurrDate()) && !flowNo.getCurrDate().equals(currDate)) {
                flowNo.setCurrDate(currDate);
                flowNo.setCurrSeq(1);
            } else {
                flowNo.setCurrSeq(flowNo.getCurrSeq() + 1);
            }


            if (StringUtil.isEmpty(flowNo.getCurrDate())) {
                String currSeq = String.format("%06d", flowNo.getCurrSeq());
                no = flowNo.getPrefix() + currSeq;
            } else {
                String currSeq = String.format("%05d", flowNo.getCurrSeq());
                no = flowNo.getPrefix() + currDate2 + currSeq;
            }

            flowNo.setCurrNo(no);

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("type", type);
            jdbcClient.jdbcUpdate(flowNo, paramMap, connection);
            return no;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            if (connections.length == 0) {
                connection.close();
            }
        }

    }
}
