package com.zt.plat.module.qms.resource.record.service.recordapply;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
import com.zt.plat.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import com.zt.plat.module.qms.api.task.BMPCallbackInterface;
import com.zt.plat.module.qms.api.task.dto.QmsBpmDTO;
import com.zt.plat.module.qms.common.data.dal.dataobject.DataCommonType;
import com.zt.plat.module.qms.common.data.service.DataKeyCheckService;
import com.zt.plat.module.qms.common.data.service.DataOpinionService;
import com.zt.plat.module.qms.common.service.BusinessFileService;
import com.zt.plat.module.qms.enums.QmsBpmConstant;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.qms.resource.clientManage.controller.vo.UploadFileVo;
import com.zt.plat.module.qms.resource.record.constant.RecordConstants;
import com.zt.plat.module.qms.resource.record.controller.admin.recordapply.vo.RecordApplyPageReqVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordapply.vo.RecordApplyRespVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordapply.vo.RecordApplySaveReqVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordapplydetail.vo.RecordApplyDetailPageReqVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordapplydetail.vo.RecordApplyDetailSaveReqVO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordapply.RecordApplyDO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordapplydetail.RecordApplyDetailDO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordpermission.RecordPermissionDO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordrecord.RecordRecordDO;
import com.zt.plat.module.qms.resource.record.dal.mapper.RecordApplyMapper;
import com.zt.plat.module.qms.resource.record.service.recordapplydetail.RecordApplyDetailService;
import com.zt.plat.module.qms.resource.record.service.recordpermission.RecordPermissionService;
import com.zt.plat.module.qms.resource.record.service.recordrecord.RecordRecordService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.*;
import static com.zt.plat.module.qms.enums.QmsBpmConstant.BPM_CALLBACK_BEAN_NAME;

/**
 * 文件记录通用申请 Service 实现类
 *
 * @author 后台管理
 */
@Service("recordApplyService")
@Validated
@Slf4j
public class RecordApplyServiceImpl implements RecordApplyService, BMPCallbackInterface {

    @Resource
    private RecordApplyMapper recordApplyMapper;
    @Resource
    private RecordApplyDetailService recordApplyDetailService;
    @Resource
    private BpmProcessInstanceApi bpmProcessInstanceApi;
    @Resource
    private DataKeyCheckService dataKeyCheckService;
    @Resource
    private DataOpinionService dataOpinionService;

    @Resource
    private RecordRecordService recordRecordService;

    @Resource
    private RecordPermissionService recordPermissionService;

    @Resource
    private BusinessFileService businessFileService;

    @Override
    public RecordApplyRespVO createRecordApply(RecordApplySaveReqVO createReqVO) {
        // 插入
        RecordApplyDO recordApply = BeanUtils.toBean(createReqVO, RecordApplyDO.class);
        recordApplyMapper.insert(recordApply);
        // 返回
        return BeanUtils.toBean(recordApply, RecordApplyRespVO.class);
    }

    public CommonResult<RecordApplyRespVO> updateDistributionDetail(RecordApplySaveReqVO updateReqVO, RecordApplyDO recordApplyDO) {
        Long applyId = updateReqVO.getId();
        List<RecordApplyDetailSaveReqVO> detailList = updateReqVO.getDetailList();
        List<RecordApplyDetailDO> recordApplyDetailDOS = recordApplyDetailService.selectAllList(applyId);
        if (!ObjectUtils.isEmpty(recordApplyDetailDOS)) {
            // 删除所有详情
//            recordApplyDetailService.deleteRecordApplyDetailByApplyId(applyId);
            // 删除不需要的明细数据--->通过 申请Id 和 记录 id
            List<Long> recordList = updateReqVO.getRecordList();
            List<Long> detailIds = detailList.stream().map(RecordApplyDetailSaveReqVO::getId).toList();
            recordApplyDetailService.deleteNotInDetailIdList(applyId, null, recordList); //先删除记录
            recordApplyDetailService.deleteNotInDetailIdList(applyId, detailIds, null); // 在删除不需要的明细数据
            CommonResult<RecordApplyRespVO> applyDetailData = createApplyDetailData(updateReqVO, recordApplyDO);
//            Long documentId = recordApplyDetailDOS.get(0).getDocumentId();
            // 判断文件是否改变
//            Long newDocumentId = detailList.get(0).getDocumentId();
//            if (!documentId.equals(newDocumentId)) { // 删除重新添加
//                List<Long> deleteFileIdList = recordApplyDetailDOS.stream().map(RecordApplyDetailDO::getId).toList();
//                recordApplyDetailService.deleteRecordApplyDetailListByIds(deleteFileIdList);
//                return true;
//            }
            return applyDetailData;
        }
        return new CommonResult<RecordApplyRespVO>();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RecordApplyRespVO updateRecordApply(RecordApplySaveReqVO updateReqVO) {
        // 校验存在
//        validateRecordApplyExists(updateReqVO.getId());
        Long applyId = updateReqVO.getId();
        RecordApplyDO recordApplyDO = recordApplyMapper.selectById(applyId);
        if (ObjectUtils.isEmpty(recordApplyDO)) CommonResult.error(RECORD_APPLY_NOT_EXISTS);
        // 分发单独处理
        RecordApplyDO updateObj = BeanUtils.toBean(updateReqVO, RecordApplyDO.class);
        List<RecordApplyDetailDO> detailList = updateObj.getDetailList();
        // 查询所有明细
        recordApplyMapper.updateById(updateObj);
        String businessType = recordApplyDO.getBusinessType();
        if (RecordConstants.BusinessType.DISTRIBUTION.equals(businessType)) { // 分发单独处理
            CommonResult<RecordApplyRespVO> recordApplyRespVOCommonResult = updateDistributionDetail(updateReqVO, recordApplyDO);
            return recordApplyRespVOCommonResult.getData();
        } else if (RecordConstants.BusinessType.CHANGE_NOTICE.equals(businessType)) { // 修改通知 单独处理
            return updateChangNoticeDetail(updateReqVO, recordApplyDO);
//            recordApplyDetailService.deleteRecordApplyDetailByApplyId(applyId);
        }
        // 判断更新中的明细是否存在
        //判断  detailList 中的数据 和 数据库中 recordApplyDetail 的数据是否一致,如果有相同的，数据保持不变，有新的，则插入；
        // detailList 中没有的数据，则删除 recordApplyDetail 表中的数据
        List<Long> detailIds = new ArrayList<>();
        List<RecordApplyDetailDO> newDetailList = new ArrayList<>();
        detailList.forEach(item -> {
            if (item.getId() != null) detailIds.add(item.getId()); // 有id的
            else {
                item.setApplyId(applyId);
                newDetailList.add(item); // 新数据
            }
        });
        recordApplyDetailService.deleteNotInDetailIdList(applyId, null, detailIds);
//        if (!ObjectUtils.isEmpty(deleteDetailAllList)) {
//            List<Long> deleteDetailIds = deleteDetailAllList.stream().map(RecordApplyDetailDO::getId).toList();
//            recordApplyDetailService.deleteRecordApplyDetailListByIds(deleteDetailIds);
//        }
        // 更新
        if (!ObjectUtils.isEmpty(newDetailList)) {
            recordApplyDetailService.createRecordApplyDetailBatch(newDetailList);
        }

        updateReqVO.setBusinessType(businessType);

        businessFileService.deleteBusinessFileList(updateReqVO.getDeleteFileIdList());

        return BeanUtils.toBean(updateReqVO, RecordApplyRespVO.class);

    }

    // TODO
    private RecordApplyRespVO updateChangNoticeDetail(RecordApplySaveReqVO updateReqVO, RecordApplyDO recordApplyDO) {
        List<UploadFileVo> files = updateReqVO.getFiles();
        if (ObjectUtils.isEmpty(files)) throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(),"请上传修改通知单文件");
        UploadFileVo fileVo = files.get(0);
        String fileId = fileVo.getId();
        Long applyId = recordApplyDO.getId();
        RecordApplyDetailPageReqVO pageReqVO = new RecordApplyDetailPageReqVO();
        pageReqVO.setApplyId(applyId);
        pageReqVO.setTargetId(Long.valueOf(fileId)); // 文件id
        pageReqVO.setPageSize(-1);
        List<RecordApplyDetailDO> recordApplyDetailDOS = recordApplyDetailService.selectList(pageReqVO);
        if (ObjectUtils.isEmpty(recordApplyDetailDOS)) {
            CommonResult<RecordApplyRespVO> applyDetailData = createApplyDetailData(updateReqVO, recordApplyDO);
            return applyDetailData.getData();
        }
        // 删除ID 不存在的数据
        List<RecordApplyDetailSaveReqVO> detailList = updateReqVO.getDetailList();
        List<Long> list = detailList.stream().map(RecordApplyDetailSaveReqVO::getId).toList();
        recordApplyDetailService.deleteNotInDetailIdList(applyId, list, null);

        createApplyDetailData(updateReqVO,recordApplyDO);
        return BeanUtils.toBean(updateReqVO, RecordApplyRespVO.class);
    }

