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

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.dal.dataobject.DataOpinionDO;
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.enums.QmsBpmConstant;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.qms.resource.record.common.RecordCommonUtils;
import com.zt.plat.module.qms.resource.record.constant.RecordConstants;
import com.zt.plat.module.qms.resource.record.controller.admin.recordapply.vo.RecordApplyDetailJoinPageVO;
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.RecordApplyDetailRespVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordrecord.vo.RecordRecordPageReqVO;
import com.zt.plat.module.qms.resource.record.dal.mapper.RecordApplyMapper;
import com.zt.plat.module.qms.resource.record.dal.mapper.RecordRecordMapper;
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.recordcategory.RecordCategoryDO;
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.service.recordapplydetail.RecordApplyDetailService;
import com.zt.plat.module.qms.resource.record.service.recordcategory.RecordCategoryService;
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.jetbrains.annotations.NotNull;
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.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

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 RecordCategoryService recordCategoryService;

    @Resource
    private RecordPermissionService recordPermissionService;

    @Resource
    private RecordRecordMapper recordRecordMapper;

    private LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();

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

    @Override
    public void updateRecordApply(RecordApplySaveReqVO updateReqVO) {
        // 校验存在
        validateRecordApplyExists(updateReqVO.getId());
        // 更新
        RecordApplyDO updateObj = BeanUtils.toBean(updateReqVO, RecordApplyDO.class);
        recordApplyMapper.updateById(updateObj);
    }

    @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 = recordApplyDetailService.selectAllList(id);
        if (!recordApplyDetailDOS.isEmpty()) recordApplyDO.setDataList(recordApplyDetailDOS);
        return recordApplyDO;
    }

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

    //创建临时数据
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<RecordApplyRespVO> createApplyData(RecordApplySaveReqVO param) {
        String businessType = param.getBusinessType();
        if (ObjectUtils.isEmpty(businessType))
            throw exception0(RECORD_APPLY_NOT_EXISTS.getCode(), "请选择业务类型");

        RecordApplyDO recordApply = BeanUtils.toBean(param, RecordApplyDO.class);
        recordApply.setBusinessStatus(QmsCommonConstant.NOT_START); // 未发起

        //取当前用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        String nickName = SecurityFrameworkUtils.getLoginUserNickname();
        recordApply.setApplyUserId(loginUser.getId());
        recordApply.setApplyUserName(nickName);
        recordApply.setApplyDepartmentId(loginUser.getVisitDeptId());
        recordApply.setApplyDepartmentName(loginUser.getVisitDeptName());

        //生成标题
        String title = nickName + "的"+ businessType +"_" + new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
        recordApply.setTitle(title);

        recordApplyMapper.insert(recordApply);
        addDetail(param,recordApply);

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

    //增加明细
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> addDetail(RecordApplySaveReqVO param,RecordApplyDO  recordApplyDO) {
        String businessType = param.getBusinessType();
        List<RecordApplyDetailRespVO> paramsList = param.getParamsList();
        //申请通用明细记录
        List<RecordApplyDetailDO> detailSaveReqVOList = new ArrayList<>();
        // 判断是否是评审，如果是评审，一批评审文件对应一个申请记录，对应多条申请明细记录
        if (RecordConstants.BusinessType.REVIEW.equals(businessType)
                || RecordConstants.BusinessType.RECORD_UPDATE.equals(businessType)
                || RecordConstants.BusinessType.VIEW_APPLY.equals(businessType)
                || RecordConstants.BusinessType.INVALID.equals(businessType)) { // 评审，或修改申请，或查看申请，或文件作废
            if (ObjectUtils.isEmpty(paramsList)) throw exception(RECORD_RECORD_NOT_EXISTS, "请选择至少一条文件记录");
            for (RecordApplyDetailRespVO item : paramsList) {
                RecordApplyDetailDO recordApplyDetailDO = getRecordApplyDetailDO(recordApplyDO, item, businessType);
                detailSaveReqVOList.add(recordApplyDetailDO);
            }
        } else if (RecordConstants.BusinessType.DISTRIBUTION.equals(businessType)) { // 分发
            Long recordId = param.getRecordId();
            Long[] userIds = param.getUserIds();
            Long[] deptIds = param.getDeptIds();
            if (!ObjectUtils.isEmpty(userIds)) { // 用户
                for (Long userId : userIds) {
                    RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
                    recordApplyDetailDO.setApplyId(recordApplyDO.getId());
                    recordApplyDetailDO.setDocumentId(recordId);
                    recordApplyDetailDO.setTargetId(userId);//用户Id
                    recordApplyDetailDO.setTargetType(RecordConstants.TargetType.USER);
                    recordApplyDetailDO.setApplyStartDate(LocalDateTime.now()); // TODO 申请开始时间
                    detailSaveReqVOList.add(recordApplyDetailDO);
                }
            } else {
                if (ObjectUtils.isEmpty(deptIds)) throw exception(RECORD_RECORD_NOT_EXISTS, "请选择分发对象");
                for (Long deptId : deptIds) {
                    RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
                    recordApplyDetailDO.setApplyId(recordApplyDO.getId());
                    recordApplyDetailDO.setDocumentId(recordId);
                    recordApplyDetailDO.setTargetId(deptId);//部门Id
                    recordApplyDetailDO.setTargetType(RecordConstants.TargetType.DEPT);
                    recordApplyDetailDO.setApplyStartDate(LocalDateTime.now()); // TODO 申请开始时间
                    detailSaveReqVOList.add(recordApplyDetailDO);
                }
            }
        }
        else { // 分发
            RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
            Long recordId = param.getRecordId();
            recordApplyDetailDO.setApplyId(recordApplyDO.getId());
            recordApplyDetailDO.setDocumentId(recordId); // 文件Id
            detailSaveReqVOList.add(recordApplyDetailDO);
        }
        boolean recordApplyDetailBatch = recordApplyDetailService.createRecordApplyDetailBatch(detailSaveReqVOList);
        if (!recordApplyDetailBatch)
            throw exception(RECORD_APPLY_NOT_EXISTS, "保存申请明细失败");

        return CommonResult.success(true);
    }

    @NotNull
    private RecordApplyDetailDO getRecordApplyDetailDO(RecordApplyDO recordApplyDO, RecordApplyDetailRespVO item, String businessType) {
        RecordApplyDetailDO recordApplyDetailDO = new RecordApplyDetailDO();
        recordApplyDetailDO.setApplyId(recordApplyDO.getId());
        recordApplyDetailDO.setDocumentId(item.getDocumentId()); // 文件Id
        if (RecordConstants.BusinessType.VIEW_APPLY.equals(businessType)){
            recordApplyDetailDO.setTargetType(RecordConstants.TargetType.USER);
            recordApplyDetailDO.setTargetId(loginUser.getId()); // 申请人，当前用户
        }
        if (RecordConstants.BusinessType.REVIEW.equals(businessType)){ // 评审 是否 修改文件
            recordApplyDetailDO.setIsModify(item.getIsModify());
            recordApplyDetailDO.setModifyCause(item.getModifyCause());
        }
        return recordApplyDetailDO;
    }

    @Override
    public CommonResult<Boolean> removeDetail(JSONObject param) {
        String detailIds = param.getString("detailIds");
        if (ObjectUtils.isEmpty(detailIds))
            return CommonResult.error(RECORD_APPLY_NOT_EXISTS.getCode(), "请选择需要删除的明细数据");
        List<Long> detailIdList = Arrays.stream(detailIds.split(",")).map(Long::valueOf).toList();
        recordApplyDetailService.deleteRecordApplyDetailListByIds(detailIdList);
        return CommonResult.success(true);
    }

    //保存
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> saveRecordApply(RecordApplySaveReqVO updateReqVO) {
        // 校验存在
        RecordApplyDO backData = getRecordApply(updateReqVO.getId());
        if (backData == null)
            throw exception(RECORD_APPLY_NOT_EXISTS);
        // 如果是临时数据，保存后状态变更为未发起
        if (QmsCommonConstant.TEMP_DATA_CODE.equals(backData.getBusinessStatus())) {
            updateReqVO.setBusinessStatus(QmsCommonConstant.NOT_START);
        }
        // 更新
        RecordApplyDO updateObj = BeanUtils.toBean(updateReqVO, RecordApplyDO.class);
        recordApplyMapper.updateById(updateObj);
        return CommonResult.success(true);
    }

    @Override
    public CommonResult<JSONObject> getWithOpinions(Long id) {
        RecordApplyDO entity = recordApplyMapper.selectById(id);
        if (entity == null)
            return CommonResult.error(RECORD_APPLY_NOT_EXISTS.getCode(), "申请不存在");

        List<DataOpinionDO> opinions = dataOpinionService.getListByBusId(entity.getId());
        JSONObject opinionJson = new JSONObject();
        for (DataOpinionDO opinion : opinions) {
            String nodeKey = opinion.getNodeKey();
            if (ObjectUtils.isEmpty(nodeKey))
                continue;
            JSONObject nodeJson = new JSONObject();
            LocalDateTime opinionTime = opinion.getOpinionTime();
            nodeJson.put("nodeName", opinion.getNodeName());
            nodeJson.put("nodeKey", opinion.getNodeKey());
            nodeJson.put("opinionContent", opinion.getOpinionContent());
            if (opinionTime != null)
                nodeJson.put("opinionTime", opinionTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            nodeJson.put("opinionUserName", opinion.getOpinionUserName());
            nodeJson.put("opinionUserId", opinion.getOpinionUserId());
            nodeJson.put("opinionDepartmentName", opinion.getOpinionDepartmentName());
            nodeJson.put("opinionDepartmentId", opinion.getOpinionDepartmentId());
            nodeJson.put("opinionSignatureId", opinion.getOpinionSignatureId());
            opinionJson.put(nodeKey, nodeJson);
        }

        JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(entity));
        json.put("opinions", opinionJson);
        return CommonResult.success(json);
    }

    // 判断文件提交是否需要走流程
    public boolean justifyRecordApply(RecordRecordDO recordDO) {
        Integer recordStatus = recordDO.getRecordStatus();
        if (recordStatus != null) throw exception(RECORD_APPLY_NOT_EXISTS, "文件已提交，无法提交申请");
        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)) {
            JSONObject jsonObject = JSONObject.parseObject(customConfig);
            Integer submitFlag = jsonObject.getInteger("submitFlag");
            if (submitFlag == 0) {
                // 不允许提交，直接修改文件记录状态
                recordDO.setRecordStatus(1); // 已生效
                recordRecordService.updateRecordRecordById(recordDO);
                return true;
            } else {
                // 把状态改为0
                recordDO.setRecordStatus(0); // 未生效
                recordRecordService.updateRecordRecordById(recordDO);
            }
        }
        return false;
    }

    public void updateReviewFlag(RecordApplySaveReqVO param) {
//        Long[] recordIdS = param.getRecordIdS();
        List<RecordApplyDetailRespVO> paramsList = param.getParamsList();
        // 修改recordRecord的submitFlag 字段状态为0，评审中
        List<RecordRecordDO> recordRecordDOS = new ArrayList<>();
        for (RecordApplyDetailRespVO it : paramsList) {
            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(1_032_350_401,"请重新登录");
        String nickName = SecurityFrameworkUtils.getLoginUserNickname();
        Long recordId = param.getRecordId();// 文件Id
        Long applyId = param.getId(); // 申请Id
        if (ObjectUtils.isEmpty(applyId)) throw exception0(1_032_350_401,"申请记录不存在");
        RecordApplyDO recordApplyDO = recordApplyMapper.selectById(applyId);

        JSONObject formData = new JSONObject();

        BpmProcessInstanceCreateReqDTO reqDTO = new BpmProcessInstanceCreateReqDTO();

        // 通用申请
//        RecordApplyDO recordApplyDO = new RecordApplyDO();
//        recordApplyDO.setApplyUserId(loginUser.getId());
//        recordApplyDO.setApplyUserName(SecurityFrameworkUtils.getLoginUserNickname());
//        recordApplyDO.setApplyDepartmentId(loginUser.getVisitDeptId());
//        recordApplyDO.setApplyDepartmentName(loginUser.getVisitDeptName());
//        recordApplyDO.setBusinessType(businessType); // 业务类型：记录提交
//        recordApplyDO.setTitle(businessType);
//        //        recordApplyDO.setTitle(entity.getName());
//        recordApplyMapper.insert(recordApplyDO);

        reqDTO.setBusinessKey(String.valueOf(applyId));
        String businessType = recordApplyDO.getBusinessType();
        switch (businessType) {
            case RecordConstants.BusinessType.RECORD_SUBMIT:
                // 判断根分类上是否配置自定义配置，允许提交，则需要走流程，否则直接提交
                if (ObjectUtils.isEmpty(recordId)) throw exception(RECORD_RECORD_NOT_EXISTS,"请选择文件记录");
                RecordRecordDO entity = recordRecordService.getRecordById(recordId);
                if (ObjectUtils.isEmpty(entity)) throw exception(RECORD_RECORD_NOT_EXISTS);
                boolean b = justifyRecordApply(entity);
                if (b) {
                    // 不需要走流程，直接返回成功
                    return CommonResult.success(BeanUtils.toBean(entity, RecordApplyRespVO.class));
                }
                reqDTO.setProcessDefinitionKey(RecordConstants.ProcessDefinitionKey.RECORD_SUBMIT_DEFINITION_KEY);
                break;
            case RecordConstants.BusinessType.DISTRIBUTION: // 分发
                if (ObjectUtils.isEmpty(recordId)) throw exception(RECORD_RECORD_NOT_EXISTS,"请选择文件记录");
                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(param);
                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", businessType); // 文件名

        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.RUNNING); //
        recordApplyMapper.updateById(recordApplyDO);

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

    //流程回调
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<JSONObject> callback(QmsBpmDTO reqDTO) {
        log.error("文件下发流程回调：{}", JSONObject.toJSONString(reqDTO));
        loginUser = SecurityFrameworkUtils.getLoginUser();
        if (ObjectUtils.isEmpty(loginUser)) throw exception0(1_032_350_401,"当前用户不存在，请重新登录");
        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 exception(RECORD_APPLY_NOT_EXISTS, "申请记录不存在");


        //同一个节点实例只触发一次
        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());
        }

        String PROCESS_STATUS = variables.getString(QmsBpmConstant.PROCESS_INSTANCE_VARIABLE_STATUS);

        String lastActivityFlag = variables.getString("lastActivityFlag");
        if ("1".equals(lastActivityFlag)) { // 执行到申请人节点，修改状态
            if (PROCESS_STATUS.equals("1") || PROCESS_STATUS.equals("2")) {
                recordApplyDO.setBusinessStatus(QmsCommonConstant.RUNNING);
                recordApplyMapper.updateById(recordApplyDO);
                JSONObject ret = new JSONObject();
                return CommonResult.success(ret);
            }
        }

        if (("1").equals(returnFlag)) {
            //驳回，状态变更为未发起 TODO
//            entity.setBusinessStatus(QmsCommonConstant.NOT_START);
//            dataOpinionService.disableOpinionsByBusId(entity.getId());
        } else if ("4".equals(PROCESS_STATUS)) {
            //作废 TODO
//            entity.setBusinessStatus(QmsCommonConstant.VOID);
        } else if ("1".equals(PROCESS_STATUS) || "2".equals(PROCESS_STATUS)) {
            //通过
            List<RecordApplyDetailDO> recordApplyDetailDOS = recordApplyDetailService.selectList(new RecordApplyDetailPageReqVO().setApplyId(Long.valueOf(mainId)));
            if (ObjectUtils.isEmpty(recordApplyDetailDOS)) throw exception(RECORD_RECORD_NOT_EXISTS,"未找到对应的申请明细记录");
            // TODO 业务代码，通过业务类型判断
            List<RecordRecordDO> recordRecordDOS = new ArrayList<>();
            switch (businessType) {
                case RecordConstants.BusinessType.RECORD_SUBMIT:
                    RecordApplyDetailDO recordApplyDetailDO = recordApplyDetailDOS.get(0);
                    Long documentId = recordApplyDetailDO.getDocumentId();
                    RecordRecordDO entity = recordRecordService.getRecordById(documentId);
                    entity.setRecordStatus(1);// 已生效
                    // 修改状态
                    recordApplyFlowStatus(entity);
                    break;
                case RecordConstants.BusinessType.REVIEW: // 评审
                    List<RecordApplyDetailRespVO> detailDOList = new ArrayList<>();
                    // 1条申请----> 多条明细记录 ----> 多条文件记录
                    for (RecordApplyDetailDO applyDetailDO : recordApplyDetailDOS) {
                        if (applyDetailDO.getIsModify() == 1){
                            RecordApplyDetailRespVO detailDO = new RecordApplyDetailRespVO();
                            detailDOList.add(detailDO);
                        }
                    }
                    // 文件评审通过了，如果需要修改文件，直接发起修改申请流程
                    RecordApplySaveReqVO recordApplyRespVO = new RecordApplySaveReqVO();
                    recordApplyRespVO.setBusinessType(RecordConstants.BusinessType.RECORD_UPDATE);
                    recordApplyRespVO.setParamsList(detailDOList);
                    submitRecordApply(recordApplyRespVO);
                    break;
                case RecordConstants.BusinessType.DISTRIBUTION: // 分发
                    recordPermissionAdd(recordApplyDetailDOS);
                    // 更改申请流程
                    break;
                case RecordConstants.BusinessType.RECORD_UPDATE: // 修改申请
                    break;
                case RecordConstants.BusinessType.VIEW_APPLY: // 查看申请
                    recordPermissionAdd(recordApplyDetailDOS);
                    break;
                case RecordConstants.BusinessType.INVALID: // 作废
                    // 修改文件作废状态
                    for (RecordApplyDetailDO applyDetailDO : recordApplyDetailDOS) {
                        RecordRecordDO recordRecordDO = new RecordRecordDO();
                        recordRecordDO.setId(applyDetailDO.getDocumentId());
                        recordRecordDO.setCancelFlag(1); // 评审通过
                        recordRecordDOS.add(recordRecordDO);
                    }
                    recordReviewFlowStatus(recordRecordDOS);
                    break;
                default:
                    throw exception(RECORD_APPLY_NOT_EXISTS, "未知的业务类型");
            }

            DataCommonType dataCommonType = new DataCommonType();
            dataCommonType.setBusinessId(Long.valueOf(mainId));
            dataCommonType.setFlowInstanceId(recordApplyDO.getFlowInstanceId());
            dataOpinionService.saveOpinionByWfCallback(dataCommonType, currentActivityId, currentActivityName, taskVariables);

            // 审批完成，修改申请通用记录状态为已完成
            recordApplyDO.setBusinessStatus(QmsCommonConstant.COMPLETED);
            recordApplyMapper.updateById(recordApplyDO);

        }

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

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

    // 文件批量跟新状态
    public void recordReviewFlowStatus(List<RecordRecordDO> recordDO) {
        // 修改文件状态为已生效
        recordRecordService.updateRecordRecordListByIds(recordDO);
    }    
    
    // 文件分发/申请-添加权限
    public void recordPermissionAdd(List<RecordApplyDetailDO> recordApplyDetailDOS) {
        for (RecordApplyDetailDO applyDetailDO : recordApplyDetailDOS) {
            // 添加记录
            String targetType = applyDetailDO.getTargetType();
            if (ObjectUtils.isEmpty(targetType))
                throw exception(RECORD_APPLY_NOT_EXISTS, "分发对象类型不能为空");
            // 通过-----> 创建人员权限表记录
            RecordPermissionDO permissionDO = new RecordPermissionDO();
            permissionDO.setPermission(RecordConstants.PermissionType.VIEW); // 可查看
            permissionDO.setSourceId(applyDetailDO.getDocumentId()); // 文件Id
            permissionDO.setDeptId(loginUser.getVisitDeptId());
            permissionDO.setDeptName(loginUser.getVisitDeptName());
            List<RecordPermissionDO> permissionDOList = new ArrayList<>();
            if (targetType.equals(RecordConstants.TargetType.USER)) {
                permissionDO.setTargetId(String.valueOf(applyDetailDO.getTargetId())); // 用户Id
                permissionDO.setTargetType(RecordConstants.TargetType.USER);
            } else { // 部门
                permissionDO.setTargetId(String.valueOf(applyDetailDO.getTargetId())); // 部门Id
                permissionDO.setTargetType(RecordConstants.TargetType.DEPT);
            }
            permissionDOList.add(permissionDO);
            boolean b = recordPermissionService.insertRecordPermissionBatch(permissionDOList);
            if (!b) throw exception(RECORD_APPLY_NOT_EXISTS, "保存分发权限失败");
        }
    }


    /**
     *  文件评审分页查询，我需要查询出 recordApply 和 recordApplyDetail 和recordRecord 关联的数据，其中：
     * recordApply 对 recordApplyDetail 一对多的关系
     * recordApplyDetail 对 和recordRecord 一对一的关系
     * 查询条件：recordApply 的 businessType = '文件评审'
     * */ 
    @Override
    public PageResult<RecordApplyDetailJoinPageVO> recordReviewPage(RecordRecordPageReqVO pageReqVO) {
        // 使用多表连接查询获取文件评审数据
        int pageNo = pageReqVO.getPageNo();
        int pageSize = pageReqVO.getPageSize();
        int offset = (pageNo - 1) * pageSize;
        
        // 查询分页数据
        List<RecordApplyDetailJoinPageVO> list = recordRecordMapper.selectRecordReviewPage(RecordConstants.BusinessType.REVIEW, offset, pageSize);
        
        // 查询总数
        Long total = recordRecordMapper.selectRecordReviewCount(RecordConstants.BusinessType.REVIEW);
        
        return new PageResult<>(list, total);
    }

    @Override
    public PageResult<RecordApplyDO> recordDistributePage(RecordApplyPageReqVO pageReqVO) {
       return recordApplyMapper.selectPage(pageReqVO);
    }
}