package com.microservices.pms.product.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.exception.NotFoundException;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.PageUtils;
import com.microservices.common.core.utils.PinYinStringUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.common.service.IPmsCommonService;
import com.microservices.pms.enterprise.domain.PmsEnterprise;
import com.microservices.pms.enterprise.service.IPmsEnterpriseService;
import com.microservices.pms.journals.service.IPmsJournalsService;
import com.microservices.pms.product.domain.*;
import com.microservices.pms.product.domain.enums.*;
import com.microservices.pms.product.domain.vo.*;
import com.microservices.pms.product.mapper.PmsProductRequirementMapper;
import com.microservices.pms.product.service.*;
import com.microservices.pms.project.domain.PmsProject;
import com.microservices.pms.project.domain.vo.PmsProjectIssuesInputVo;
import com.microservices.pms.project.service.IPmsProjectService;
import com.microservices.pms.project.service.PmsProjectIssuesService;
import com.microservices.pms.utils.PmsConstants;
import com.microservices.pms.utils.PmsGitLinkRequestUrl;
import com.microservices.pms.utils.PmsUtils;
import com.microservices.system.api.RemoteFileService;
import com.microservices.system.api.domain.SysUser;
import com.microservices.system.api.utils.FeignUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;

import static com.microservices.common.core.utils.PageUtils.startPage;

/**
 * 产品需求Service业务层处理
 *
 * @author otto
 * @date 2023-10-10
 */
@Service
public class PmsProductRequirementServiceImpl implements IPmsProductRequirementService {
    @Autowired
    private PmsProductRequirementMapper pmsProductRequirementMapper;
    @Autowired
    private IPmsEnterpriseService pmsEnterpriseService;
    @Autowired
    private IPmsProductPlanService pmsProductPlanService;
    @Autowired
    private IPmsProductService pmsProductService;
    @Autowired
    private IPmsProductModuleService pmsProductModuleService;
    @Autowired
    private IPmsProductRequirementTagService pmsProductRequirementTagService;
    @Autowired
    private IPmsProductPriorityService pmsProductPriorityService;
    @Autowired
    private IPmsProductReqOperationRecordService pmsProductReqOperationRecordService;
    @Autowired
    private IPmsCommonService pmsCommonService;
    @Autowired
    private IPmsProjectService pmsProjectService;
    @Autowired
    private PmsProjectIssuesService pmsProjectIssuesService;
    @Autowired
    @Lazy
    private IPmsJournalsService pmsJournalsService;
    @Autowired
    private RemoteFileService remoteFileService;
    @Autowired
    private GitLinkRequestHelper gitLinkRequestHelper;

    @Override
    public PmsProductRequirement selectPmsProductRequirementById(Long id, boolean checkRole) {
        PmsProductRequirement pmsProductRequirement = pmsProductRequirementMapper.selectPmsProductRequirementById(id);
        if (pmsProductRequirement == null) {
            throw new NotFoundException("该产品需求不存在(产品需求Id[%d])", id);
        }
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(pmsProductRequirement.getPmsProductIdentifier());
        if (checkRole) {
            pmsProductService.checkManageRole(pmsProduct);
        }
        return pmsProductRequirement;
    }


    @Override
    public GenericsTableDataInfo<ProductUserReqDataVo> selectUserReqList(ProductUserReqSearchVo productUserReqSearchVo) {
        pmsProductService.selectPmsProductByIdentifier(productUserReqSearchVo.getPmsProductIdentifier());
        startPage();
        List<PmsProductRequirement> userReqList = pmsProductRequirementMapper.selectUserReqList(productUserReqSearchVo);
        return PageUtils.toPage(userReqList, this::toProductUserReqDataVo);
    }

    private ProductUserReqDataVo toProductUserReqDataVo(PmsProductRequirement pmsProductRequirement) {
        ProductUserReqDataVo productUserReqDataVo = pmsProductRequirement.toProductUserReqDataVo();
        // 设置状态
        productUserReqDataVo.setStatus(ProductReqStatus.getTypeByKey(pmsProductRequirement.getStatus()));
        if (StringUtils.isNotEmpty(pmsProductRequirement.getReviewContent())
                && JSON.isValid(pmsProductRequirement.getReviewContent())) {
            JSONObject reviewContentJson = JSONObject.parseObject(pmsProductRequirement.getReviewContent());
            productUserReqDataVo.setReviewUser(reviewContentJson.getString("reviewUser"));
            productUserReqDataVo.setReviewContent(reviewContentJson.getString("reviewContent"));
        }
        return productUserReqDataVo;
    }