    @Override
    public void deleteRecordApply(Long id) {
        // 校验存在
        validateRecordApplyExists(id);
        // 删除
        recordApplyMapper.deleteById(id);
    }

    @Override
    public void deleteRecordApplyListByIds(List<Long> ids) {
        // 校验存在
        validateRecordApplyExists(ids);
        // 删除
        recordApplyMapper.deleteByIds(ids);
    }

    private void validateRecordApplyExists(List<Long> ids) {
        List<RecordApplyDO> list = recordApplyMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(RECORD_APPLY_NOT_EXISTS);
        }
    }

    private void validateRecordApplyExists(Long id) {
        if (recordApplyMapper.selectById(id) == null) {
            throw exception(RECORD_APPLY_NOT_EXISTS);
        }
    }

    @Override
    public RecordApplyDO getRecordApply(Long id) {
        RecordApplyDO recordApplyDO = recordApplyMapper.selectById(id);
        if (ObjectUtils.isEmpty(recordApplyDO)) return recordApplyDO;
        List<RecordApplyDetailDO> recordApplyDetailDOS;
        recordApplyDetailDOS = recordApplyDetailService.selectAllList(id);
        String businessType = recordApplyDO.getBusinessType();
        if (RecordConstants.BusinessType.DISTRIBUTION.equals(businessType)) { //处理分发数据
            // 明细中如果有相同名称和ID 的数据，只需要一条,默认保存第一条，通过 targetType 和 targetId 判断
            Map<String, RecordApplyDetailDO> distributionDetailData = getDistributionDetailData(recordApplyDetailDOS);
            recordApplyDetailDOS = new ArrayList<>(distributionDetailData.values());
        }
        recordApplyDO.setDetailList(recordApplyDetailDOS);
        return recordApplyDO;
    }

    // 获取分发明细数据，处理重复数据
    public Map<String, RecordApplyDetailDO> getDistributionDetailData(List<RecordApplyDetailDO> recordApplyDetailDOS) {
        Map<String, RecordApplyDetailDO> uniqueMap = new LinkedHashMap<>();
        for (RecordApplyDetailDO detail : recordApplyDetailDOS) {
            String key = detail.getTargetType() + "_" + detail.getTargetId();
            RecordApplyDetailDO existing = uniqueMap.get(key);

            if (existing == null) {
                // 第一次遇到这个 key，直接放入
                uniqueMap.put(key, detail);
            } else {
                // 已存在相同的 key，判断是否需要替换
                boolean currentIsSaveFlag1 = !ObjectUtils.isEmpty(detail.getSaveFlag()) && detail.getSaveFlag().equals("1");
                boolean existingIsSaveFlag1 = !ObjectUtils.isEmpty(existing.getSaveFlag()) && existing.getSaveFlag().equals("1");

                // 如果当前数据是 saveFlag='1' 且已存在的不是，则替换
                if (currentIsSaveFlag1 && !existingIsSaveFlag1) {
                    uniqueMap.put(key, detail);
                }
                // 其他情况保持原有数据不变
            }
        }
        return uniqueMap;
    }

    @Override
    public PageResult<RecordApplyDO> getRecordApplyPage(RecordApplyPageReqVO pageReqVO) {
        pageReqVO.setApplyUserId(SecurityFrameworkUtils.getLoginUserId());
        return recordApplyMapper.selectPage(pageReqVO);
    }

    // 创建申请数据
    public RecordApplyDO createApply(RecordApplySaveReqVO param) {
        RecordApplyDO recordApply = BeanUtils.toBean(param, RecordApplyDO.class);
        recordApply.setBusinessStatus(QmsCommonConstant.NOT_START); // 待提交
        recordApply.setApplyStartDate(LocalDateTime.now()); // 申请开始时间
        String businessType = param.getBusinessType();
        //取当前用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String nickName = SecurityFrameworkUtils.getLoginUserNickname();
        recordApply.setApplyUserId(loginUser.getId());
        recordApply.setApplyUserName(nickName);
        Long visitDeptId = loginUser.getVisitDeptId();
        // 获取当前用户所在的部门
        if (ObjectUtils.isEmpty(visitDeptId))
            throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "获取当前部门信息失败");
        recordApply.setApplyDepartmentId(visitDeptId);
        recordApply.setApplyDepartmentName(loginUser.getVisitDeptName());

        //生成标题
        String title = nickName + "的" + businessType + "_" + new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
        recordApply.setTitle(title);
        try {
            recordApplyMapper.insert(recordApply);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return recordApply;
    }

    //创建申请数据
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<RecordApplyRespVO> createApplyData(RecordApplySaveReqVO param) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (ObjectUtils.isEmpty(loginUser)) throw exception0(CURRENT_USER_NOT_EXISTS.getCode(), "用户不存在");

        List<RecordApplyDetailSaveReqVO> detailList = param.getDetailList();
        if (ObjectUtils.isEmpty(detailList))
            throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "没有找到文件记录数据");

        RecordApplyDO recordApply = createApply(param);

        return createApplyDetailData(param, recordApply);
    }

    public CommonResult<RecordApplyRespVO> createApplyDetailData(RecordApplySaveReqVO param, RecordApplyDO recordApply) {
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        String businessType = param.getBusinessType();
        List<RecordApplyDetailSaveReqVO> detailList = param.getDetailList();
        if (ObjectUtils.isEmpty(businessType))
            throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "请选择业务类型");
        switch (businessType) {
            case RecordConstants.BusinessType.REVIEW: // 评审
                detailSaveReqVOList = addReviewDetail(detailList, recordApply);
                break;
            case RecordConstants.BusinessType.DISTRIBUTION: // 分发
                List<Long> recordList = param.getRecordList();
                detailSaveReqVOList = addDistributionDetail(detailList, recordList, recordApply);
                break;
            case RecordConstants.BusinessType.RECORD_UPDATE: // 更改申请
                detailSaveReqVOList = addUpdateDetail(detailList, recordApply);
                break;
            case RecordConstants.BusinessType.INVALID: // 作废
                detailSaveReqVOList = addInvalidDetail(detailList, recordApply);
                break;
            case RecordConstants.BusinessType.VIEW_APPLY: // 查看
                detailSaveReqVOList = addViewApplyDetail(detailList, recordApply);
                break;
            case RecordConstants.BusinessType.RECORD_SUBMIT: // 提交
                Long recordId = param.getDetailList().get(0).getDocumentId(); // 记录Id
                Long applyId = recordApply.getId(); // 申请Id
                detailSaveReqVOList = addRecordSubmitDetail(recordId, applyId);
                break;
            case RecordConstants.BusinessType.CHANGE_NOTICE: // 更改通知单
                List<UploadFileVo> files = param.getFiles();
                if (ObjectUtils.isEmpty(files))
                    throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "文件通知单数据不能为空");
                detailSaveReqVOList = addChangeNoticeDetail(detailList, files, recordApply);
                break;
        }

        if (!ObjectUtils.isEmpty(detailSaveReqVOList)) {
//            throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "没有找到文件记录数据");
            boolean recordApplyDetailBatch = recordApplyDetailService.createRecordApplyDetailBatch(detailSaveReqVOList);
            if (!recordApplyDetailBatch)
                throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "保存申请明细失败");
        }

        return CommonResult.success(BeanUtils.toBean(recordApply, RecordApplyRespVO.class));
    }

    private List<RecordApplyDetailDO> addChangeNoticeDetail(List<RecordApplyDetailSaveReqVO> detailReqList, List<UploadFileVo> files, RecordApplyDO applyDO) {
        Long applyId = applyDO.getId();
        List<RecordApplyDetailDO> detailDOList = BeanUtils.toBean(detailReqList, RecordApplyDetailDO.class);
        List<RecordApplyDetailDO> newDetailDOList = new ArrayList<>();
        for (RecordApplyDetailDO item : detailDOList){
            if (item.getId() != null) {
                item.clean();
                continue;
            }
            item.setApplyId(applyId);
            item.setTargetType(RecordConstants.TargetType.FILE); //  文件
            item.setApplyStartDate(LocalDateTime.now());
            files.forEach(it -> {
                item.setTargetId(Long.valueOf(it.getId())); // 文件Id
                item.setTargetName(it.getName()); // 文件名称
            });
            newDetailDOList.add(item);
        }
        return newDetailDOList;
    }

    // 保存评审明细
    public List<RecordApplyDetailDO> addReviewDetail(List<RecordApplyDetailSaveReqVO> detailList, RecordApplyDO recordApplyDO) {
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        for (RecordApplyDetailSaveReqVO item : detailList) {
            RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
            recordApplyDetailDO.setApplyId(recordApplyDO.getId());
            recordApplyDetailDO.setTargetId(SecurityFrameworkUtils.getLoginUserId());
            recordApplyDetailDO.setTargetType(RecordConstants.TargetType.USER);
            recordApplyDetailDO.setTargetName(SecurityFrameworkUtils.getLoginUserNickname());
            recordApplyDetailDO.setDocumentId(item.getDocumentId());
            recordApplyDetailDO.setIsModify(item.getIsModify());
            recordApplyDetailDO.setModifyCause(item.getModifyCause());
            recordApplyDetailDO.setFormData(item.getFormData());
            detailSaveReqVOList.add(recordApplyDetailDO);
        }
        return detailSaveReqVOList;
    }

    // 添加分发明细
    public List<RecordApplyDetailDO> addDistributionDetail(List<RecordApplyDetailSaveReqVO> detailList, List<Long> recordList, RecordApplyDO recordApplyDO) {
        if (ObjectUtils.isEmpty(detailList))
            throw exception0(RECORD_APPLY_DETAIL_NOT_EXISTS.getCode(), "申请明细不存在");
        if (ObjectUtils.isEmpty(recordList))
            throw exception0(RECORD_APPLY_DETAIL_NOT_EXISTS.getCode(), "分发文件不存在");

        List<RecordApplyDetailSaveReqVO> detailSaveReqVOList = new ArrayList<>();
        List<RecordApplyDetailSaveReqVO> detailUpdateReqVOList = new ArrayList<>();
        for (RecordApplyDetailSaveReqVO item : detailList) {
            for (Long recordId : recordList) {
                if (item.getId() != null && Objects.equals(item.getDocumentId(), recordId)) {
                    detailUpdateReqVOList.add(item);
                    continue;
                }
                // 创建新对象，避免引用问题
                RecordApplyDetailSaveReqVO newItem = new RecordApplyDetailSaveReqVO();
                BeanUtils.copyProperties(item, newItem);
                newItem.setId(null); // 更新使用
                newItem.setDocumentId(recordId);
                newItem.setApplyId(recordApplyDO.getId());
                newItem.setApplyStartDate(LocalDateTime.now());
                detailSaveReqVOList.add(newItem);
            }
        }
        // 更新明细
        if (!ObjectUtils.isEmpty(detailUpdateReqVOList)) {
            recordApplyDetailService.updateRecordApplyDetailBatch(detailUpdateReqVOList);
        }
        List<RecordApplyDetailDO> bean = BeanUtils.toBean(detailSaveReqVOList, RecordApplyDetailDO.class);
        return bean;
    }

    // 添加更改申请明细
    public List<RecordApplyDetailDO> addUpdateDetail(List<RecordApplyDetailSaveReqVO> detailList, RecordApplyDO recordApplyDO) {
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        List<RecordApplyDetailDO> detailDOList = BeanUtils.toBean(detailList, RecordApplyDetailDO.class);
        for (RecordApplyDetailDO item : detailDOList) {
            item.setApplyId(recordApplyDO.getId());
            item.setTargetId(SecurityFrameworkUtils.getLoginUserId());
            item.setTargetType(RecordConstants.TargetType.USER);
            item.setTargetName(SecurityFrameworkUtils.getLoginUserNickname());
            detailSaveReqVOList.add(item);
        }
        return detailSaveReqVOList;
    }

    // 添加作废明细
    public List<RecordApplyDetailDO> addInvalidDetail(List<RecordApplyDetailSaveReqVO> detailList, RecordApplyDO recordApplyDO) {
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        for (RecordApplyDetailSaveReqVO item : detailList) {
            RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
            recordApplyDetailDO.setApplyId(recordApplyDO.getId());
            recordApplyDetailDO.setDocumentId(item.getDocumentId());
            recordApplyDetailDO.setIsModify(item.getIsModify());
            recordApplyDetailDO.setModifyCause(item.getModifyCause());
            recordApplyDetailDO.setFormData(item.getFormData());
            recordApplyDetailDO.setTargetId(SecurityFrameworkUtils.getLoginUserId());
            recordApplyDetailDO.setTargetType(RecordConstants.TargetType.USER);
            recordApplyDetailDO.setTargetName(SecurityFrameworkUtils.getLoginUserNickname());
            detailSaveReqVOList.add(recordApplyDetailDO);
        }
        return detailSaveReqVOList;
    }

    // 添加查看申请
    public List<RecordApplyDetailDO> addViewApplyDetail(List<RecordApplyDetailSaveReqVO> detailList, RecordApplyDO recordApplyDO) {
        Long userId = SecurityFrameworkUtils.getLoginUser().getId();
        String loginUserNickname = SecurityFrameworkUtils.getLoginUserNickname();
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        for (RecordApplyDetailSaveReqVO item : detailList) {
            RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
            recordApplyDetailDO.setApplyId(recordApplyDO.getId());
            recordApplyDetailDO.setDocumentId(item.getDocumentId());
            recordApplyDetailDO.setTargetId(userId);
            recordApplyDetailDO.setTargetName(loginUserNickname);
            recordApplyDetailDO.setTargetType(RecordConstants.TargetType.USER); // 用户
            recordApplyDetailDO.setSaveFlag(item.getSaveFlag());
            recordApplyDetailDO.setEndDate(item.getEndDate());
            recordApplyDetailDO.setFormData(item.getFormData());
            detailSaveReqVOList.add(recordApplyDetailDO);
        }
        return detailSaveReqVOList;
    }

    // 添加文件提交明细
    public List<RecordApplyDetailDO> addRecordSubmitDetail(Long recordId, Long applyId) {
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
        recordApplyDetailDO.setApplyId(applyId);
        recordApplyDetailDO.setDocumentId(recordId); // 文件Id
        recordApplyDetailDO.setTargetType(RecordConstants.TargetType.USER);
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        recordApplyDetailDO.setTargetId(loginUser.getId());
        String loginUserNickname = SecurityFrameworkUtils.getLoginUserNickname();
        recordApplyDetailDO.setTargetName(loginUserNickname);
        detailSaveReqVOList.add(recordApplyDetailDO);
        return detailSaveReqVOList;
    }


    // 判断文件提交是否需要走流程
    public boolean justifyRecordApply(RecordRecordDO recordDO) {
        Integer recordStatus = recordDO.getRecordStatus();
        if (recordStatus != null && recordStatus == 1)
            throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "文件已提交，无法提交申请");
