package com.hzyj.sc.service.impl;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzyj.sc.dto.ExamineDeptDTO;
import com.hzyj.sc.dto.SpBusinessTypeDTO;
import com.hzyj.sc.service.ExamineDeptService;
import com.hzyj.sc.service.SpBusinessTypeFetchService;
import com.hzyj.sc.service.SpBusinessTypeService;
import com.hzyj.sc.utils.SnowflakeIdGenerator;
import com.hzyj.sc.vo.SpBusinessTypeFetchDO;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.service.BaseService;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteActivitiService;
import com.ruoyi.system.api.RemoteBaseScAccountRecordService;
import com.ruoyi.system.api.RemoteRuleService;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.StartActiviti;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.hzyj.sc.dto.SpScAppealRepairBusinessDTO;
import com.hzyj.sc.service.SpScAppealRepairBusinessService;
import com.hzyj.sc.vo.SpScAppealRepairBusinessDO;
import com.hzyj.sc.mapper.SpScAppealRepairBusinessMapper;
import org.springframework.util.CollectionUtils;

/**
 * 三船信用申诉和修复审批业务Service业务层处理
 * 
 * @author xb
 * @date 2024-05-09
 */
@Service
public class SpScAppealRepairBusinessServiceImpl extends ServiceImpl<SpScAppealRepairBusinessMapper, SpScAppealRepairBusinessDO> implements SpScAppealRepairBusinessService
{

    @Autowired
    private SpBusinessTypeService spBusinessTypeService;

    @Autowired
    private RemoteActivitiService remoteActivitiService;

    @Autowired
    private SpBusinessTypeFetchService spBusinessTypeFetchService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private ExamineDeptService examineDeptService;

    @Autowired
    private RemoteBaseScAccountRecordService remoteBaseScAccountRecordService;


    @Autowired
    private RemoteRuleService remoteRuleService;



    @Override
    @Transactional(rollbackFor = Exception.class)
    public SpScAppealRepairBusinessDTO saveEntity(SpScAppealRepairBusinessDTO entityDTO) {
        SpScAppealRepairBusinessDO entityDO =BaseService.dtoChange(entityDTO,SpScAppealRepairBusinessDO.class);
        if(super.save(entityDO)){
            return BaseService.dtoChange(entityDO,SpScAppealRepairBusinessDTO.class);
        }
        throw new ServiceException("系统异常");
    }

    @Override
    public SpScAppealRepairBusinessDTO getEntityById(Serializable id) throws Exception {
        return BaseService.dtoChange(super.getById(id),SpScAppealRepairBusinessDTO.class);
    }

    @Override
    public List<SpScAppealRepairBusinessDTO> listByEntity(SpScAppealRepairBusinessDTO entityDTO) throws Exception {

        SpScAppealRepairBusinessDO entityDO =BaseService.dtoChange(entityDTO,SpScAppealRepairBusinessDO.class);
        LambdaQueryWrapper<SpScAppealRepairBusinessDO> queryWrapper = new LambdaQueryWrapper<SpScAppealRepairBusinessDO>();
        queryWrapper.eq(StringUtils.isNotBlank(entityDO.getCreateBy()),SpScAppealRepairBusinessDO::getCreateBy,entityDO.getCreateBy());
        queryWrapper.like(StringUtils.isNotBlank(entityDO.getBusinessActType()),SpScAppealRepairBusinessDO::getBusinessActType,entityDO.getBusinessActType());
        List<SpScAppealRepairBusinessDO> list=super.list(queryWrapper);
        List<SpScAppealRepairBusinessDTO> dtoList = BaseService.dtoChange(list, SpScAppealRepairBusinessDTO.class);
        for (SpScAppealRepairBusinessDTO dto:dtoList
             ) {
            R<String> ruleRsc = remoteRuleService.getBaseScRuleDetail(dto.getGz());
            if(ruleRsc.getCode()!= Constants.SUCCESS){
                throw new ServiceException(ruleRsc.getMsg());
            }
            String ruleName = ruleRsc.getData();
            dto.setGzStr(ruleName);
        }
        return dtoList;
    }