    @Override
    public ProductUserReqDetailVo selectUserReqDetailById(Long id) {
        PmsProductRequirement pmsProductRequirement = selectPmsProductRequirementById(id, false);
        PmsProductReqOperationRecord record = pmsProductReqOperationRecordService.selectUserReqLatestReviewRecord(pmsProductRequirement.getId());
        if (record != null) {
            pmsProductRequirement.setReviewContent(record.getContent());
            pmsProductRequirement.setReviewTime(record.getOperatingTime());
        }
        return toProductUserReqDetailVo(pmsProductRequirement);
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public Long insertUserReq(ProductUserReqInputVo productUserReqInputVo) {
        // 校验产品是否存在
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(productUserReqInputVo.getPmsProductIdentifier());
        pmsProductService.checkManageRole(pmsProduct);
        PmsProductRequirement pmsProductRequirement = productUserReqInputVo.toPmsProductRequirement();
        // 校验参数
        checkUserReqParameter(pmsProductRequirement, pmsProduct);
        if (StringUtils.isEmpty(productUserReqInputVo.getSourceCompany())) {
            PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseByIdentifier(productUserReqInputVo.getEnterpriseIdentifier());
            pmsProductRequirement.setSourceCompany(pmsEnterprise.getEnterpriseName());
        }
        // 设置默认需求状态
        pmsProductRequirement.setStatus(ProductReqStatus.PENDING_REVIEW_USER_REQ.getKey());

        pmsProductRequirement.setCreateAndUpdate(SecurityUtils.getUsername());

        pmsProductService.updatePmsProductChange(pmsProductRequirement.getPmsProductIdentifier());
        pmsProductRequirementMapper.insertPmsProductRequirement(pmsProductRequirement);
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(
                productUserReqInputVo.toPmsProductReqOperationRecord(pmsProductRequirement));
        return pmsProductRequirement.getId();
    }

    @Override
    public int updateUserReq(ProductUserReqUpdateVo productUserReqUpdateVo) {
        // 通过id检查需修改的产品需求是否存在
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(productUserReqUpdateVo.getId(), true);
        PmsProductRequirement pmsProductRequirement = productUserReqUpdateVo.toPmsProductRequirement();
        if (!ProductReqStatus.PENDING_REVIEW_USER_REQ.getKey().equals(oldPmsProductRequirement.getStatus())) {
            throw new ServiceException("只有待审核状态的用户需求才能修改");
        }

        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(oldPmsProductRequirement.getPmsProductIdentifier());
        checkUserReqParameter(pmsProductRequirement, pmsProduct);
        int success = updateRequirement(pmsProductRequirement, oldPmsProductRequirement.getPmsProductIdentifier());
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(
                productUserReqUpdateVo.toPmsProductReqOperationRecord(pmsProductRequirement));
        return success;
    }

    private void checkReqSpecsParameter(PmsProductRequirement pmsProductRequirement, PmsProduct pmsProduct, PmsProductRequirement oldPmsProductRequirement) {
        // 校验产品计划是否存在
        if (pmsProductRequirement.getPmsProductPlanId() != null) {
            PmsProductPlan pmsProductPlan = pmsProductPlanService.selectPmsProductPlanById(pmsProductRequirement.getPmsProductPlanId(), false);
            if (!pmsProductPlan.getPmsProductIdentifier().equals(pmsProduct.getProductIdentifier())) {
                throw new ServiceException("该产品计划不属于当前产品(计划标题[%s],产品名称[%s])", pmsProductPlan.getPlanTitle(), pmsProduct.getProductName());
            }

            if (oldPmsProductRequirement == null || oldPmsProductRequirement.getPmsProductPlanId() == null) {
                // 当原需求没有计划时，此操作相当于将该需求移入该计划，需要更新计划的更新时间
                pmsProductPlanService.updatePmsProductPlanChange(pmsProductRequirement.getPmsProductPlanId());
            } else if (!oldPmsProductRequirement.getPmsProductPlanId().equals(pmsProductRequirement.getPmsProductPlanId())) {
                // 当原需求有计划且该计划id与原计划id不同时，此操作相当于从原计划移入新计划，需要更新原计划和新计划的更新时间
                pmsProductPlanService.updatePmsProductPlanChange(pmsProductRequirement.getPmsProductPlanId());
                pmsProductPlanService.updatePmsProductPlanChange(oldPmsProductRequirement.getPmsProductPlanId());
            }
        } else if (oldPmsProductRequirement != null && oldPmsProductRequirement.getPmsProductPlanId() != null) {
            // 当原需求有计划且当前设置计划为空时，此操作相当于将该需求从原计划中移除，需更新原计划的更新时间
            pmsProductPlanService.updatePmsProductPlanChange(oldPmsProductRequirement.getPmsProductPlanId());
        }
        if (StringUtils.isNotEmpty(pmsProductRequirement.getType())) {
            ProductReqSpecsType.checkKey(pmsProductRequirement.getType());
        }
        checkUserReqParameter(pmsProductRequirement, pmsProduct);
    }

    private void checkUserReqParameter(PmsProductRequirement pmsProductRequirement, PmsProduct pmsProduct) {
        // 校验模块是否存在
        if (pmsProductRequirement.getPmsProductModuleId() != null) {
            checkModuleId(pmsProductRequirement.getPmsProductModuleId(), pmsProduct);
        }
        // 检查附件列表是否有异常数据
        pmsCommonService.getAllFileByFileIdentifiers(pmsProductRequirement.getFileIdentifiers());
    }

    private int updateRequirement(PmsProductRequirement pmsProductRequirement, String productIdentifier) {
        pmsProductRequirement.setUpdateBy(SecurityUtils.getUsername());
        pmsProductRequirement.setUpdateTime(DateUtils.getNowDate());
        pmsProductService.updatePmsProductChange(productIdentifier);
        return pmsProductRequirementMapper.updatePmsProductRequirement(pmsProductRequirement);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserReqByIds(Long[] ids) {
        int success = 0;
        for (Long id : ids) {
            success += deleteUserReqById(id);
        }
        return success;
    }


    /**
     * 删除产品需求信息
     *
     * @param id 产品需求主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserReqById(Long id) {
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(id, true);
        if (!ProductReqStatus.PENDING_REVIEW_USER_REQ.getKey().equals(oldPmsProductRequirement.getStatus())) {
            throw new ServiceException("只有待审核状态的用户需求才能被删除");
        }
        pmsJournalsService.deletePmsJournalsByTypeAndJournalId(PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, id);
        pmsProductService.updatePmsProductChange(oldPmsProductRequirement.getPmsProductIdentifier());
        return pmsProductRequirementMapper.deletePmsProductRequirementById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteReqSpecsByIds(Long[] ids) {
        int success = 0;
        for (Long id : ids) {
            success += deleteReqSpecsById(id);
        }
        return success;
    }


    /**
     * 删除产品需求信息
     *
     * @param id 产品需求主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteReqSpecsById(Long id) {
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(id, true);

        if (!ProductReqStatus.PENDING_REVIEW_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus()) &&
                !ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus()) &&
                !ProductReqStatus.REJECTED_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus())) {
            throw new ServiceException("只有待审核、变更中和已拒绝状态的需求规格才能被删除");
        }
        if (ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus())) {
            // 变更中需求规格被删除时需将原需求还原状态
            PmsProductRequirement fromReqSpecs = selectPmsProductRequirementById(oldPmsProductRequirement.getFromId(), true);
            fromReqSpecs.setStatus(ProductReqStatus.getFromStatus(fromReqSpecs.getStatus()).getKey());
            updateRequirement(fromReqSpecs, oldPmsProductRequirement.getPmsProductIdentifier());
            // 需求评论对象还原为原需求id
            pmsJournalsService.updateJournalsIdByTypeAndOldId(
                    PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, oldPmsProductRequirement.getId(), fromReqSpecs.getId());
            // 记录取消变更
            PmsProductReqOperationRecord record = new PmsProductReqOperationRecord();
            record.setProductRequirementId(fromReqSpecs.getId());
            record.setType(ProductReqOperationType.CONTENT_MODIFY.getKey());
            record.setOperation(ProductContentModifyOperation.CANCEL_CHANGE_REQ.getKey());
            record.setOperator(SecurityUtils.getUsername());
            record.setOperatingTime(DateUtils.getNowDate());
            pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(record);
        }
        pmsJournalsService.deletePmsJournalsByTypeAndJournalId(PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, id);
        pmsProductService.updatePmsProductChange(oldPmsProductRequirement.getPmsProductIdentifier());
        return pmsProductRequirementMapper.deletePmsProductRequirementById(id);
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public int reviewUserReq(ProductReqReviewVo productReqReviewVo) {
        // 通过id检查需修改的产品需求是否存在
        PmsProductRequirement userReq = selectPmsProductRequirementById(productReqReviewVo.getId(), true);
        if (!ProductReqStatus.PENDING_REVIEW_USER_REQ.getKey().equals(userReq.getStatus())) {
            throw new ServiceException("只有待审核状态的用户需求才能进行审核");
        }

        if (ProductReqReviewStatus.PASS.getKey().equals(productReqReviewVo.getReviewStatus())) {
            userReq.setStatus(ProductReqStatus.REVIEWED_USER_REQ.getKey());
            userReqToReqSpecs(userReq, productReqReviewVo.toUserReqRecord(SecurityUtils.getUsername()));
        } else if (ProductReqReviewStatus.REJECTED.getKey().equals(productReqReviewVo.getReviewStatus())) {
            userReq.setStatus(ProductReqStatus.REJECTED_USER_REQ.getKey());
        } else {
            throw new ServiceException("请选择正确的审核状态");
        }
        // 记录评审意见
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(
                productReqReviewVo.toUserReqRecord(SecurityUtils.getUsername()));
        return updateRequirement(userReq, userReq.getPmsProductIdentifier());
    }


    @Override
    public int reviewReqSpecs(ProductReqReviewVo productReqReviewVo) {
        // 通过id检查需修改的需求规格是否存在
        PmsProductRequirement reqSpecs = selectPmsProductRequirementById(productReqReviewVo.getId(), true);
        if (!ProductReqStatus.PENDING_REVIEW_REQ_SPECS.getKey().equals(reqSpecs.getStatus())
                && !ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(reqSpecs.getStatus())) {
            throw new ServiceException("只有待审核和变更中状态的需求规格才能进行审核");
        }
        if (ProductReqReviewStatus.PASS.getKey().equals(productReqReviewVo.getReviewStatus())) {
            if (ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(reqSpecs.getStatus())) {
                PmsProductRequirement fromReqSpecs = selectPmsProductRequirementById(reqSpecs.getFromId(), true);
                // 若原需求为计划中需同步更新计划详情
                if (ProductReqStatus.PLANNED_REQ_SPECS_CHANGING.getKey().equals(fromReqSpecs.getStatus())) {
                    List<String> forgeFileIdentifierList = null;
                    if (StringUtils.isNotEmpty(reqSpecs.getFileIdentifiers())) {
                        // 需求规格文件上传至forge
                        forgeFileIdentifierList = FeignUtils.getReturnData(
                                remoteFileService.uploadFileToForge(reqSpecs.getFileIdentifiers(), SecurityConstants.INNER)
                        );
                    }
                    PmsProjectIssuesInputVo issue = new PmsProjectIssuesInputVo();
                    issue.setSubject(reqSpecs.getTitle());
                    issue.setDescription(reqSpecs.getContent());
                    issue.setAttachmentIds(forgeFileIdentifierList);
                    issue.setPmProjectId(fromReqSpecs.getPmsProjectId());
                    pmsProjectIssuesService.updatePmsProjectIssues(fromReqSpecs.getProjectReqId(), issue);
                }
                // 变更中的需求规格通过评审后设置状态为原需规状态
                reqSpecs.setStatus(ProductReqStatus.getFromStatus(fromReqSpecs.getStatus()).getKey());
                // 变更中的需规通过审核时需将原需求状态调整为已变更
                fromReqSpecs.setStatus(ProductReqStatus.CHANGED_REQ_SPECS.getKey());
                updateRequirement(fromReqSpecs, reqSpecs.getPmsProductIdentifier());
            } else {
                reqSpecs.setStatus(ProductReqStatus.REVIEWED_REQ_SPECS.getKey());
            }
        } else if (ProductReqReviewStatus.REJECTED.getKey().equals(productReqReviewVo.getReviewStatus())) {
            if (ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(reqSpecs.getStatus())) {
                PmsProductRequirement fromReqSpecs = selectPmsProductRequirementById(reqSpecs.getFromId(), true);
                // 变更中的需求规格拒绝评审后设置状态为已拒绝变更状态
                reqSpecs.setStatus(ProductReqStatus.REJECTED_CHANGE_REQ_SPECS.getKey());
                // 变更中的需规通过审核时需将原需求状态调整为来源状态
                fromReqSpecs.setStatus(ProductReqStatus.getFromStatus(fromReqSpecs.getStatus()).getKey());
                updateRequirement(fromReqSpecs, reqSpecs.getPmsProductIdentifier());
                // 需求评论对象还原为原需求id
                pmsJournalsService.updateJournalsIdByTypeAndOldId(
                        PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, reqSpecs.getId(), fromReqSpecs.getId());
                // 原需规记录评审意见
                PmsProductReqOperationRecord oldReqSpecsRecord
                        = productReqReviewVo.toReqSpecsRecord(SecurityUtils.getUsername());
                oldReqSpecsRecord.setId(fromReqSpecs.getId());
                pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(oldReqSpecsRecord);
            } else {
                reqSpecs.setStatus(ProductReqStatus.REJECTED_REQ_SPECS.getKey());
            }
        } else {
            throw new ServiceException("请选择正确的审核状态");
        }
        // 记录评审意见
        PmsProductReqOperationRecord pmsProductReqOperationRecord
                = productReqReviewVo.toReqSpecsRecord(SecurityUtils.getUsername());
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(pmsProductReqOperationRecord);
        return updateRequirement(reqSpecs, reqSpecs.getPmsProductIdentifier());
    }

    /**
     * 用户需求转换为需求规格
     */
    private void userReqToReqSpecs(PmsProductRequirement userReq, PmsProductReqOperationRecord record) {
        PmsProductRequirement reqSpecs =
                userReq.userReqToReqSpecs();
        reqSpecs.setIdentifier(genReqSpecsIdentifier(userReq.getPmsProductIdentifier(), userReq.getTitle()));
        reqSpecs.setCreateAndUpdate(SecurityUtils.getUsername());
        pmsProductRequirementMapper.insertPmsProductRequirement(reqSpecs);
        record.setProductRequirementId(reqSpecs.getId());
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(record);
    }

    @Override
    public GenericsTableDataInfo<ProductReqSpecsDataVo> selectReqSpecsList(ProductReqSpecsSearchVo productReqSpecsSearchVo) {
        pmsProductService.selectPmsProductByIdentifier(productReqSpecsSearchVo.getPmsProductIdentifier());
        if (productReqSpecsSearchVo.getPmsProductModuleId() != null && productReqSpecsSearchVo.getPmsProductModuleId() != 0) {
            List<Long> moduleIdList = pmsProductModuleService.selectChildrenPmsProductModuleIdList(productReqSpecsSearchVo.getPmsProductModuleId());
            productReqSpecsSearchVo.setChildrenModuleIdList(moduleIdList);
        }
        startPage();
        List<PmsProductRequirement> userReqList = pmsProductRequirementMapper.selectReqSpecsList(productReqSpecsSearchVo);
        HashMap<String, Object> hashMap = new HashMap<>();
        return PageUtils.toPage(userReqList, x -> toProductReqSpecsDataVo(x, hashMap));
    }


    private ProductReqSpecsDataVo toProductReqSpecsDataVo(PmsProductRequirement pmsProductRequirement, HashMap<String, Object> hashMap) {
        ProductReqSpecsDataVo productReqSpecsDataVo = pmsProductRequirement.toProductReqSpecsDataVo();
        // 设置状态
        productReqSpecsDataVo.setStatus(ProductReqStatus.getTypeByKey(pmsProductRequirement.getStatus()));

        // 设置产品模块
        if (pmsProductRequirement.getPmsProductModuleId() != null) {
            productReqSpecsDataVo.setPmsProductModule(
                    PmsUtils.getSelectObjectInCache(
                            hashMap
                            , x -> pmsProductModuleService.selectPmsProductModuleById(x, false)
                            , pmsProductRequirement.getPmsProductModuleId())
            );
        }
        return productReqSpecsDataVo;
    }

    @Override
    public ProductReqSpecsDetailVo selectReqSpecsDetailById(Long id) {
        PmsProductRequirement pmsProductRequirement = selectPmsProductRequirementById(id, false);
        return toProductReqSpecsDetailVo(pmsProductRequirement);
    }

    private String genReqSpecsIdentifier(String productIdentifier, String reqTitle) {
        String reqTitleIdentifier = PinYinStringUtils.toFirstChar(reqTitle).replaceAll("[^a-z^A-Z]", "").toUpperCase();
        return productIdentifier + "-" + reqTitleIdentifier;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertReqSpecs(ProductReqSpecsInputVo productReqSpecsInputVo) {
        // 校验产品是否存在
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(productReqSpecsInputVo.getPmsProductIdentifier());
        pmsProductService.checkManageRole(pmsProduct);
        PmsProductRequirement pmsProductRequirement = productReqSpecsInputVo.toPmsProductRequirement();

        // 校验参数
        checkReqSpecsParameter(pmsProductRequirement, pmsProduct, null);

        // 生成需求唯一标识
        pmsProductRequirement.setIdentifier(genReqSpecsIdentifier(pmsProduct.getProductIdentifier(), productReqSpecsInputVo.getTitle()));
        // 设置默认需求状态
        pmsProductRequirement.setStatus(ProductReqStatus.PENDING_REVIEW_REQ_SPECS.getKey());

        pmsProductRequirement.setCreateAndUpdate(SecurityUtils.getUsername());

        pmsProductService.updatePmsProductChange(pmsProductRequirement.getPmsProductIdentifier());
        pmsProductRequirementMapper.insertPmsProductRequirement(pmsProductRequirement);
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(
                productReqSpecsInputVo.toPmsProductReqOperationRecord(pmsProductRequirement));
        return pmsProductRequirement.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateReqSpecs(ProductReqSpecsUpdateVo productReqSpecsUpdateVo) {
        // 通过id检查需修改的产品需求是否存在
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(productReqSpecsUpdateVo.getId(), true);
        PmsProductRequirement pmsProductRequirement = productReqSpecsUpdateVo.toPmsProductRequirement();
        int success = 0;
        PmsProductReqOperationRecord pmsProductReqOperationRecord;
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(oldPmsProductRequirement.getPmsProductIdentifier());
        checkReqSpecsParameter(pmsProductRequirement, pmsProduct, oldPmsProductRequirement);
        if (ProductReqStatus.REVIEWED_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus()) || ProductReqStatus.PLANNED_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus())) {
            if (productReqSpecsUpdateVo.isReqChange(oldPmsProductRequirement)) {
                throw new ServiceException("已评审或计划中的需求规格请通过需求变更调整需求内容（标题、正文、附件）");
            }
        } else if (ProductReqStatus.PENDING_REVIEW_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus()) || ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus())) {
            // 待审核和变更中的需求可随意更改
            if (StringUtils.isNotEmpty(productReqSpecsUpdateVo.getTitle())) {
                // 更新需求唯一标识
                pmsProductRequirement.setIdentifier(genReqSpecsIdentifier(pmsProduct.getProductIdentifier(), productReqSpecsUpdateVo.getTitle()));
            }
        } else {
            throw new ServiceException("当前状态下的需求规格不允许修改");
        }
        success = updateRequirement(pmsProductRequirement, oldPmsProductRequirement.getPmsProductIdentifier());

        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(productReqSpecsUpdateVo.toPmsProductReqOperationRecord(pmsProductRequirement));
        return success;
    }