//        RecordCategoryDO recordCategory = recordCategoryService.getRecordCategory(recordDO.getCategoryId());
        // 获取分类的根分类Id
//        String idPath = recordCategory.getIdPath();
//        Optional<String> segment = RecordCommonUtils.getSegment(idPath, 1);
//        String s = segment.orElse(null);
//        if (ObjectUtils.isEmpty(s))
//            throw exception(RECORD_APPLY_NOT_EXISTS);
//        RecordCategoryDO category = recordCategoryService.getRecordCategory(Long.valueOf(s));
//        String customConfig = category.getCustomConfig();
//        if (ObjectUtils.isEmpty(customConfig)) { // 空，直接判断是否到生效日期
//            // 判断是否到生效日期
//            RecordRecordDO effectiveRecordRecordDO = isEffective(recordDO);
//            recordRecordService.updateRecordRecordById(effectiveRecordRecordDO);
//            return true;
//        }
//        JSONObject jsonObject = JSONObject.parseObject(customConfig);
//        Integer submitFlag = jsonObject.getInteger("submitFlag");
//        if (submitFlag == 0) {
        // 不允许提交，直接修改文件记录状态
        RecordRecordDO effectiveRecordRecordDO = isEffective(recordDO);
        recordRecordService.updateRecordRecordById(effectiveRecordRecordDO);
        return true;