    @Override
    public Page<SpScAppealRepairBusinessDTO> pageByEntity(Page page, SpScAppealRepairBusinessDTO entityDTO) throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getSysUser();
        SpScAppealRepairBusinessDO entityDO = BaseService.dtoChange(entityDTO,SpScAppealRepairBusinessDO.class);
        LambdaQueryWrapper<SpScAppealRepairBusinessDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(entityDO.getZhutiCode()),SpScAppealRepairBusinessDO::getZhutiCode,entityDO.getZhutiCode());
        queryWrapper.like(StringUtils.isNotBlank(entityDO.getZhutiName()),SpScAppealRepairBusinessDO::getZhutiName,entityDO.getZhutiName());
        queryWrapper.like(StringUtils.isNotBlank(entityDO.getZhutiIdentifier()),SpScAppealRepairBusinessDO::getZhutiIdentifier,entityDO.getZhutiIdentifier());
        queryWrapper.eq(StringUtils.isNotBlank(entityDO.getSpResultStatus()),SpScAppealRepairBusinessDO::getSpResultStatus,entityDO.getSpResultStatus());
        //queryWrapper.eq(SpScAppealRepairBusinessDO::getCreateBy,sysUser.getUserId());
        if (entityDTO.getParams() != null && entityDTO.getParams().containsKey("beginTime") && entityDTO.getParams().containsKey("endTime")) {
            // 在这里执行查询逻辑
            String beginTime = (String) entityDTO.getParams().get("beginTime");
            String endTime = (String) entityDTO.getParams().get("endTime");

            queryWrapper.between(SpScAppealRepairBusinessDO::getCreateTime, DateUtils.parseDate(beginTime), DateUtils.parseDate(endTime));
            // 使用 beginTime 和 endTime 来构建查询条件
        }
        if(StringUtils.isNotBlank(entityDTO.getQueryLx())){
            if("appeal".equals(entityDTO.getQueryLx())){
                queryWrapper.nested(
                        // 在这里放置你想要括起来的条件
                        wrapper -> wrapper.eq(SpScAppealRepairBusinessDO::getBusinessActType, "nomal_break_appeal")
                                .or()
                                .eq(SpScAppealRepairBusinessDO::getBusinessActType, "serious_break_appeal")
                );
            }else if("repair".equals(entityDTO.getQueryLx())){
                queryWrapper.eq(SpScAppealRepairBusinessDO::getBusinessActType, "serious_break_repair");
            }
        }
        queryWrapper.orderByDesc(SpScAppealRepairBusinessDO::getCreateTime);
        Page pageOut =super.page(page, queryWrapper);
        pageOut.setRecords(BaseService.dtoChange(pageOut.getRecords(), SpScAppealRepairBusinessDTO.class));
        return pageOut;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEntityById(SpScAppealRepairBusinessDTO entityDTO) throws Exception {
        SpScAppealRepairBusinessDO entityDO = BaseService.dtoChange(entityDTO, SpScAppealRepairBusinessDO.class);
        return super.updateById(entityDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeEntityById(Serializable id) throws Exception {
        return super.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeEntityByIds(SpScAppealRepairBusinessDTO entityDTO) throws Exception {
        return super.removeByIds(Arrays.asList(entityDTO.getIds()));
    }

    @Override
    @Transactional
    public void saveAndStartActiviti(SpScAppealRepairBusinessDTO dto) throws Exception{

        StartActiviti st =  new StartActiviti();

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getSysUser();

        //检查入参
        checkParam(dto);

        dto.setZhutiCode(user.getUserType());
        dto.setZhutiName(user.getNickName());

        if("7".contains(dto.getZhutiCode())) {//公司信用申请
            dto.setZhutiIdentifier(user.getEnterpriseCode());
        }else if("8".contains(dto.getZhutiCode())){//船舶信用申请
            dto.setZhutiIdentifier(user.getEnterpriseCode());
        }else if("6".contains(dto.getZhutiCode())){
            dto.setZhutiIdentifier(user.getCertNumber());
        }

        //生成id
        SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1, 1);
        String id = generator.nextId()+"";

        //版本一 写死的
        //String deptId = "2921";

        //版本二 从用户管理部门拿
        //ExamineDeptDTO edd = examineDeptService.queryExamineDeptDO(user);
        //String deptId = edd.getDeptId();

        //版本三 谁提交的，谁审批
        String deptId = dto.getManageUnit();

        //行业外用户固定部门为2333
        if("hy_nomal_break_appeal".equals(dto.getBusinessActType()) || "hy_serious_break_appeal".equals(dto.getBusinessActType())
                || "hy_serious_break_repair".equals(dto.getBusinessActType())){
            deptId = "2333";
        }

        //根据单位、部门、业务类型 获取工作流的key
        List<SpBusinessTypeFetchDO> typeFetchList = spBusinessTypeFetchService.getByGlBMAndActKey(deptId, dto.getBusinessActType());//暂时不能实现 先写死

        if(CollectionUtils.isEmpty(typeFetchList)){
            throw new ServiceException("该部门未配置流程实例，请联系管理员");
        }
        SpBusinessTypeFetchDO typeFetch = typeFetchList.get(0);

        String processDenfKey = typeFetch.getActKey();
        //获取配置主记录
        SpBusinessTypeDTO spBusinessType = spBusinessTypeService.getEntityById(typeFetch.getBid());
        if(spBusinessType==null){
            throw new ServiceException("该部门未配置流程实例，请联系管理员");
        }

        //生成title,并保存
        String title = designTitle(dto);
        dto.setTitle(title);


        //启动工作流
        st.setProcessDefinitionKey(processDenfKey);
        st.setId(id);
        st.setType(dto.getBusinessActType());
        st.setUserName(user.getUserName());
        //st.setDeptId(deptId);
        st.setDepts(deptId);
        st.setTitle(title);
        st.setSfbdm(spBusinessType.getBdwsp());
        //处理如果设置了第一审核人
        if(StringUtils.isNotBlank(spBusinessType.getFirstMan())) {
            String firstman = spBusinessType.getFirstMan();
            String[] assigeners = firstman.split(",");
            st.setAssigeners(assigeners);
        }
        //handleAssinger(spBusinessType,deptId,st);
        //启动工作流
        R<String> rsc = remoteActivitiService.startActiviti(st, SecurityConstants.INNER);
        if(rsc.getCode()!= Constants.SUCCESS){
            throw new ServiceException(rsc.getMsg());
        }
        String processInstanceId  = rsc.getData();
        dto.setInstanceId(processInstanceId);
        //关联流程实例编号,保存业务
        dto.setAppealRepairId(id);

        dto.setReadStatus("0");
        dto.setSpResultStatus("0");
        //dto.setSpResultStatus("-1");

        //前端偷懒，把别人原数据传过来了
        dto.setDelFlag(null);
        dto.setCreateBy(null);
        dto.setCreateTime(null);
        dto.setUpdateBy(null);
        dto.setUpdateTime(null);

        this.saveEntity(dto);

        //改变源记录的状态
        R<String> rcdRsc = remoteBaseScAccountRecordService.updateApplyStatusByRecordId(dto.getCreditEventsId(), "1");

        if(rcdRsc.getCode()!= Constants.SUCCESS){
            throw new ServiceException(rsc.getMsg());
        }

    }

    private void handleAssinger(SpBusinessTypeDTO spBusinessType, String deptId, StartActiviti st){
        if(StringUtils.isNotBlank(spBusinessType.getFirstMan())){
            String firstman = spBusinessType.getFirstMan();
            String[] assigeners = firstman.split(",");
            if("0".equals(spBusinessType.getBdwsp())){//0本单位审核
                //第一阶段只允许本单位审批，则需要判断第一审批人是否属于本单位
                R<List<SysUser>> userRes = remoteUserService.checkUserDepts(assigeners, deptId, SecurityConstants.INNER);
                if(userRes.getCode()!= Constants.SUCCESS){
                    throw new ServiceException(userRes.getMsg());
                }
                List<SysUser> userList = userRes.getData();
                if(!CollectionUtils.isEmpty(userList)){
                    String[] assigeners_bl = new String[userList.size()];
                    for (int i = 0; i < userList.size(); i++) {
                        assigeners_bl[i] = userList.get(i).getUserName();
                    }
                    st.setAssigeners(assigeners_bl);
                }
            }else{//允许非本单位审批
                //允许非单位审批，直接指定审批人

                st.setAssigeners(assigeners);
            }
        }
    }

    private String designTitle(SpScAppealRepairBusinessDTO dto) {

        String title = "关于【";
        title+= dto.getZhutiName();
        String typeStr = "nomal_break_appeal".equals(dto.getBusinessActType()) || "serious_break_appeal".equals(dto.getBusinessActType()) ?"信用申诉":"信用修复";
        title+= "】的安全"+typeStr+"申请";
        return title;
    }

    private void checkParam(SpScAppealRepairBusinessDTO dto) {

        if(StringUtils.isBlank(dto.getBusinessActType())){
            throw new ServiceException("业务类型不能为空");
        }


        if(StringUtils.isBlank(dto.getCreditEventsId())){
            throw new ServiceException("信用事件不能为空");
        }

        if(StringUtils.isBlank(dto.getHyType())){
            throw new ServiceException("行业用户标识不能为空");
        }

        if(StringUtils.isBlank(dto.getJfxw())){
            throw new ServiceException("记分行为不能为空");
        }


        if(StringUtils.isBlank(dto.getGz())){
            throw new ServiceException("规则不能为空");
        }

        if("nomal_break_appeal".equals(dto.getBusinessActType()) || "serious_break_appeal".equals(dto.getBusinessActType())
                || "serious_break_repair".equals(dto.getBusinessActType())){
            if(StringUtils.isBlank(dto.getManageUnit())){
                throw new ServiceException("业务管理部门不能为空");
            }

        }else if("hy_nomal_break_appeal".equals(dto.getBusinessActType()) || "hy_serious_break_appeal".equals(dto.getBusinessActType())
                || "hy_serious_break_repair".equals(dto.getBusinessActType())){

        }
        else{
            throw new ServiceException("业务类型不匹配");
        }


    }
}



上面是我写的一个java类，我发现里面有很多重复的代码，你能帮我把代码优化一下，显得更整洁，高级，重复代码尽量少。但是实现功能不能变