    @Override
    public int changeReqSpecs(ProductReqSpecsChangeVo productReqSpecsChangeVo) {
        // 通过id检查需修改的产品需求是否存在
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(productReqSpecsChangeVo.getId(), true);
        if (!ProductReqStatus.REVIEWED_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus()) && !ProductReqStatus.PLANNED_REQ_SPECS.getKey().equals(oldPmsProductRequirement.getStatus())) {
            throw new ServiceException("仅已评审和计划中的需求规格才能发起需求变更");
        }
        if (!productReqSpecsChangeVo.isReqChange(oldPmsProductRequirement)) {
            throw new ServiceException("变更需求规格时，变更内容不能为空");
        }

        // 已评审或已计划的需规需要进行变更（创建一条对应的需规）
        // 调整原需规状态
        oldPmsProductRequirement.setStatus(ProductReqStatus.getToStatus(oldPmsProductRequirement.getStatus()).getKey());
        updateRequirement(oldPmsProductRequirement, oldPmsProductRequirement.getPmsProductIdentifier());
        // 创建变更后的需规
        PmsProductRequirement changingReqSpecs = oldPmsProductRequirement.toChangeReqSpecs(productReqSpecsChangeVo);
        if (StringUtils.isNotEmpty(productReqSpecsChangeVo.getTitle())) {
            // 更新需求唯一标识
            changingReqSpecs.setIdentifier(genReqSpecsIdentifier(oldPmsProductRequirement.getPmsProductIdentifier(), productReqSpecsChangeVo.getTitle()));
        }
        changingReqSpecs.setUpdateBy(SecurityUtils.getUsername());
        changingReqSpecs.setUpdateTime(DateUtils.getNowDate());
        int success = pmsProductRequirementMapper.insertPmsProductRequirement(changingReqSpecs);
        // 原需求评论需迁移至变更后的需求
        pmsJournalsService.updateJournalsIdByTypeAndOldId(PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, oldPmsProductRequirement.getId(), changingReqSpecs.getId());
        // 插入变更记录
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(productReqSpecsChangeVo.toReqSpecsChangeRecord(oldPmsProductRequirement.getId(), changingReqSpecs));
        return success;
    }

    @Override
    public int activePlan(ProductReqSpecsActivePlanVo productReqSpecsActivePlanVo) {
        // 通过id检查需修改的产品需求是否存在
        PmsProductRequirement reqSpecs = selectPmsProductRequirementById(productReqSpecsActivePlanVo.getId(), true);
        if (!ProductReqStatus.REVIEWED_REQ_SPECS.getKey().equals(reqSpecs.getStatus())) {
            throw new ServiceException("仅已评审状态的需求规格才能纳入计划");
        }
        PmsProject project = pmsProjectService.selectAndCheckPmsProjectById(productReqSpecsActivePlanVo.getProjectId());
        List<String> forgeFileIdentifierList = null;
        if (StringUtils.isNotEmpty(reqSpecs.getFileIdentifiers())) {
            // 需求规格文件上传至forge
            forgeFileIdentifierList = FeignUtils.getReturnData(
                    remoteFileService.uploadFileToForge(reqSpecs.getFileIdentifiers(), SecurityConstants.INNER)
            );
        }
        PmsProjectIssuesInputVo pmsProjectIssuesInputVo = productReqSpecsActivePlanVo.toPmsProjectIssuesInputVo(reqSpecs, forgeFileIdentifierList);

        JSONObject projectIssue = pmsProjectIssuesService.insertPmsProjectIssues(pmsProjectIssuesInputVo);
        reqSpecs.setPmsProjectId(project.getId());
        reqSpecs.setProjectReqId(projectIssue.getLong("id"));
        reqSpecs.setStatus(ProductReqStatus.PLANNED_REQ_SPECS.getKey());
        int success = updateRequirement(reqSpecs, reqSpecs.getPmsProductIdentifier());
        pmsProductReqOperationRecordService.insertPmsProductReqOperationRecord(
                productReqSpecsActivePlanVo.toPmsProductReqOperationRecord(reqSpecs)
        );
        return success;
    }

    @Override
    public List<ReqStatusCommonVo> selectUserReqStatusList() {
        return ProductReqStatus.getUserReqStatusList();
    }

    @Override
    public List<ReqStatusCommonVo> selectReqSpecsStatusList() {
        return ProductReqStatus.getReqSpecsStatusList();
    }

    @Override
    public List<EnumCommonVo> selectReqSpecsTypeList() {
        return ProductReqSpecsType.getReqSpecsTypeList();
    }

    @Override
    public JSONObject selectReqSpecsAssociatedPlanData(Long reqSpecsId) {
        PmsProductRequirement reqSpecs = selectPmsProductRequirementById(reqSpecsId, true);
        if (reqSpecs.getPmsProjectId() == null) {
            return null;
        }
        return gitLinkRequestHelper.doGet(
                PmsGitLinkRequestUrl.GET_REQ_SPECS_LINK_ISSUES(reqSpecs.getProjectReqId(), reqSpecs.getPmsProjectId())
        );
    }

    private ProductReqSpecsDetailVo toProductReqSpecsDetailVo(PmsProductRequirement pmsProductRequirement) {
        ProductReqSpecsDataVo productReqSpecsDataVo = toProductReqSpecsDataVo(pmsProductRequirement, null);
        ProductReqSpecsDetailVo productReqSpecsDetailVo = productReqSpecsDataVo.toProductReqSpecsDetailVo();
        productReqSpecsDetailVo.setContent(pmsProductRequirement.getContent());
        // 设置文件列表
        productReqSpecsDetailVo.setFileList(pmsCommonService.getAllFileByFileIdentifiers(pmsProductRequirement.getFileIdentifiers())
        );
        if (pmsProductRequirement.getPmsProjectId() != null) {
            productReqSpecsDetailVo.setProject(pmsProjectService.selectAndCheckPmsProjectById(pmsProductRequirement.getPmsProjectId()));
            if (pmsProductRequirement.getProjectReqId() != null) {
                productReqSpecsDetailVo.setProjectIssue(
                        pmsProjectIssuesService.selectPmsProjectIssueById(pmsProductRequirement.getProjectReqId(), pmsProductRequirement.getPmsProjectId()));
            }
        }
        // 设置产品计划
        if (pmsProductRequirement.getPmsProductPlanId() != null) {
            productReqSpecsDetailVo.setPmsProductPlan(
                    pmsProductPlanService.selectPmsProductPlanById(pmsProductRequirement.getPmsProductPlanId(), false));
        }
        productReqSpecsDetailVo.setCreateBy(pmsCommonService.getSimpleSysUserByUsername(pmsProductRequirement.getCreateBy()));
        productReqSpecsDetailVo.setCreateTime(pmsProductRequirement.getCreateTime());
        if (ProductReqStatus.CHANGING_REQ_SPECS.getKey().equals(pmsProductRequirement.getStatus())) {
            PmsProductReqOperationRecord changeRecord = pmsProductReqOperationRecordService.selectReqSpecsLatestChangeRecord(pmsProductRequirement.getFromId());
            if (changeRecord != null) {
                productReqSpecsDetailVo.setChangeBy(pmsCommonService.getSimpleSysUserByUsername(changeRecord.getOperator()));
                productReqSpecsDetailVo.setChangeTime(changeRecord.getOperatingTime());
            }
        }
        PmsProductRequirement fromReq = pmsProductRequirement;
        PmsProductReqOperationRecord record = null;
        while (fromReq != null) {
            if (ProductReqStatus.isUserReqStatus(fromReq.getStatus())) {
                record = pmsProductReqOperationRecordService.selectUserReqLatestReviewRecord(fromReq.getId());
            } else {
                record = pmsProductReqOperationRecordService.selectReqSpecsLatestReviewRecord(fromReq.getId());
            }

            if (record != null) {
                break;
            }
            fromReq = selectPmsProductRequirementById(fromReq.getFromId(), true);
        }
        if (record != null) {
            productReqSpecsDetailVo.setReviewTime(record.getOperatingTime());
            if (StringUtils.isNotEmpty(record.getContent())
                    && JSON.isValid(record.getContent())) {
                JSONObject reviewContentJson = JSONObject.parseObject(record.getContent());
                productReqSpecsDetailVo.setReviewUser(reviewContentJson.getString("reviewUser"));
                productReqSpecsDetailVo.setReviewContent(reviewContentJson.getString("reviewContent"));
            }
        }
        return productReqSpecsDetailVo;
    }

    private ProductUserReqDetailVo toProductUserReqDetailVo(PmsProductRequirement pmsProductRequirement) {
        ProductUserReqDataVo productUserReqDataVo = toProductUserReqDataVo(pmsProductRequirement);
        ProductUserReqDetailVo productUserReqDetailVo = productUserReqDataVo.toProductReqUserDetailVo();
        productUserReqDetailVo.setContent(pmsProductRequirement.getContent());
        // 设置文件列表
        productUserReqDetailVo.setFileList(pmsCommonService.getAllFileByFileIdentifiers(pmsProductRequirement.getFileIdentifiers())
        );
        // 设置产品模块
        if (pmsProductRequirement.getPmsProductModuleId() != null) {
            productUserReqDetailVo.setPmsProductModule(
                    pmsProductModuleService.selectPmsProductModuleById(pmsProductRequirement.getPmsProductModuleId(), false));
        }
        return productUserReqDetailVo;
    }

    private void checkPmsProductRequirement(PmsProductRequirement pmsProductRequirement, PmsProduct pmsProduct, PmsProductRequirement oldPmsProductRequirement) {
        if (StringUtils.isNotBlank(pmsProductRequirement.getRequirementAssigneeGitlinkIds())) {
            String[] gitlinkUserIdStrList = pmsProductRequirement.getRequirementAssigneeGitlinkIds().split(",");
            checkGitlinkUserIds(gitlinkUserIdStrList, pmsProduct);
        }

        // 校验产品计划是否存在
        if (pmsProductRequirement.getPmsProductPlanId() != null) {
            PmsProductPlan pmsProductPlan = pmsProductPlanService.selectPmsProductPlanById(pmsProductRequirement.getPmsProductPlanId(), false);
            if (!pmsProductPlan.getPmsProductIdentifier().equals(pmsProduct.getProductIdentifier())) {
                throw new ServiceException("该产品计划不属于当前产品(计划标题[%s],产品名称[%s])", pmsProductPlan.getPlanTitle(), pmsProduct.getProductName());
            }

            if (oldPmsProductRequirement == null || oldPmsProductRequirement.getPmsProductPlanId() == null) {
                // 当原需求没有计划时，此操作相当于将该需求移入该计划，需要更新计划的更新时间
                pmsProductPlanService.updatePmsProductPlanChange(pmsProductRequirement.getPmsProductPlanId());
            } else if (!oldPmsProductRequirement.getPmsProductPlanId().equals(pmsProductRequirement.getPmsProductPlanId())) {
                // 当原需求有计划且该计划id与原计划id不同时，此操作相当于从原计划移入新计划，需要更新原计划和新计划的更新时间
                pmsProductPlanService.updatePmsProductPlanChange(pmsProductRequirement.getPmsProductPlanId());
                pmsProductPlanService.updatePmsProductPlanChange(oldPmsProductRequirement.getPmsProductPlanId());
            }
        } else if (oldPmsProductRequirement != null && oldPmsProductRequirement.getPmsProductPlanId() != null) {
            // 当原需求有计划且当前设置计划为空时，此操作相当于将该需求从原计划中移除，需更新原计划的更新时间
            pmsProductPlanService.updatePmsProductPlanChange(oldPmsProductRequirement.getPmsProductPlanId());
        }
        // 校验项目是否存在
        if (pmsProductRequirement.getPmsProjectId() != null) {
            checkProjectId(pmsProductRequirement.getPmsProjectId(), pmsProduct);
        }


        // 校验模块是否存在
        if (pmsProductRequirement.getPmsProductModuleId() != null) {
            checkModuleId(pmsProductRequirement.getPmsProductModuleId(), pmsProduct);
        }

        // 校验标记是否存在
        pmsProductRequirementTagService.checkTags(pmsProductRequirement.getTags(), PmsConstants.PRODUCT_TAG_AND_MODULE_TYPE, pmsProduct.getPmsEnterpriseId());
        pmsProductRequirement.setTagIds(pmsProductRequirement.getTags());

        //校验结束时间需大于开始时间
        if (pmsProductRequirement.getStartTime() != null && pmsProductRequirement.getEndTime() != null) {
            if (pmsProductRequirement.getStartTime().after(pmsProductRequirement.getEndTime())) {
                throw new ServiceException("结束时间不能早于开始时间");
            }
        }

        // 检查附件列表是否有异常数据
        pmsCommonService.getAllFileByFileIdentifiers(pmsProductRequirement.getFileIdentifiers());
    }

    /**
     * 修改产品需求
     *
     * @param pmsProductRequirement 产品需求
     * @return 结果
     */
    @Override
    public int updatePmsProductRequirement(PmsProductRequirement pmsProductRequirement) {
        // 通过id检查需修改的产品需求是否存在
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(pmsProductRequirement.getId(), true);
        pmsProductRequirement.setPmsProductIdentifier(oldPmsProductRequirement.getPmsProductIdentifier());
        if (pmsProductRequirement.getPriorityId() != null) {
            // 设置需求优先级
            Long priorityId =
                    pmsProductPriorityService.selectPmsProductPriorityIdByInputId(pmsProductRequirement.getPriorityId(), PmsConstants.PRODUCT_STATUS_OR_PRIORITY_REQUIREMENT_TYPE);
            pmsProductRequirement.setPriorityId(priorityId);
        }

        // 设置需求状态
        // TODO:需要根据用户需求、需求规格来判断需求状态
        // pmsProductRequirement.setStatusId(statusId);
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(oldPmsProductRequirement.getPmsProductIdentifier());
        checkPmsProductRequirement(pmsProductRequirement, pmsProduct, oldPmsProductRequirement);
        if (pmsProductRequirement.getStartTime() != null && pmsProductRequirement.getEndTime() == null) {
            if (oldPmsProductRequirement.getEndTime() != null && pmsProductRequirement.getStartTime().after(oldPmsProductRequirement.getEndTime())) {
                throw new ServiceException("开始时间不能晚于结束时间");
            }
        }
        if (pmsProductRequirement.getStartTime() == null && pmsProductRequirement.getEndTime() != null) {
            if (oldPmsProductRequirement.getStartTime() != null && oldPmsProductRequirement.getStartTime().after(pmsProductRequirement.getEndTime())) {
                throw new ServiceException("结束时间不能早于开始时间");
            }
        }
        pmsProductRequirement.setUpdateBy(SecurityUtils.getUsername());
        pmsProductRequirement.setUpdateTime(DateUtils.getNowDate());
        pmsProductService.updatePmsProductChange(oldPmsProductRequirement.getPmsProductIdentifier());
        return pmsProductRequirementMapper.updatePmsProductRequirement(pmsProductRequirement);
    }

    @Override
    public int updatePmsProductRequirementChange(Long id) {
        PmsProductRequirement pmsProductRequirement = selectPmsProductRequirementById(id, false);
        pmsProductRequirement.setUpdateBy(SecurityUtils.getUsername());
        pmsProductRequirement.setUpdateTime(DateUtils.getNowDate());
        pmsProductService.updatePmsProductChange(pmsProductRequirement.getPmsProductIdentifier());
        return pmsProductRequirementMapper.updatePmsProductRequirement(pmsProductRequirement);
    }

    /**
     * 删除产品需求信息
     *
     * @param id 产品需求主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePmsProductRequirementById(Long id) {
        PmsProductRequirement oldPmsProductRequirement = selectPmsProductRequirementById(id, true);
        if (oldPmsProductRequirement.getPmsProductPlanId() != null) {
            pmsProductPlanService.updatePmsProductPlanChange(oldPmsProductRequirement.getPmsProductPlanId());
        }
        pmsJournalsService.deletePmsJournalsByTypeAndJournalId(PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT, id);
        pmsProductService.updatePmsProductChange(oldPmsProductRequirement.getPmsProductIdentifier());
        return pmsProductRequirementMapper.deletePmsProductRequirementById(id);
    }

    @Override
    public Integer selectPmsProductRequirementCount(PmsProductRequirement pmsProductRequirementSearch) {
        return pmsProductRequirementMapper.selectPmsProductRequirementCount(pmsProductRequirementSearch);
    }

    /**
     * 检查批量更新的产品需求是否属于同一个产品
     *
     * @param idList id列表
     */
    private void checkBatchUpdateInTheSameProduct(List<Long> idList) {
        List<String> productIdentifierList = pmsProductRequirementMapper.selectProductIdentifierListInRequirementIdList(idList);
        if (productIdentifierList != null && productIdentifierList.size() == 1) {
            // 校验数据权限
            PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(productIdentifierList.get(0));
            pmsProductService.checkManageRole(pmsProduct);
            return;
        }
        throw new ServiceException("批量编辑需求时仅允许编辑同一产品下需求");

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePmsProductRequirementByProductIdentifier(String productIdentifier) {
        PmsProductRequirement pmsProductRequirementSearch = new PmsProductRequirement();
        pmsProductRequirementSearch.setPmsProductIdentifier(productIdentifier);
        List<PmsProductRequirement> pmsProductRequirementList = pmsProductRequirementMapper.selectPmsProductRequirementList(pmsProductRequirementSearch);
        for (PmsProductRequirement pmsProductRequirement : pmsProductRequirementList) {
            deletePmsProductRequirementById(pmsProductRequirement.getId());
        }
    }

    @Override
    public void updatePmsProductRequirementNoPlanByPlanId(Long planId) {
        PmsProductRequirement pmsProductRequirementSearch = new PmsProductRequirement();
        pmsProductRequirementSearch.setPmsProductPlanId(planId);
        List<PmsProductRequirement> pmsProductRequirementList = pmsProductRequirementMapper.selectPmsProductRequirementList(pmsProductRequirementSearch);
        for (PmsProductRequirement pmsProductRequirement : pmsProductRequirementList) {
            pmsProductRequirement.setPmsProductPlanId(null);
            updatePmsProductRequirement(pmsProductRequirement);
        }
    }

    @Override
    public void updatePmsProductRequirementToNoModule(Long moduleId) {
        PmsProductRequirement pmsProductRequirementSearch = new PmsProductRequirement();
        pmsProductRequirementSearch.setPmsProductModuleId(moduleId);
        List<PmsProductRequirement> pmsProductRequirementList = pmsProductRequirementMapper.selectPmsProductRequirementList(pmsProductRequirementSearch);
        for (PmsProductRequirement pmsProductRequirement : pmsProductRequirementList) {
            pmsProductRequirement.setPmsProductModuleId(null);
            updatePmsProductRequirement(pmsProductRequirement);
        }
    }

    @Override
    public List<PmsProductRequirement> selectPmsProductRequirementList(PmsProductRequirement pmsProductRequirementSearch) {
        return pmsProductRequirementMapper.selectPmsProductRequirementList(pmsProductRequirementSearch);
    }

    private int batchUpdatePmsProductRequirementByJsonObject(List<Long> idList, JSONObject jsonObject) {
        PmsProductRequirementBatchUpdateVo pmsProductRequirementBatchUpdateVo = new PmsProductRequirementBatchUpdateVo();
        pmsProductRequirementBatchUpdateVo.setIdList(idList);
        if (jsonObject.containsKey("priorityId")) {
            pmsProductRequirementBatchUpdateVo.setPriorityId(jsonObject.getLong("priorityId"));
            pmsProductRequirementBatchUpdateVo.setPriorityIdIsChange(true);
        }
        // TODO:需考虑是否涉及状态的变更
        if (jsonObject.containsKey("pmsProductModuleId")) {
            pmsProductRequirementBatchUpdateVo.setPmsProductModuleId(jsonObject.getLong("pmsProductModuleId"));
            pmsProductRequirementBatchUpdateVo.setPmsProductModuleIdIsChange(true);
        }
        if (jsonObject.containsKey("tags")) {
            pmsProductRequirementBatchUpdateVo.setTagIds(jsonObject.getString("tags"));
            pmsProductRequirementBatchUpdateVo.setTagIdsIsChange(true);
        }
        if (jsonObject.containsKey("requirementAssigneeGitlinkIds")) {
            pmsProductRequirementBatchUpdateVo.setRequirementAssigneeGitlinkIds(jsonObject.getString("requirementAssigneeGitlinkIds"));
            pmsProductRequirementBatchUpdateVo.setRequirementAssigneeGitlinkIdsIsChange(true);
        }
        if (jsonObject.containsKey("pmsProjectId")) {
            pmsProductRequirementBatchUpdateVo.setPmsProjectId(jsonObject.getLong("pmsProjectId"));
            pmsProductRequirementBatchUpdateVo.setPmsProjectIdIsChange(true);
        }
        if (jsonObject.containsKey("pmsProductPlanId")) {
            pmsProductRequirementBatchUpdateVo.setPmsProductPlanId(jsonObject.getLong("pmsProductPlanId"));
            pmsProductRequirementBatchUpdateVo.setPmsProductPlanIdIsChange(true);
        }
        if (pmsProductRequirementBatchUpdateVo.thisIsChange()) {
            checkPmsProductRequirementBatchUpdateVo(pmsProductRequirementBatchUpdateVo);
            pmsProductRequirementBatchUpdateVo.setUpdateBy(SecurityUtils.getUsername());
            pmsProductRequirementBatchUpdateVo.setUpdateTime(DateUtils.getNowDate());
            return pmsProductRequirementMapper.batchUpdatePmsProductRequirement(pmsProductRequirementBatchUpdateVo);
        }
        return 1;
    }


    private void checkPmsProductRequirementBatchUpdateVo(PmsProductRequirementBatchUpdateVo pmsProductRequirementBatchUpdateVo) {
        if (pmsProductRequirementBatchUpdateVo.getIdList() == null || pmsProductRequirementBatchUpdateVo.getIdList().isEmpty()) {
            return;
        }
        PmsProductRequirement oldPmsProductRequirement =
                pmsProductRequirementMapper.selectPmsProductRequirementById(pmsProductRequirementBatchUpdateVo.getIdList().get(0));
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(oldPmsProductRequirement.getPmsProductIdentifier());
        if (pmsProductRequirementBatchUpdateVo.getRequirementAssigneeGitlinkIdsIsChange()
                && StringUtils.isNotBlank(pmsProductRequirementBatchUpdateVo.getRequirementAssigneeGitlinkIds())) {
            String[] gitlinkUserIdStrList = pmsProductRequirementBatchUpdateVo.getRequirementAssigneeGitlinkIds().split(",");
            checkGitlinkUserIds(gitlinkUserIdStrList, pmsProduct);
        }

        // 校验产品计划是否存在
        if (pmsProductRequirementBatchUpdateVo.getPmsProductPlanIdIsChange()
                && pmsProductRequirementBatchUpdateVo.getPmsProductPlanId() != null) {
            checkProductPlanId(pmsProductRequirementBatchUpdateVo.getPmsProductPlanId(), pmsProduct);
        }

        // 校验项目是否存在
        if (pmsProductRequirementBatchUpdateVo.getPmsProjectIdIsChange()
                && pmsProductRequirementBatchUpdateVo.getPmsProjectId() != null) {
            checkProjectId(pmsProductRequirementBatchUpdateVo.getPmsProjectId(), pmsProduct);
        }

        // 校验模块是否存在
        if (pmsProductRequirementBatchUpdateVo.getPmsProductModuleIdIsChange()
                && pmsProductRequirementBatchUpdateVo.getPmsProductModuleId() != null) {
            checkModuleId(pmsProductRequirementBatchUpdateVo.getPmsProductModuleId(), pmsProduct);
        }

        if (pmsProductRequirementBatchUpdateVo.getTagIdsIsChange()) {
            // 校验标记是否存在
            pmsProductRequirementTagService.checkTags(
                    pmsProductRequirementBatchUpdateVo.getTagIds(),
                    PmsConstants.PRODUCT_TAG_AND_MODULE_TYPE,
                    pmsProduct.getPmsEnterpriseId());
        }
        if (pmsProductRequirementBatchUpdateVo.getPriorityIdIsChange()) {
            pmsProductPriorityService.selectPmsProductPriorityIdByInputId(pmsProductRequirementBatchUpdateVo.getPriorityId(), PmsConstants.PRODUCT_STATUS_OR_PRIORITY_REQUIREMENT_TYPE);
        }

        // TODO:需考虑是否涉及状态的变更
    }

    private void checkProjectId(Long projectId, PmsProduct pmsProduct) {
        PmsProject pmsProject = pmsProjectService.selectAndCheckPmsProjectById(projectId);
        if (pmsProject.getPmsProductId() == null || !pmsProject.getPmsProductId().equals(pmsProduct.getId())) {
            throw new ServiceException("该项目不属于当前产品(项目名称[%s],产品名称[%s])", pmsProject.getProjectName(), pmsProduct.getProductName());
        }
    }

    private void checkGitlinkUserIds(String[] gitlinkUserIdStrList, PmsProduct pmsProduct) {
        for (String gitlinkUserIdStr : gitlinkUserIdStrList) {
            try {
                Long gitlinkUserId = Long.parseLong(gitlinkUserIdStr);
                SysUser productAssigneeUser = pmsCommonService.getSysUserByGitlinkId(gitlinkUserId);
                boolean isExist = pmsEnterpriseService.checkUserInEnterprise(pmsProduct.getPmsEnterpriseId(), productAssigneeUser.getUserId());
                if (!isExist) {
                    PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseById(pmsProduct.getPmsEnterpriseId());
                    throw new ServiceException("该产品需求的负责人不在当前企业中(企业名称[%s],用户名[%s])", pmsEnterprise.getEnterpriseName(), productAssigneeUser.getUserName());
                }
            } catch (NumberFormatException e) {
                throw new ServiceException("该Gitlink用户Id格式错误(Gitlink用户id[%s])", gitlinkUserIdStr);
            }
        }
    }

    private void checkProductPlanId(Long productPlanId, PmsProduct pmsProduct) {
        PmsProductPlan pmsProductPlan = pmsProductPlanService.selectPmsProductPlanById(productPlanId, false);
        if (!pmsProductPlan.getPmsProductIdentifier().equals(pmsProduct.getProductIdentifier())) {
            throw new ServiceException("该产品计划不属于当前产品(计划标题[%s],产品名称[%s])", pmsProductPlan.getPlanTitle(), pmsProduct.getProductName());
        }
    }

    private void checkModuleId(Long moduleId, PmsProduct pmsProduct) {
        PmsProductModule pmsProductModule = pmsProductModuleService.selectPmsProductModuleById(moduleId, false);
        if (!pmsProductModule.getPmsProductIdentifier().equals(pmsProduct.getProductIdentifier())) {
            throw new ServiceException("该模块不属于当前产品(模块名称[%s],产品名称[%s])", pmsProductModule.getModuleName(), pmsProduct.getProductName());
        }
    }
}