//        } else { // 需要走流程
//            recordDO.setSubmitFlag(1);
//            recordDO.setRecordStatus(0);
//            recordRecordService.updateRecordRecordById(recordDO);
//        }

//        return false;
    }

    // 判断文件记录生效状态
    public RecordRecordDO isEffective(RecordRecordDO recordDO) {
        LocalDateTime effectiveDate = recordDO.getEffectiveDate(); // 生效日期
        LocalDateTime expirationDate = recordDO.getExpirationDate(); // 过期日期
        LocalDateTime now = LocalDateTime.now();

        if (effectiveDate == null) { // 没有生效日期，立即生效
            recordDO.setRecordStatus(1);
        } else {
            recordDO.setRecordStatus(0); // 待生效
            if (now.isAfter(effectiveDate) || now.isEqual(effectiveDate)) {
                recordDO.setRecordStatus(1); // 已生效
                // 已到生效日期，检查是否过期
                if (expirationDate != null && (now.isAfter(expirationDate))) {
                    recordDO.setRecordStatus(0); // 过期, 未生效
                    recordDO.setExpirationStatus(1);
                }
            }
        }
        return recordDO;
    }

    //    修改评审状态
    public void updateReviewFlag(Long applyId) {
        List<RecordApplyDetailDO> recordApplyDetailDOS = recordApplyDetailService.selectAllList(applyId);
        // 修改recordRecord的submitFlag 字段状态为0，评审中
        List<RecordRecordDO> recordRecordDOS = new ArrayList<>();
        for (RecordApplyDetailDO it : recordApplyDetailDOS) {
            RecordRecordDO recordRecordDO = new RecordRecordDO();
            recordRecordDO.setSubmitFlag(0); // 评审中
            recordRecordDO.setId(it.getDocumentId());
            recordRecordDOS.add(recordRecordDO);
        }
        recordRecordService.updateRecordRecordListByIds(recordRecordDOS);
    }

    //提交申请-发起流程
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<RecordApplyRespVO> submitRecordApply(RecordApplySaveReqVO param) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (ObjectUtils.isEmpty(loginUser)) throw exception0(RECORD_RECORD_NOT_EXISTS.getCode(), "请重新登录");
        String nickName = SecurityFrameworkUtils.getLoginUserNickname();
        Long applyId = param.getId(); // 申请Id
        String paramBusinessType = param.getBusinessType();
        if (!ObjectUtils.isEmpty(paramBusinessType) && paramBusinessType.equals(RecordConstants.BusinessType.RECORD_SUBMIT)) {
            // 创建申请记录
            CommonResult<RecordApplyRespVO> applyData = createApplyData(param);
            applyId = applyData.getData().getId();

        }
        if (ObjectUtils.isEmpty(applyId)) throw exception0(RECORD_RECORD_NOT_EXISTS.getCode(), "申请记录不存在");
        RecordApplyDO recordApplyDO = recordApplyMapper.selectById(applyId);

        // TODO // 提交,不需要走流程
        Integer isSubmit = param.getIsSubmit();
        if (!ObjectUtils.isEmpty(isSubmit) && isSubmit == 1) {
            RecordApplyDO applyDO = applySubmitStatus(recordApplyDO);
            return CommonResult.success(BeanUtils.toBean(applyDO, RecordApplyRespVO.class));
        }
        // TODO =============== 流程
        JSONObject formData = new JSONObject();

        BpmProcessInstanceCreateReqDTO reqDTO = new BpmProcessInstanceCreateReqDTO();

        RecordRecordDO recordRecordDO = new RecordRecordDO();

        reqDTO.setBusinessKey(String.valueOf(applyId));
        String businessType = recordApplyDO.getBusinessType();
        switch (businessType) {
            case RecordConstants.BusinessType.RECORD_SUBMIT:
                // 判断根分类上是否配置自定义配置，允许提交，则需要走流程，否则直接提交
                List<RecordApplyDetailSaveReqVO> detailList = param.getDetailList();
                Long recordId = detailList.get(0).getDocumentId();
                recordRecordDO = recordRecordService.getRecordById(recordId);
                if (ObjectUtils.isEmpty(recordRecordDO))
                    throw exception0(RECORD_RECORD_NOT_EXISTS.getCode(), "文件记录实体不存在");
                boolean b = justifyRecordApply(recordRecordDO);
                if (b) {
                    // 不需要走流程，直接返回成功
                    return CommonResult.success(BeanUtils.toBean(recordRecordDO, RecordApplyRespVO.class));
                }
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.RECORD_SUBMIT_DEFINITION_KEY);
                break;
            case RecordConstants.BusinessType.DISTRIBUTION: // 分发
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.DISTRIBUTION_DEFINITION_KEY);
                // 文件分发需要关联权限表，
                break;
            case RecordConstants.BusinessType.VIEW_APPLY: // 查看申请
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.VIEW_APPLY_DEFINITION_KEY);
                break;
            case RecordConstants.BusinessType.INVALID: // 作废
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.INVALID_DEFINITION_KEY);
                break;
            case RecordConstants.BusinessType.REVIEW: // 评审
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.REVIEW_DEFINITION_KEY);
                // 修改评审状态（null,0,1）
                updateReviewFlag(applyId);
                break;
            case RecordConstants.BusinessType.RECORD_UPDATE: // 文件修改申请
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.RECORD_UPDATE_DEFINITION_KEY);
                break;
            default:
                throw exception(RECORD_APPLY_NOT_EXISTS, "未知的业务类型");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        formData.put("mainId", recordApplyDO.getId());
        formData.put("applyUser", nickName);
        formData.put("applyUserId", loginUser.getId());
        formData.put("applyDepartment", loginUser.getVisitDeptName());
        formData.put("applyDepartmentId", loginUser.getVisitDeptId());
        formData.put("applyTime", sdf.format(new Date()));
        formData.put("businessType", businessType);
        formData.put("title", recordApplyDO.getTitle()); // 文件名

        Map<String, Object> variables = formData.toJavaObject(Map.class);
        variables.put(BPM_CALLBACK_BEAN_NAME, "recordApplyService");

        reqDTO.setVariables(variables);

        CommonResult<String> result = bpmProcessInstanceApi.createProcessInstance(loginUser.getId(), reqDTO);
        if (!result.isSuccess()) {
            throw exception0(ERROR_CODE_MODULE_COMMON, result.getMsg());
        }

        String wfInsId = result.getData();
        recordApplyDO.setFlowInstanceId(wfInsId);
        // 更新申请实例Id
        recordApplyDO.setBusinessStatus(QmsCommonConstant.IN_PROGRESS); //
        recordApplyMapper.updateById(recordApplyDO);

        // 提交申请-发起流程, 更新 实例Id到文件记录
        if (businessType.equals(RecordConstants.BusinessType.RECORD_SUBMIT)) {
            recordRecordDO.setFlowInstanceId(wfInsId);
            recordRecordDO.setApplyStatus(QmsCommonConstant.IN_PROGRESS);
            recordRecordService.updateRecordRecordById(recordRecordDO);
        }

        return CommonResult.success(BeanUtils.toBean(recordApplyDO, RecordApplyRespVO.class));
    }

    // 提交申请-不需要发起流程
    public RecordApplyDO applySubmitStatus(RecordApplyDO recordApplyDO) {
        String businessType = recordApplyDO.getBusinessType();
        Long id = recordApplyDO.getId();
        List<RecordApplyDetailDO> recordApplyDetailDOS = recordApplyDetailService.selectList(new RecordApplyDetailPageReqVO().setApplyId(id));
        processHandle(businessType, recordApplyDetailDOS);

        // 更新申请提交状态
        recordApplyDO.setIsSubmit(1);
        recordApplyDO.setBusinessStatus(QmsCommonConstant.SUBMITTED);
        recordApplyMapper.updateById(recordApplyDO);
        return recordApplyDO;
    }

    //流程回调
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<JSONObject> callback(QmsBpmDTO reqDTO) {
        log.error("文件下发流程回调：{}", JSONObject.toJSONString(reqDTO));
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (ObjectUtils.isEmpty(loginUser))
            throw exception0(CURRENT_USER_DEPT_NOT_EXISTS.getCode(), "当前用户不存在，请重新登录");
        JSONObject variables = reqDTO.getVariables();
        // TODO 目前审批意见在流程回调时保存，后续可以考虑在每个节点完成时保存审批意见，这样可以避免审批意见丢失的情况，同时也能更及时地记录审批意见
        JSONObject taskVariables = variables.getJSONObject("taskVariables");
        String processInsId = variables.getString(QmsBpmConstant.BPM_PROCESS_INS_ID);
        String currentActivityInsId = variables.getString(QmsBpmConstant.BPM_CUR_ACTIVITY_INS_ID);
        String currentActivityId = variables.getString(QmsBpmConstant.BPM_CALLBACK_ACTIVITY_ID);
        String currentActivityName = variables.getString(QmsBpmConstant.BPM_CALLBACK_ACTIVITY_NAME);
        String returnFlag = variables.getString(QmsBpmConstant.BPM_REJECT_TO_FIRST_FLAG);

        String businessType = variables.getString("businessType");
        String mainId = variables.getString("mainId"); // 申请ID

        RecordApplyDO recordApplyDO = recordApplyMapper.selectById(Long.valueOf(mainId)); // 申请记录
        if (recordApplyDO == null) throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "申请记录不存在");

        //同一个节点实例只触发一次
        String checkKey = currentActivityInsId;
        if (ObjectUtils.isEmpty(currentActivityInsId))
            checkKey = processInsId + "-create";
        if ("1".equals(returnFlag))
            checkKey += "-reject";
        try {
            dataKeyCheckService.create(checkKey, this.getClass().getName());
        } catch (Exception e) {
            log.error("checkKey 重复：key={}", checkKey);
            return CommonResult.success(new JSONObject());
        }

        //流程状态  1-提交（含退回）  4-取消流程
        String PROCESS_STATUS = variables.getString(QmsBpmConstant.PROCESS_INSTANCE_VARIABLE_STATUS);
        JSONArray fieldExtensions = new JSONArray();
        if (variables.containsKey(QmsBpmConstant.BPM_FIELD_EXTENSIONS)) {
            fieldExtensions = variables.getJSONArray(QmsBpmConstant.BPM_FIELD_EXTENSIONS);
        }

        //判断是否最后一个节点
        String lastActivityFlag = "0";
        String firstActivityFlag = "0";
        if (!fieldExtensions.isEmpty()) {
            for (int i = 0; i < fieldExtensions.size(); i++) {
                JSONObject extension = fieldExtensions.getJSONObject(i);
                String fieldName = extension.getString("fieldName");
                String stringValue = extension.getString("stringValue");
                if (ObjectUtils.isEmpty(stringValue))
                    stringValue = "";
                if (fieldName.equalsIgnoreCase(QmsBpmConstant.BPM_LAST_ACTIVITY_FLAG) && stringValue.equals("1")) {
                    lastActivityFlag = "1";
                }
                if (fieldName.equalsIgnoreCase(QmsBpmConstant.BPM_FIRST_ACTIVITY_FLAG) && stringValue.equals("1")) {
                    firstActivityFlag = "1";
                }
            }
        }

        List<RecordApplyDetailDO> recordApplyDetailDOS = recordApplyDetailService.selectList(new RecordApplyDetailPageReqVO().setApplyId(Long.valueOf(mainId)));
        if (ObjectUtils.isEmpty(recordApplyDetailDOS))
            throw exception0(RECORD_RECORD_NOT_EXISTS.getCode(), "未找到对应的申请明细记录");
        //"RETURN_FLAG_Activity_001": true 标识驳回到发起环节
        if (("1").equals(returnFlag)) {
            //驳回。流程需要配置退回到发起节点
            log.info("文件下发流程回调：驳回");
            recordApplyDO.setBusinessStatus(QmsCommonConstant.REJECTED);
        } else if ("3".equals(PROCESS_STATUS)) {
            //作废
            log.info("文件下发流程回调：作废");
            if ("1".equals(firstActivityFlag)) {
                recordApplyDO.setBusinessStatus(QmsCommonConstant.VOID);
            }
            recordApplyMapper.updateById(recordApplyDO);
            if (businessType.equals(RecordConstants.BusinessType.RECORD_SUBMIT)) { // 文件申请, 更新文件记录审批状态
                RecordRecordDO recordRecordDO = new RecordRecordDO();
                recordRecordDO.setId(recordApplyDetailDOS.get(0).getDocumentId());
                recordRecordDO.setApplyStatus(QmsCommonConstant.VOID);
                recordRecordService.updateRecordRecordById(recordRecordDO);
            }
        } else if ("1".equals(PROCESS_STATUS)) {
            //通过 保存审批意见
            DataCommonType dataCommonType = new DataCommonType();
            dataCommonType.setBusinessId(Long.valueOf(mainId));
            dataCommonType.setFlowInstanceId(recordApplyDO.getFlowInstanceId());
            dataOpinionService.saveOpinionByWfCallback(dataCommonType, currentActivityId, currentActivityName, taskVariables);
            // 最后一个节点
            if ("1".equals(lastActivityFlag)) {
                //通过
                String completed = processHandle(businessType, recordApplyDetailDOS);
                recordApplyDO.setBusinessStatus(completed);
            }
        }
        // 审批完成，修改申请通用记录状态为已完成
        recordApplyDO.setApplyEndDate(LocalDateTime.now());
        recordApplyMapper.updateById(recordApplyDO);

        JSONObject ret = new JSONObject();
        return CommonResult.success(ret);
    }

    public String processHandle(String businessType, List<RecordApplyDetailDO> recordApplyDetailDOS) {
        switch (businessType) {
            case RecordConstants.BusinessType.RECORD_SUBMIT:
                recordSubmitCallHandle(recordApplyDetailDOS);
                break;
            case RecordConstants.BusinessType.REVIEW: // 评审
//                reviewCallHandle(recordApplyDetailDOS); // 暂时不处理
                break;
            case RecordConstants.BusinessType.DISTRIBUTION: // 分发
                recordPermissionAdd(recordApplyDetailDOS, businessType);
                // 更改申请流程
                break;
            case RecordConstants.BusinessType.RECORD_UPDATE: // 修改申请
                break;
            case RecordConstants.BusinessType.VIEW_APPLY: // 查看申请
                recordPermissionAdd(recordApplyDetailDOS, businessType);
                break;
            case RecordConstants.BusinessType.INVALID: // 作废 -- > 回收权限
                recordInvalidFlowStatus(recordApplyDetailDOS);
                break;
            case RecordConstants.BusinessType.CHANGE_NOTICE: // 更改通知单
                // TODO
                break;
            default:
                throw exception(RECORD_APPLY_NOT_EXISTS, "未知的业务类型");
        }
        return QmsCommonConstant.COMPLETED;
    }

    public void recordSubmitCallHandle(List<RecordApplyDetailDO> recordApplyDetailDOS) {
        RecordApplyDetailDO recordApplyDetailDO = recordApplyDetailDOS.get(0);
        Long documentId = recordApplyDetailDO.getDocumentId();
        RecordRecordDO entity = recordRecordService.getRecordById(documentId);
        // 判断生效日期
        RecordRecordDO effectiveRecordRecordDO = isEffective(entity);
        effectiveRecordRecordDO.setApplyStatus(QmsCommonConstant.COMPLETED); // 审批完成
        // 修改状态
        effectiveRecordRecordDO.setSubmitFlag(1);
        recordApplyFlowStatus(effectiveRecordRecordDO);

        // 如果文件生效， 作废老版本文件
        Integer recordStatus = effectiveRecordRecordDO.getRecordStatus();
        if (recordStatus == 0) return;
        LambdaUpdateWrapper<RecordRecordDO> updateWrapper = new LambdaUpdateWrapper<RecordRecordDO>();
        updateWrapper.eq(RecordRecordDO::getMainId, entity.getMainId()); // 所有版本
        updateWrapper.eq(RecordRecordDO::getCurrentFlag, 0); // 旧版本
        updateWrapper.eq(RecordRecordDO::getCancelFlag, 0); //未作废的
        updateWrapper.set(RecordRecordDO::getCancelFlag, 1); // 作废
        updateWrapper.set(RecordRecordDO::getRecordStatus, 0); // 无效
        recordRecordService.updateRecord(updateWrapper);
    }

    // 评审通过，处理修改修改的文件，走更改申请流程
    public void reviewCallHandle(List<RecordApplyDetailDO> recordApplyDetailDOS) {
        List<RecordApplyDetailSaveReqVO> detailDOList = new ArrayList<>();

        for (RecordApplyDetailDO applyDetailDO : recordApplyDetailDOS) {
            if (applyDetailDO.getIsModify() != 1) continue; //是否修改，是：直接创建更改申请
            RecordApplyDetailSaveReqVO detailDO = new RecordApplyDetailSaveReqVO();
            Long documentId = applyDetailDO.getDocumentId();
            detailDO.setDocumentId(documentId);
            detailDO.setIsModify(1);
            detailDO.setTargetId(applyDetailDO.getTargetId());
            detailDO.setTargetType(applyDetailDO.getTargetType());
            detailDO.setTargetName(applyDetailDO.getTargetName());
            detailDO.setModifyCause(applyDetailDO.getModifyCause());
//            detailDO.setApplyStartDate(LocalDateTime.now());
            String formData = applyDetailDO.getFormData();
            JSONObject formDataJson = JSONObject.parseObject(formData);
            // 把documentId 存到 formDataJson 中key = id 的里面
            formDataJson.put("id", documentId.toString());
            detailDOList.add(detailDO);
            // 创建更改申请
            RecordApplySaveReqVO recordApplyRespVO = new RecordApplySaveReqVO();
            recordApplyRespVO.setBusinessType(RecordConstants.BusinessType.RECORD_UPDATE);
            recordApplyRespVO.setModifyFlag("1");
            recordApplyRespVO.setApplyContent(applyDetailDO.getModifyCause()); // 修改原因
            recordApplyRespVO.setFormData(formDataJson.toJSONString());
            recordApplyRespVO.setDetailList(detailDOList);
            recordApplyRespVO.setApplyStartDate(LocalDateTime.now());
            createApplyData(recordApplyRespVO);

        }
        // 文件评审通过了，如果需要修改文件，直接申请流程
//        if (!ObjectUtils.isEmpty(detailDOList)) {
//            RecordApplySaveReqVO recordApplyRespVO = new RecordApplySaveReqVO();
//            recordApplyRespVO.setBusinessType(RecordConstants.BusinessType.RECORD_UPDATE);
//            recordApplyRespVO.setDetailList(detailDOList);
//            createApplyData(recordApplyRespVO);
//        }
    }

    // 文件提交-更改状态
    public void recordApplyFlowStatus(RecordRecordDO recordDO) {
        // 修改文件状态为已生效
        recordRecordService.updateRecordRecordById(recordDO);
    }

    // 作废：文件批量跟新状态
    public void recordInvalidFlowStatus(List<RecordApplyDetailDO> recordApplyDetailDOS) {
        List<Long> recordIds = recordApplyDetailDOS.stream().map(RecordApplyDetailDO::getDocumentId).toList();
        // 修改文件状态为已生效
        LambdaUpdateWrapper<RecordRecordDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(RecordRecordDO::getId, recordIds);
        updateWrapper.set(RecordRecordDO::getCancelFlag, 1);
        updateWrapper.set(RecordRecordDO::getRecordStatus, 0);
        recordRecordService.updateRecord(updateWrapper);

        // 回收文件权限,如果需要保留的权限，则不回收
        LambdaUpdateWrapper<RecordPermissionDO> update = new LambdaUpdateWrapper<>();
        update.eq(RecordPermissionDO::getSourceType, RecordConstants.PermissionSourceType.RECORD);
        update.eq(RecordPermissionDO::getCancelFlag, "0"); // 未回收
        update.eq(RecordPermissionDO::getSaveFlag, "0"); // 未保留
        update.in(RecordPermissionDO::getSourceId, recordIds); // 记录id
        update.set(RecordPermissionDO::getCancelFlag, "1"); // 设置为已回收
        recordPermissionService.updatePermission(update);
    }

    /**
     * 将 Object 类型的时间戳转换为 LocalDateTime
     *
     * @param timestamp 时间戳对象（可能是 Long、Date 等类型）
     * @return LocalDateTime 对象
     */
    private static LocalDateTime convertToLocalDateTime(Object timestamp) {
        if (timestamp == null) {
            return null;
        }

        if (timestamp instanceof Date) {
            return ((Date) timestamp).toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
        } else if (timestamp instanceof Long) {
            return Instant.ofEpochMilli((Long) timestamp)
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
        } else if (timestamp instanceof LocalDateTime) {
            return (LocalDateTime) timestamp;
        }

        return null;
    }

    // 文件分发/申请-添加权限
    public void recordPermissionAdd(List<RecordApplyDetailDO> recordApplyDetailDOS, String businessType) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        List<RecordPermissionDO> permissionDOList = new ArrayList<>();
        for (RecordApplyDetailDO applyDetailDO : recordApplyDetailDOS) {
            // 添加记录
            RecordPermissionDO permissionDO = new RecordPermissionDO();
            String targetType = applyDetailDO.getTargetType();
            String saveFlag = applyDetailDO.getSaveFlag();

            if (ObjectUtils.isEmpty(saveFlag)) permissionDO.setSaveFlag("0"); // 默认不保留
            else permissionDO.setSaveFlag(saveFlag);
            if (businessType.equals(RecordConstants.BusinessType.VIEW_APPLY)) {
                targetType = RecordConstants.TargetType.USER;
                permissionDO.setSaveFlag("1"); // 文件查看使用
            }

            if (ObjectUtils.isEmpty(targetType))
                throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "分发对象类型不能为空");

//            String saveFlag = applyDetailDO.getSaveFlag(); // 文件查看使用
            LocalDateTime endDate = applyDetailDO.getEndDate();
//            if (!ObjectUtils.isEmpty(saveFlag)) {
//                permissionDO.setSaveFlag(saveFlag);
//            } else permissionDO.setSaveFlag("1"); // 默认保留
            permissionDO.setEffectiveDate(LocalDateTime.now());
            permissionDO.setApplyType(businessType);
            permissionDO.setExpirationDate(endDate); // 过期效期
            permissionDO.setPermission(RecordConstants.PermissionType.VIEW); // 可查看
            permissionDO.setSourceType(RecordConstants.PermissionSourceType.RECORD); // 记录权限
            permissionDO.setSourceId(applyDetailDO.getDocumentId()); // 文件Id
            permissionDO.setDeptId(loginUser.getVisitDeptId());
            permissionDO.setDeptName(loginUser.getVisitDeptName());
            permissionDO.setTargetId(String.valueOf(applyDetailDO.getTargetId())); // 用户Id
            permissionDO.setTargetType(targetType);
            permissionDO.setTargetName(applyDetailDO.getTargetName());

            permissionDOList.add(permissionDO);
        }

        // 处理权限
        handleRecordPermission(permissionDOList, businessType);
    }

    //处理权限
    private void handleRecordPermission(List<RecordPermissionDO> permissionDOList, String businessType) {
        // 判断是否重复
        LambdaQueryWrapper<RecordPermissionDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RecordPermissionDO::getApplyType, businessType);
        queryWrapper.eq(RecordPermissionDO::getSourceType, RecordConstants.PermissionSourceType.RECORD);
        queryWrapper.eq(RecordPermissionDO::getPermission, RecordConstants.PermissionType.VIEW);
        queryWrapper.eq(RecordPermissionDO::getCancelFlag, "0");
        queryWrapper.eq(RecordPermissionDO::getExpirationStatus, "0");

        List<Long> sourceIds = permissionDOList.stream().map(RecordPermissionDO::getSourceId).toList();
        List<String> targetIds = permissionDOList.stream().map(RecordPermissionDO::getTargetId).toList();
        queryWrapper.in(RecordPermissionDO::getSourceId, sourceIds);
        queryWrapper.in(RecordPermissionDO::getTargetId, targetIds);

        List<RecordPermissionDO> existingPermissions = recordPermissionService.selectList(queryWrapper);

        // 构建 Map 以提高查询效率：key = sourceId_targetId
        Map<String, RecordPermissionDO> existingMap = existingPermissions.stream()
                .collect(Collectors.toMap(
                        p -> p.getSourceId() + "_" + p.getTargetId(),
                        p -> p
                ));

        // 分离新增和更新的数据
        List<RecordPermissionDO> toInsert = new ArrayList<>();
        List<RecordPermissionDO> toUpdate = new ArrayList<>();

        for (RecordPermissionDO item : permissionDOList) {
            String key = item.getSourceId() + "_" + item.getTargetId();
            RecordPermissionDO existing = existingMap.get(key);

            if (existing != null) {
                // 已存在，更新过期日期
                item.setId(existing.getId());
                item.setExpirationDate(item.getExpirationDate()); // 保持新的过期日期
                toUpdate.add(item);
            } else {
                // 不存在，新增
                toInsert.add(item);
            }
        }

        // 分别处理新增和更新
        if (!toInsert.isEmpty()) {
            recordPermissionService.insertBatch(toInsert);
        }
        if (!toUpdate.isEmpty()) {
            recordPermissionService.updateBatch(toUpdate);
        }
    }
}