package com.lz.modules.app.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lz.common.emun.ChartFlowType;
import com.lz.common.emun.WorkMsgTypeEnum;
import com.lz.common.utils.*;
import com.lz.modules.app.dto.ApprovalDto;
import com.lz.modules.app.dto.DepartmentsDto;
import com.lz.modules.app.dto.RecordDetailDto;
import com.lz.modules.app.dto.StaffDepartmentDto;
import com.lz.modules.app.entity.DepartmentsStaffRelateEntity;
import com.lz.modules.app.entity.StaffEntity;
import com.lz.modules.app.entity.StaffSimpleInfo;
import com.lz.modules.app.req.RecordDetailExplanReq;
import com.lz.modules.app.req.ResultRecordReq;
import com.lz.modules.app.resp.RecordDetailExportResp;
import com.lz.modules.app.resp.ResultDetailResp;
import com.lz.modules.app.resp.Step;
import com.lz.modules.app.service.DepartmentsService;
import com.lz.modules.app.service.DepartmentsStaffRelateService;
import com.lz.modules.app.service.StaffOccupationService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.flow.entity.*;
import com.lz.modules.flow.model.*;
import com.lz.modules.flow.req.ResultDetailReq;
import com.lz.modules.flow.service.*;
import com.lz.modules.job.business.DingtalkBusiness;
import com.lz.modules.performance.dto.ResultTaskDto;

import com.lz.modules.performance.dto.StaffTypeDto;
import com.lz.modules.performance.req.ResultUpdateTaskReq;

import com.lz.modules.performance.entity.ResultTask;
import com.lz.modules.performance.res.ResultRankListRes;
import com.lz.modules.performance.service.ChartResultService;
import com.lz.modules.performance.service.ResultTaskService;
import com.lz.modules.sys.controller.AbstractController;
import com.lz.modules.sys.entity.Print;
import com.lz.modules.sys.entity.Resource;
import com.lz.modules.sys.entity.SysUserEntity;
import com.lz.modules.sys.entity.app.ResultComment;
import com.lz.modules.sys.entity.app.ResultDetail;
import com.lz.modules.sys.entity.app.ResultRecord;
import com.lz.modules.sys.service.PrintService;
import com.lz.modules.sys.service.ResourceService;
import com.lz.modules.sys.service.app.ResultCommentService;
import com.lz.modules.sys.service.app.ResultDetailService;
import com.lz.modules.sys.service.app.ResultRecordService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 业绩记录表
 *
 * @author zgh
 * @email zgh@ldxinyong.com
 * @date 2020-08-10 17:19:22
 */
@RestController
@RequestMapping("user/lzresultrecord")
@Slf4j
@Api(tags = "绩效相关")
public class ResultRecordController extends AbstractController {
    @Autowired
    private ResultRecordService lzResultRecordService;
    @Autowired
    private DepartmentsService departmentsService;
    @Autowired
    private ResultDetailService resultDetailService;
    @Autowired
    private ResultRecordService resultRecordService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private DepartmentsStaffRelateService departmentsStaffRelateService;
    @Autowired
    private RecordAuthService recordAuthService;
    @Autowired
    private ResultCommentService resultCommentService;

    @Autowired
    private FlowRecordService flowRecordService;

    @Autowired
    private RecordFileService  recordFileService;

    @Autowired
    private EvaluationStartStaffService evaluationStartStaffService;

    @Autowired
    private   StaffRoleService staffRoleService;

    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Autowired
    private ResultModelService resultModelService;

    @Autowired
    private ResultCalculateService resultCalculateService;

    @Autowired
    private ResultScoreService resultScoreService;

    @Autowired
    private FlowChartDetailRecordService flowChartDetailRecordService;

    @Autowired
    private DingtalkBusiness dingtalkBusiness;

    @Autowired
    private PrintService printService;

    @Autowired
    private ResourceService resourceService;
    @Autowired
    private ChartResultService chartResultService;
    @Autowired
    private FlowStartService flowStartService;

    @Autowired
    private ResultTaskService resultTaskService;
    @Autowired
    private StaffOccupationService staffOccupationService;



    private final static String TYPE = "H5_URL";
    private final static String SEC_TYPE = "RECORD";

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("user:lzresultrecord:list")
    public R list(ResultRecordReq req) {
        List<DepartmentsDto> departmentList2 = new ArrayList<>();
        List<DepartmentsDto> departmentList3 = new ArrayList<>();
        List<DepartmentsDto> departmentList1 = departmentsService.selectByParentDepartmentId("1");
        String department1 = req.getDepartment1();
        String department2 = req.getDepartment2();
        String department3 = req.getDepartment3();
        SysUserEntity user = getUser();
        if (req.getIsSelf() == 1) {
            req.setStaffId(user.getUserId());
        } else {
            StaffRole staffRole = staffRoleService.selectByStaffId(getUserId());
            if (staffRole == null && req.getIsChangeDepartmentrtment() == 0) {
                DepartmentsStaffRelateEntity relateEntity = departmentsStaffRelateService.selectLastDepartmentByStaffId(getUserId());
                Map<String, String> map = departmentsService.selectUserAllDepartmentInFo(relateEntity.getDepartmentId());
                int i = 0;
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    i++;
                }
                i = i / 2;
                if (i == 3) { // 表示有三级部门
                    departmentList2 = departmentsService.selectByParentDepartmentId(map.get("dd3"));
                    departmentList3 = departmentsService.selectByParentDepartmentId(map.get("dd2"));
                    department1 = map.get("dd3");
                    department2 = map.get("dd2");
                    department3 = map.get("dd1");
                    req.setDepartment3(map.get("dd1"));
                } else if (i == 2) {
                    departmentList2 = departmentsService.selectByParentDepartmentId(map.get("dd2"));
                    department2 = map.get("dd1");
                    department1 = map.get("dd2");
                    req.setDepartment2(map.get("dd1"));
                } else if (i == 1) {
                    department1 = map.get("dd1");
                    req.setDepartment1(map.get("dd1"));
                }
            }
        }
        R r = lzResultRecordService.queryPage(req, user);
        r .put("departmentList1", departmentList1)
                .put("departmentList2", departmentList2)
                .put("departmentList3", departmentList3)
                .put("department1", department1)
                .put("department2", department2)
                .put("department3", department3);
        return r ;

    }


    @RequestMapping("/departmentQuery")
    public R departmentQuery(ResultRecordReq req) {
        List<DepartmentsDto> departmentList1 = departmentsService.selectByParentDepartmentId(req.getDepartmentId());
        return R.ok()
                .put("departmentList", departmentList1);
    }

    @RequestMapping("/getStaffResultDetail")
    public R getStaffResultDetail(ResultRecordReq req) {
        int yeJiCheckNum = 0;
        int wenHuaJiaZhiGuanNum = 1;
        int lastResultNum = 2;
        int commentNum = 0;
        int recordType = req.getRecordType();
        ResultRecord resultRecord = resultRecordService.selectResultRecordById(req.getRecordResultId());
        StaffEntity staffEntity = staffService.getById(resultRecord != null ? resultRecord.getStaffId() : getUserId());
        List<DepartmentsStaffRelateEntity> departmentsStaffRelateEntities = departmentsStaffRelateService.selectByStaffIds(Arrays.asList(staffEntity.getId()));
        DepartmentsStaffRelateEntity departmentsStaffRelateEntity = departmentsStaffRelateEntities.get(0);
        StaffDepartmentDto departmentDto = departmentsService.selectStaffAllDepartments(departmentsStaffRelateEntity.getDepartmentId());
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM");
        List<ResultDetailResp> list = new ArrayList<>();
        // 获取权限
        Auth auth = new Auth();
        List<RecordAuth> listAuth = new ArrayList<>();
        if (req.getRecordType() == 1 && resultRecord == null) { //新增目标
            listAuth = recordAuthService.selectAuthInfo(7l);
            auth = recordAuthService.getAuth(listAuth);
            resultRecord = resultRecordService.createResultRecord(getUserId(), req.getRecordType(), 7l);
            flowRecordService.initFlowRecord(resultRecord, 7l, req.getRecordType(), "月初目标");
            recordType = 3;
        } else if (req.getRecordType() == 2 && resultRecord == null) { //新增业绩
            listAuth = recordAuthService.selectAuthInfo(8l);
            auth = recordAuthService.getAuth(listAuth);
            auth.setWenHuaEdit(1);
            resultRecord = resultRecordService.initResult(getUserId(), req.getRecordType(), 8l);
            recordType = 3;
        } else if (resultRecord != null) {
            Map<Long, Long> staffRoleMap = recordAuthService.selectRoleIdByStaffRoleInfo(resultRecord.getFlowStaffIdRole());
            listAuth = recordAuthService.selectAuthInfo(staffRoleMap.get(getUserId()));
            auth = recordAuthService.getAuth(listAuth);
        }
        List<ResultDetail> resultDetails = resultDetailService.selectByRecordId(resultRecord.getId());
        List<Step> stepList = resultDetailService.getStepList(resultRecord);
        BigDecimal sumWenHuaJiaZhiGuan = BigDecimal.ZERO;
        BigDecimal sumYeJi = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(resultDetails)) {
            Map<Integer, Long> details = resultDetails.stream().collect(Collectors.groupingBy(ResultDetail::getType, Collectors.counting()));
            int tempType1 = NumberUtil.objToIntDefault(details.get(new Integer(1)), 0);
            int tempType2 = NumberUtil.objToIntDefault(details.get(new Integer(2)), 0);
            yeJiCheckNum = tempType1;
            wenHuaJiaZhiGuanNum = tempType2;
            if (tempType1 == 0) {
                yeJiCheckNum = 1;
                list.add(resultDetailService.getYeJi());
                list.add(resultDetailService.getYeJiKaoHe(BigDecimal.ZERO));
            }
            int count = 0;
            for (ResultDetail resultDetail : resultDetails) {
                count++;
                ResultDetailResp resp = new ResultDetailResp();
                BeanUtils.copyProperties(resultDetail, resp);
                if (resultDetail.getType() == 1) {
                    resp.setCheckRange("绩效");
                } else if (resultDetail.getType() == 2) {
                    resp.setCheckRange("文化价值观");
                }
                if (count == yeJiCheckNum) {
                    resp.setIsAdd(1);
                }
                resp.setIsEdit(1);
                BigDecimal checkWeight = NumberUtil.objToBigDecimalDefault(resultDetail.getCheckWeight(), BigDecimal.ZERO);
                BigDecimal acquireScore = NumberUtil.objToBigDecimalDefault(resultDetail.getAcquireScore(), BigDecimal.ZERO);
                BigDecimal tempSum = checkWeight.multiply(acquireScore);
                if (resultDetail.getType().equals(1)) {
                    sumYeJi = sumYeJi.add(tempSum);
                } else {
                    sumWenHuaJiaZhiGuan = sumWenHuaJiaZhiGuan.add(tempSum);
                }
                if (count == yeJiCheckNum + 1 && tempType1 != 0) {
                    list.add(resultDetailService.getYeJiKaoHe(BigDecimalUtil.setScale(sumYeJi, 3)));
                }
                list.add(resp);
            }
            if (tempType2 == 0) {
                list.add(resultDetailService.getYeJiKaoHe(BigDecimal.ZERO));
                list.add(resultDetailService.getWenHuaJiaZhiGua1(auth));
            }
        } else {
            yeJiCheckNum = 1;
            list.add(resultDetailService.getYeJi());
            list.add(resultDetailService.getYeJiKaoHe(BigDecimal.ZERO));
            list.add(resultDetailService.getWenHuaJiaZhiGua1(auth));
        }
        list.add(resultDetailService.getWenHuaJiaZhiGuaResult1(sumWenHuaJiaZhiGuan));
        list.add(resultDetailService.getWenHuaJiaZhiGuaResult2());
        list.add(resultDetailService.getLastResult(resultRecord.getLastScore()));
        List<ResultComment> comments = resultCommentService.selectByRecordId(resultRecord.getId());

        if (CollectionUtils.isNotEmpty(comments)) {
            ResultDetailResp header = new ResultDetailResp();
            header.setCheckRange("领导");
            header.setTarget("状态");
            header.setKeyResult("意见");
            list.add(header);
            commentNum = comments.size();
            for (ResultComment resultComment : comments) {
                ResultDetailResp comment = new ResultDetailResp();
                comment.setCheckRange(resultComment.getStaffName());
                String target = "审批通过";
                if (resultComment.getStatus() == 5) {
                    target = "驳回";
                }else if (resultComment.getStatus() == 6){
                    target = "申述";
                }
                comment.setTarget(target);
                comment.setKeyResult(resultComment.getComment());
                list.add(comment);
            }
        }
        String superStaff = recordAuthService.selectByStaffId(resultRecord.getStaffId());
        int fileCount = recordFileService.selectRecordFileCountByRecordId(resultRecord.getId());
        //表示是自己查看详情
        if(resultRecord.getStaffId().equals(getUserId())){
            List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordByResultRecordIdTypeStatus(req.getRecordResultId(), resultRecord.getType(), 0);
            if (flowRecords != null && flowRecords.size() == 2) {       // 表示可以撤回
                auth.setCancel(1);
            }
            // 审批人是自己，不提供催办按钮,流程结束不显示
            if (flowRecords != null && flowRecords.size() >= 2 &&
                    !getUserId().equals(resultRecord.getCurrentApprovalStaffId()) &&
                    resultRecord.getCurrentApprovalStaffId() != null) {
                auth.setSubmited(1);
            }
        }

        return R.ok()
                .put("staffName", staffEntity.getName())
                .put("department1", departmentDto.getDepartment1())
                .put("department2", departmentDto.getDepartment2())
                .put("department3", departmentDto.getDepartment3())
                .put("checkMonth", sdf3.format(resultRecord == null ? new Date() : resultRecord.getMonthTime()))
                .put("list", list)
                .put("auth", auth)
                .put("recordType", recordType)
                .put("recordResultId", resultRecord.getId())
                .put("yeJiCheckNum", yeJiCheckNum)
                .put("wenHuaJiaZhiGuanNum", wenHuaJiaZhiGuanNum)
                .put("lastResultNum", lastResultNum)
                .put("commentNum", commentNum)
                .put("superStaff", superStaff)
                .put("fileCount",fileCount)
                .put("stepList",stepList)
        ;
    }

    @RequestMapping("/commitApproval")
    public R commitApproval(ResultRecordReq req) {
        return resultRecordService.commitApproval(req, getUserId());
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("user:lzresultrecord:info")
    public R info(@PathVariable("id") Long id) {
        ResultRecord lzResultRecord = lzResultRecordService.selectResultRecordById(id);
        return R.ok().put("lzResultRecord", lzResultRecord);
    }

    /**
     * 信息
     */
    @GetMapping("/urging")
    @ApiOperation("绩效催办-吴林")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "绩效id")})
    @ApiResponses({@ApiResponse(code = 200, message = "成功", response = R.class)})
    public R urging(@RequestParam Long id) {
        ResultRecord lzResultRecord = lzResultRecordService.selectResultRecordById(id);
        //获取当前节点，谁在处理
        List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordsByRecordIdAndStatus(id, 2);
        if(flowRecords.size() > 0){
            List<Long> ids = flowRecords.stream().map(new Function<FlowRecord, Long>() {
                @Override
                public Long apply(FlowRecord flowRecord) {
                    return flowRecord.getApprovalStaffId();
                }
            }).collect(Collectors.toList());
            List<StaffEntity> staffs = staffService.selectNamesByIds(ids);
            dingtalkBusiness.sendNoticeMsg(lzResultRecord, staffs);
            return R.ok("催办成功");
        }
        return R.error("无可催办人员");
    }

    /**
     * 信息
     */
    @GetMapping("/getDetail")
    @ApiOperation("获取绩效详情-吴林")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "绩效id可为空，为空时使用token的用户获取"),
            @ApiImplicitParam(name = "startId", value = "任务id可为空，为空时使用token的用户获取")})
    @ApiResponses({@ApiResponse(code = 200, message = "成功", response = ResultRecordDetailDto.class)})
    public R getDetail(@RequestParam Map<String, Object> param) {
        Long id = null;
        Long startId = null;
        SysUserEntity user = getUser();
        ResultRecord resultRecord = null;

        if(param.containsKey("id")){
            String value = param.get("id").toString();
            if(value.length() > 0){
                id = Long.parseLong(value);
            }
        }else if(param.containsKey("startId")){//根据startId和token获取
            String value = param.get("startId").toString();
            if(value.length() > 0){
                startId = Long.parseLong(value);
            }
        }

        if(id == null){
            if(startId == null){
                //根据token获取
                resultRecord = lzResultRecordService.selectLastResultRecordByUserId(getUserId());
                if(resultRecord == null){
                    return R.error("绩效不存在");
                }
            }else{
                resultRecord = lzResultRecordService.selectResultRecordByStaffIdAndStartId(getUserId(), startId);
                if(resultRecord == null){
                    return R.error("绩效不存在");
                }
            }
        }else{
            resultRecord = lzResultRecordService.selectResultRecordById(id);
            if(resultRecord == null){
                return R.error("绩效不存在");
            }
            //下面判断权限
            if(user.getUserId().longValue() != resultRecord.getStaffId().longValue()){
                //不是自己的绩效，判断是否为绩效管理人员，老板，部门管理人员
                log.info("不是自己的绩效");
            }
        }

        //获取考核维度等信息
        ResultRecordDetailDto resultRecordDetailDto = new ResultRecordDetailDto();
        BeanUtils.copyProperties(resultRecord, resultRecordDetailDto);
        List<ResultModel> resultModels = resultModelService.selectResultModelByGroupId(resultRecord.getEvaluationId());
        //获取单个人评分总分计算公式
        List<CalculateModel> calculateModels1 = getCalculate(3l);
        //获取每行的计算公式
        List<CalculateModel> calculateModels = getCalculate(resultModels.get(0).getCalculateId());



        List<ResultScoreDto> scoreDtos = new ArrayList<>();
        //查询所有参与评分人以及所占比重
        List<FlowChartDetailRecord> flowChartDetailRecords =
                flowChartDetailRecordService.selectFlowChartDetailRecordsByFlowProcess(resultRecord.getEvaluationId(), ChartFlowType.SCORE.getCode());//获取参与评分的人

        //List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordByRecordIdFlowProcess(resultRecord.getId(), ChartFlowType.SCORE.getCode());
        List<StaffEntity> staffs = new ArrayList<>();
        Boolean isAllScore = true;//false表示返回所有的评分，true表示值返回评分了的人
        Boolean isOrScore = false;//是否为或签
        for (FlowChartDetailRecord record:flowChartDetailRecords
        ) {
            List<StaffEntity> staffs1 = new ArrayList<>();
            if(record.getOptType().intValue() == -1){
                //自己
                StaffEntity staffEntity = new StaffEntity();
                staffEntity.setId(resultRecord.getStaffId());
                staffEntity.setName(resultRecord.getStaffName());
                staffs1.add(staffEntity);
            }else if(record.getOptType().intValue() == 0){
                //指定人员
                //获取人员信息
                List<Long> sIds = Arrays.stream(record.getOptIds().split(",")).map(new Function<String, Long>() {
                    @Override
                    public Long apply(String s) {
                        return Long.parseLong(s);
                    }
                }).collect(Collectors.toList());
                staffs1.addAll(staffService.selectNamesByIds(sIds));//这里不过滤离职人员，因为过滤了可能涉及到评分规则的变更

            }else{
                //领导
                DepartManagers departManagers = staffService.findLeader(resultRecord.getStaffId(), record.getOptType());
                if(departManagers.getManagers().size() > 0){
                    staffs1.addAll(departManagers.getManagers());
                }
            }
            if(staffs1.size() == 0){
                log.info("无法找到评分人员，开始找绩效管理人员");
                staffs1 = staffService.findManger(resultRecord.getId(), ChartFlowType.SCORE.getCode());
            }
            //流程已经到了审批节点，那么判断评分是否为或签，如果是那么只需要返回实际评分的那个人即可，否则全部返回
            List<FlowRecord>  flowRecords = flowRecordService.selectFlowRecordByRecordIdFlowProcess(resultRecord.getId(), ChartFlowType.SCORE.getCode());//获取当前的流程节点
            if(flowRecords.size() == 0){
                return R.error("绩效流程数据初始化中...，请稍后！");
            }
            if(flowRecords.get(0).getType().intValue() == 1){
                //或签,这里还有优化。多个评分节点时，针对每个节点是否为或签
                isOrScore = true;
            }

            for (StaffEntity staff:staffs1
            ) {
                ResultScoreDto resultScore = new ResultScoreDto();
                resultScore.setIsEdit(0);
                resultScore.setApprovalId(staff.getId());
                resultScore.setApprovalName(staff.getName());
                if(isOrScore){
                    //或签每个权重一样
                    resultScore.setWeight(record.getWeight());
                }else{
                    //多人的时候权重平分
                    resultScore.setWeight(record.getWeight().divide(BigDecimal.valueOf(staffs1.size()), RoundingMode.HALF_UP));
                }

                scoreDtos.add(resultScore);
            }

            flowRecords = flowRecordService.selectFlowRecordByRecordIdStatus(resultRecord.getId(), 0);//获取未执行的节点
            if(flowRecords.size() > 0){
                if(flowRecords.get(0).getFlowProcess().intValue() > ChartFlowType.SCORE.getCode()){
                    //流程已经到了审批节点，那么判断评分是否为或签，如果是那么只需要返回实际评分的那个人即可，否则全部返回
                    if(isOrScore){
                        isAllScore = false;
                    }
                }
            }else{//绩效流程已经走完
                if(isOrScore){
                    isAllScore = false;
                }
            }


            staffs.addAll(staffs1);

        }


        resultRecordDetailDto.setGradeGroupId(resultModels.get(0).getGradeGroupId());//设置评分等级
        StaffEntity staffEntity = staffService.selectStaffById(resultRecord.getStaffId());
        resultRecordDetailDto.setAvatar(staffEntity.getAvatar());
        resultRecordDetailDto.setJobNumber(staffEntity.getJobNumber());
        List<ResultRecortModelDto> resultRecortModelDtos = new ArrayList<>();
        BigDecimal weight = BigDecimal.ZERO;
        for (ResultModel model:resultModels
        ) {
            ResultRecortModelDto resultRecortModelDto = new ResultRecortModelDto();
            BeanUtils.copyProperties(model, resultRecortModelDto);
            if(resultRecortModelDto.getWeight().compareTo(BigDecimal.ZERO) == 0){//不限权重的
                resultRecortModelDto.setWeight(null);
            }
            if(resultRecortModelDto.getMaxCount().intValue() == 10000){//不限制数量
                resultRecortModelDto.setMaxCount(null);
            }
            List<ResultDetailDto> detailDtos =
                    resultDetailService.selectDtosByRecordId(resultRecord.getId(), model.getId());
            for (ResultDetailDto dto:detailDtos
            ) {
                //下面设置计算公式
                //dto.setCalculate(setCalculateValue(calculateModels1, dto)) ;
                List<ResultTaskDto> resultTaskDtos = resultTaskService.selectResultTaskDtosByDetailId(dto.getId());
                dto.setTaskDtos(resultTaskDtos);
                weight = weight.add(dto.getCheckWeight());
                if(scoreDtos.size() > 0){
                    //获取评分详细
                    List<ResultScore> scores =
                            resultScoreService.selectResultScoresByDetailIdAndOrderByStaffIds(dto.getId(), scoreDtos);

                    if(scores.size() > 0){//已经有平分了

                        List<ResultScoreDto> scoreDtos1 = new ArrayList<>();
                        for (ResultScoreDto scoreDto: scoreDtos
                        ) {//


                            boolean isAdd = false;
                            for (ResultScore score:
                                    scores) {//设置每个已经评分的领导
                                if(scoreDto.getApprovalId().longValue() == score.getApprovalId().longValue()){
                                    ResultScoreDto scoreDto1 = new ResultScoreDto();
                                    BeanUtils.copyProperties(score, scoreDto1);
                                    scoreDto1.setApprovalId(scoreDto.getApprovalId());
                                    scoreDto1.setApprovalName(scoreDto.getApprovalName());
                                    scoreDto1.setWeight(scoreDto.getWeight());
                                    //下面设置计算公式
                                    scoreDto1.setCalculate(setCalculateValue(calculateModels, model)) ;
                                    scoreDto1.setCalculate(scoreDto1.getCalculate() + setCalculateValue(calculateModels, dto)) ;
                                    scoreDto1.setCalculate(scoreDto1.getCalculate() + setCalculateValue(calculateModels, scoreDto1)) ;
                                    scoreDtos1.add(scoreDto1);

                                    //设置个人评分总分的计算方式， add
                                    scoreDto1.setAllCalculate(setCalculateValue(calculateModels1, dto)) ;
                                    scores.remove(score);
                                    isAdd = true;
                                    break;
                                }
                            }
                            if(!isAdd && isAllScore){//如果isAllScore为true返回所有的评分包括为评分和已评分的，false只返回已评分的，评分或签时用到
                                ResultScoreDto scoreDto1 = new ResultScoreDto();
                                scoreDto1.setApprovalId(scoreDto.getApprovalId());
                                scoreDto1.setApprovalName(scoreDto.getApprovalName());
                                scoreDto1.setWeight(scoreDto.getWeight());
                                //下面设置计算公式
                                scoreDto1.setCalculate(setCalculateValue(calculateModels, model)) ;
                                scoreDto1.setCalculate(scoreDto1.getCalculate() + setCalculateValue(calculateModels, dto)) ;
                                scoreDto1.setCalculate(scoreDto1.getCalculate() + setCalculateValue(calculateModels, scoreDto1)) ;
                                scoreDtos1.add(scoreDto1);
                            }
                        }
                        dto.setScoreDtos(scoreDtos1);
                    }else{//一个评分都没有
                        List<ResultScoreDto> scoreDtos1 = new ArrayList<>();
                        for (ResultScoreDto scoreDto: scoreDtos
                        ) {//
                            //下面设置计算公式
                            ResultScoreDto sdto = new ResultScoreDto();
                            BeanUtils.copyProperties(scoreDto, sdto);
                            sdto.setCalculate(setCalculateValue(calculateModels, model));
                            sdto.setCalculate(sdto.getCalculate() + setCalculateValue(calculateModels, dto));
                            sdto.setCalculate(sdto.getCalculate() + setCalculateValue(calculateModels, sdto));
                            scoreDtos1.add(sdto);
                        }
                        dto.setScoreDtos(scoreDtos1);
                    }
                }
            }
            resultRecortModelDto.setDetailDtos(detailDtos);

            resultRecortModelDtos.add(resultRecortModelDto);
        }
        resultRecordDetailDto.setWeight(weight);
        resultRecordDetailDto.setRecortModelDtos(resultRecortModelDtos);

        //增加导出所需数据
        List<String> depIds = Lists.newArrayList(resultRecord.getDepartmentId());
        Map<Long, List<String>> map = departmentsService.selectDepartmentTreeByDepIds(depIds);

        List<String> names = map.get(Long.valueOf(resultRecord.getDepartmentId()));
        if(CollectionUtils.isNotEmpty(names)){
            Collections.reverse(names);
            int size = names.size();
            if(size>0 && StringUtils.isNotBlank(names.get(0))){
                resultRecordDetailDto.setDepartmentOne(names.get(0));
            }
            if(size>1 && StringUtils.isNotBlank(names.get(1))){
                resultRecordDetailDto.setDepartmentTwo(names.get(1));
            }
            if(size>2 && StringUtils.isNotBlank(names.get(2))){
                resultRecordDetailDto.setDepartmentThree(names.get(2));
            }
        }

        List<Long> staffIds = Lists.newArrayList(resultRecord.getStaffId());
        List<StaffTypeDto> staffTypeDtos = staffOccupationService.selectStaffTypesByStaffIds(staffIds);

        if(CollectionUtils.isNotEmpty(staffTypeDtos)){
            resultRecordDetailDto.setPosition(staffTypeDtos.get(0).getPosition());
        }
        FlowStart flowStart = flowStartService.selectFlowStartById(resultRecord.getStartId());
        if(flowStart != null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            String startDate = sdf.format(flowStart.getStartTime());
            if(flowStart.getCycleType().intValue() != 0){
                String endDate = sdf.format(flowStart.getEndTime());
                resultRecordDetailDto.setAssessCycle(startDate + "至" + endDate );
            }else{
                resultRecordDetailDto.setAssessCycle(startDate);
            }
        }


        return R.ok().put("data", resultRecordDetailDto);
    }

    //目前支持已生成对象的。不支持当前非对象表中的数据，如果要使用请用常量值
    //lz_result_detail>check_weight*lz_result_detail>acquire_score
    private String setCalculateValue(List<CalculateModel> calculateModels, Object model){
        String mName = model.getClass().getName();//.replace("req", "dto");
        String cal = "";
        //for (CalculateModel calculate:calculateModels
        //) {
        for(int i = 0; i < calculateModels.size(); i++){
            CalculateModel calculate = calculateModels.get(i);
            if(calculate.getTaboleBeanName() == null){//数字
                cal += calculate.getFieldName();
                if(calculate.getOpt() != null){
                    cal += calculate.getOpt();
                }
            }else if(mName.contains("." + calculate.getTaboleBeanName())){//支持表名生成的req和dto
                //获取值
                try {
                    Class<?> clazz = model.getClass();
                    Method method = clazz.getMethod("get" + calculate.getFieldBeanName());
                    Object obj = method.invoke(model);
                    if(obj != null){
                        calculate.setFieldValue(obj.toString());
                    }
                    //最后一个对象为自己，或者获取的对象中的属性为null
                    if(calculate.getFieldValue() == null || i == calculateModels.size() - 1){
                        cal += ("{" + calculate.getFieldBeanName().substring(0, 1).toLowerCase() + calculate.getFieldBeanName().substring(1) + "}");
                    }else{
                        cal += calculate.getFieldValue();
                    }
                    if(calculate.getOpt() != null){
                        cal += calculate.getOpt();
                    }
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        return cal;
    }

    private List<CalculateModel> getCalculate(Long id){
        ResultCalculate resultCalculate =
                resultCalculateService.selectResultCalculateById(id);
        char[] chars = new char[resultCalculate.getCalculate().length()];
        resultCalculate.getCalculate().getChars(0, chars.length, chars, 0);
        List<CalculateModel> calculateModels = new ArrayList<>();
        CalculateModel calculateModel = null;
        int type = 0;//0table名称 1字段名称
        String value = "";
        boolean isDig = false;//是否为数字
        for (int i = 0; i < chars.length;i++
        ) {
            char b = chars[i];
            if(b == '*' || b == '/' || b == '+' || b == '-'){
                if(isDig){
                    calculateModel.setTableName(null);
                }
                calculateModel.setFieldName(value);
                calculateModel.setFieldBeanName(getBeanName(value));
                calculateModel.setOpt(String.valueOf(b));
                calculateModels.add(calculateModel);
                calculateModel = null;
                type = 0;
                value = "";
                isDig = false;
                continue;

            }else if(b == '>'){
                if(type == 0){
                    calculateModel.setTableName(value);
                    value = value.replace("lz_", "");//去掉lz_前缀
                    calculateModel.setTaboleBeanName(getBeanName(value));
                }
                type--;
                type *= -1;
                value = "";
                isDig = false;
                continue;
            }else if(b > 47 && b < 58){
                //数字
                isDig = true;
            }
            if(calculateModel == null){
                calculateModel = new CalculateModel();
            }
            value += String.valueOf(b);
            if(i == chars.length - 1){
                if(isDig){
                    calculateModel.setTableName(null);
                }
                calculateModel.setFieldName(value);
                calculateModel.setFieldBeanName(getBeanName(value));
                calculateModels.add(calculateModel);
                isDig = false;
                break;
            }

        }
        return calculateModels;
    }

    private String getBeanName(String value){
        String[] bean = value.split("_");
        value = "";
        for(String s:bean){
            value += s.substring(0, 1).toUpperCase() + s.substring(1);
        }
        return value;
    }

    @PostMapping("/saveDetail")
    @ApiOperation("保存绩效详情-吴林")
    public R saveDetail(@RequestBody @ApiParam ResultRecordDetailDto dto) {
        Long userId = getUserId();
        //ResultRecord resultRecord = new ResultRecord();
        ResultRecord resultRecord = resultRecordService.selectResultRecordById(dto.getId());

        resultRecord.setAllScore(resultRecord.getLastScore());
        List<ResultDetail> inserts = new ArrayList<>();
        List<ResultDetail> updates = new ArrayList<>();

        List<ResultScore> insertScores = new ArrayList<>();
        List<ResultScore> updateScores = new ArrayList<>();

        List<ResultDetail> resultDetails = resultDetailService.selectByRecordId(dto.getId());
        Map<Long, ResultDetail> mapDetails =
                resultDetails.stream().collect(Collectors.toMap(ResultDetail::getId, Function.identity(), (e, r) -> e));

        List<ResultDetail> updateResultDetails = new ArrayList<>();
        List<ResultDetail> editResultDetails = new ArrayList<>();//涉及到修改的指标保存，方便后面生成修改记录

        //获取当前绩效的节点
        boolean isSetKeyResult = false;
        List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordByRecordIdStatus(dto.getId(), 2);
        if(flowRecords.size() > 0){
            if(dto.getSave() != null && dto.getSave().intValue() ==1){
                if(flowRecords.get(0).getFlowProcess().intValue() < 1){//因为先提交流程在保存，所以这里写了小于2
                    //指定目标中
                    log.info("暂存制定目标中");
                    isSetKeyResult = true;
                }
            }else{
                if(flowRecords.get(0).getFlowProcess().intValue() < 2){//因为先提交流程在保存，所以这里写了小于2
                    //指定目标中
                    log.info("制定目标中");
                    isSetKeyResult = true;
                }
            }

        }


        for (ResultRecortModelDto model:dto.getRecortModelDtos()
             ) {
            int index = 0;
            BigDecimal weight = BigDecimal.ZERO;
            /*if(model.getMaxCount() != null && model.getDetailDtos().size() > model.getMaxCount().intValue()){
                return R.error(model.getName() + "维度指标数量不能超过" + model.getMaxCount());
            }*/

            for (ResultDetailDto detailDto:model.getDetailDtos()
                 ) {//排序
                ResultDetail resultDetail = new ResultDetail();
                BeanUtils.copyProperties(detailDto, resultDetail);
                if(!isSetKeyResult){
                    if(resultDetail.getIsDelete() != null && resultDetail.getIsDelete().intValue() == 1){//被删除了
                        log.info("指标被删除了");
                        resultDetail.setIsBack(2);
                        resultDetail.setBackId(resultDetail.getId());
                        updateResultDetails.add(resultDetail);
                        editResultDetails.add(resultDetail);
                    }else if(resultDetail.getId() == null){
                        resultDetail.setIsBack(3);//新增
                        editResultDetails.add(resultDetail);//插入数据库之后会生成id
                        log.info("新增指标");
                    }else {
                        if(resultDetail.getId() != null && mapDetails.containsKey(resultDetail.getId())){
                            //这里判断是否有更新，或者删除
                            boolean isUp = false;
                            ResultDetail resultDetail1 = null;
                            resultDetail1 = mapDetails.get(resultDetail.getId());


                            if(!resultDetail.getTarget().equals(resultDetail1.getTarget())){
                                //打上标识
                                log.info("修改名称");
                                isUp = true;
                            }
                            if(!resultDetail.getKeyResult().equals(resultDetail1.getKeyResult())){
                                //打上标识
                                log.info("修改关键结果");
                                isUp = true;
                            }

                            if(!resultDetail.getCheckWeight().equals(resultDetail1.getCheckWeight())){
                                //打上标识
                                log.info("修改权重");
                                isUp = true;
                            }
                            if(isUp){
                                resultDetail1.setId(null);
                                resultDetail1.setIsBack(2);
                                resultDetail1.setBackId(resultDetail.getId());
                                inserts.add(resultDetail1);
                                editResultDetails.add(resultDetail1);//插入数据库之后会生成id
                            }
                        }
                    }
                }


                resultDetail.setPriority(index);

                index++;
                if(resultDetail.getId() != null){
                    updates.add(resultDetail);


                }else{
                    resultDetail.setStaffId(resultRecord.getStaffId());
                    resultDetail.setRecordId(resultRecord.getId());
                    resultDetail.setType(model.getType());
                    resultDetail.setModelId(model.getId());
                    resultDetailService.insertResultDetail(resultDetail);

                    //inserts.add(resultDetail);
                }
                if(resultDetail.getIsDelete() != null && resultDetail.getIsDelete().intValue() == 1){
                    //删除任务
                    resultTaskService.deleteResultTasksByDetailId(resultDetail.getId());
                }else{
                    //更新任务
                    if(detailDto.getTaskDtos() != null && detailDto.getTaskDtos().size() > 0){
                        log.info("任务个数{}", detailDto.getTaskDtos().size());
                        int orderBy = 0;
                        for (ResultTaskDto taskDto:detailDto.getTaskDtos()
                        ) {
                            if(taskDto.getId() != null && taskDto.getIsDelete() != null && taskDto.getIsDelete().intValue() == 1){
                                //删除
                                resultTaskService.deleteTask(taskDto.getId(),userId);
                            }else{
                                ResultUpdateTaskReq taskReq = new ResultUpdateTaskReq();
                                taskReq.setDetailId(resultDetail.getId());
                                taskReq.setTaskId(taskDto.getId());
                                taskReq.setName(taskDto.getName());
                                taskReq.setOrderBy(orderBy);
                                taskReq.setProcessRate(BigDecimal.valueOf(taskDto.getProcessRate()));
                                resultTaskService.saveOrUpdateResultTask(taskReq,userId);
                                orderBy++;
                            }

                        }

                    }
               // }
                //if(resultDetail.getIsDelete() == null || resultDetail.getIsDelete().intValue() == 0){
                    BigDecimal score = BigDecimal.ZERO;
                    if(detailDto.getScoreDtos() != null){
                        for (ResultScoreDto scoreDto:detailDto.getScoreDtos()
                        ) {
                            //计算得分
                            ResultScore resultScore = new ResultScore();
                            BeanUtils.copyProperties(scoreDto, resultScore);
                            if(scoreDto.getAcquireScore() != null){
                                score = score.add(scoreDto.getAcquireScore().multiply(scoreDto.getWeight()));
                            }
                            if(resultScore.getId() == null){
                                insertScores.add(resultScore);
                            }else{
                                updateScores.add(resultScore);
                            }
                            resultScore.setDetailId(detailDto.getId());
                        }
                        resultDetail.setAcquireScore(score);
                        weight = weight.add(resultDetail.getCheckWeight());
                    }
                }

            }
        }
        //下面更新指标记录
        if(inserts.size() > 0){
            resultDetailService.saveBatch(inserts);
        }
        if(updates.size() > 0){
            resultDetailService.updateBatchById(updates);
        }

        //下面更新评分记录
        if(insertScores.size() > 0){
            resultScoreService.saveBatch(insertScores);
        }
        if(updateScores.size() > 0){
            resultScoreService.updateBatchById(updateScores);
        }

        resultRecordService.updateResultRecordById(resultRecord);

        if(dto.getCommentId() != null && dto.getCommentId().intValue() > 0){
            //修改评论信息
            log.info("修改了多少个指标{}", editResultDetails.size());
            editResultDetails.addAll(resultDetailService.selectNotNoticeResultDetailByRecordId(dto.getId())) ;
            log.info("可能需要写入评论的内容条数{}", editResultDetails.size());
            //去重
            mapDetails = editResultDetails.stream().collect(Collectors.toMap(ResultDetail::getId, Function.identity(), (e, r) -> e));
            editResultDetails = mapDetails.values().stream().collect(Collectors.toList());
            if(!isSetKeyResult){
                log.info("实际需要写入评论的内容条数{}", editResultDetails.size());
                if(editResultDetails.size() > 0){
                    updates.addAll(inserts);

                    mapDetails = updates.stream().collect(Collectors.toMap(ResultDetail::getId, Function.identity(), (e, r) -> e));

                    String commandValue = "";
                    int commandIndex = 1;
                    for (ResultDetail resultDetail1:editResultDetails
                    ) {
                        log.info("修改的对象为{}", resultDetail1);
                        if(resultDetail1.getIsDelete() != null && resultDetail1.getIsDelete().intValue() == 1){
                            commandValue += (commandIndex + "：(删除) 指标" + resultDetail1.getTarget() + "\n");
                            commandIndex++;
                            resultDetail1.setIsBack(1);
                        }else if(resultDetail1.getIsBack().intValue() == 3){
                            commandValue += (commandIndex + "：(新增) 指标" + resultDetail1.getTarget() + "\n");
                            commandIndex++;
                            resultDetail1.setIsBack(0);
                        }else{

                            ResultDetail resultDetail = mapDetails.get(resultDetail1.getBackId());
                            if(resultDetail != null){
                                log.info("修改后的对象为{}", resultDetail1);
                                boolean isUp = false;
                                String value = "";
                                String heard = "";
                                if(!resultDetail.getTarget().equals(resultDetail1.getTarget())){
                                    //打上标识
                                    value += ("(修改) 名称：" +
                                            resultDetail1.getTarget()+ " \n(为)：\n" + resultDetail.getTarget() + "\n");
                                    isUp = true;

                                }else{
                                    heard = "指标：" + resultDetail1.getTarget() + "\n";
                                }
                                if(!resultDetail.getKeyResult().equals(resultDetail1.getKeyResult())){
                                    //打上标识
                                    value += ("(修改) 考核标准：" +
                                            resultDetail1.getKeyResult() + "\n(为)：\n" + resultDetail.getKeyResult() + "\n");
                                    isUp = true;
                                }
                                if(!resultDetail.getCheckWeight().equals(resultDetail1.getCheckWeight())){
                                    //打上标识
                                    value += ("(修改) 权重：" +
                                            resultDetail1.getCheckWeight().multiply(new BigDecimal(100)).intValue() + "%\n(为)：\n"
                                            + resultDetail.getCheckWeight().multiply(new BigDecimal(100)).intValue() +
                                            "%\n");
                                    isUp = true;
                                }
                                if(isUp){
                                    commandValue += (commandIndex + "：" + heard + value);
                                    commandIndex++;
                                    resultDetail1.setIsBack(1);
                                }
                            }

                        }
                    }
                    if(commandValue.length() > 0){
                        log.info("需要写入评论，具体呢容为{}", commandValue);
                        ResultComment resultComment = resultCommentService.selectResultCommentById(dto.getCommentId());
                        log.info("resultComment的值{}", resultComment);
                        if(resultComment.getOptDesc().indexOf("制定了目标") >= 0){
                            resultComment.setOptDesc("修改了目标");
                            resultComment.setComment(commandValue);
                        }else{
                            resultComment.setOptDesc("修改了目标-" + resultComment.getOptDesc());

                            resultComment.setComment((resultComment.getComment() == null ? "" : (resultComment.getComment() + "\n")) + commandValue);
                        }
                        resultCommentService.updateResultCommentById(resultComment);//.updateResultCommentCommentById(dto.getCommentId(), commandValue);
                    }
                }
            }else{
                for (ResultDetail resultDetail1:editResultDetails
                ) {
                    if(resultDetail1.getIsBack().intValue() == 3){
                        resultDetail1.setIsBack(0);
                    }else{
                        resultDetail1.setIsBack(1);
                    }
                }
            }
            resultDetailService.updateBatchById(editResultDetails);
        }

        return R.ok();
    }

    /**
     * 信息
     */
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id) {
        ResultDetail detail = resultDetailService.selectResultDetailById(id);
        return R.ok().put("detailInfo", detail);
    }

    /**
     * 信息
     */
    @RequestMapping("/getResultComment/{recordId}")
    public R getResultComment(@PathVariable("recordId") Long recordId) {
        ResultComment resultComment = resultCommentService.selectLastComment(recordId);
        FlowRecord flowRecordLast = flowRecordService.selectLastFlowRecordByRecordId(recordId);
        if (resultComment ==null || !resultComment.getFlowRecordId().equals(flowRecordLast.getId())) {
            resultComment = new ResultComment();
        }

        List<FlowRecord> flowRecords = flowRecordService.selectFlowRecordByResultRecordIdFlowId(recordId);
        if (flowRecords != null && flowRecords.size() > 0) {
            FlowRecord flowRecord = flowRecords.get(flowRecords.size()-1);
            if(flowRecord.getApprovalStaffId().equals(getUserId())){
                flowRecords.remove(flowRecord);
            }
        }
        return R.ok().put("resultComment", resultComment)
                .put("list", flowRecords);
    }

    /**
     * 信息
     */
    @RequestMapping("/recorddetailDelete/{id}")
    public R recorddetailDelete(@PathVariable("id") Long id) {
        resultDetailService.deleteResultDetailById(id);
        return R.ok("删除成功");
    }

    /**lzresultrecord/saveDetail
     * 信息
     */
    @RequestMapping("/recordIdsSubmit")
    public R recordIdsSubmit(String recordIds,Integer batchOpt) {
        if (StringUtil.isBlank(recordIds)) {
            return R.error("请勾选需要批量操作业绩！");
        }
        List<Long> records = new ArrayList<>();
        String ids[] = recordIds.split(",");
        if (ids != null && ids.length > 0) {
            for (String id : ids) {
                if (StringUtil.isNotBlank(id)) {
                    records.add(NumberUtil.objToLongDefault(id, 0));
                }
            }
        }
        R r = null;
        List<ResultRecord> resultRecords = resultRecordService.selectResultRecordByIds(records);
        if(batchOpt == 1){                          //提交审批
            for (ResultRecord resultRecord : resultRecords) {
                if (!StringUtil.in(resultRecord.getStatus(),1,2,3,5)) {
                    return R.error("您的提交记录中有状态不正确，请重新选择");
                }
            }
            for (ResultRecord resultRecord : resultRecords) {
                r = resultRecordService.approval(resultRecord.getId(), resultRecord.getCurrentApprovalStaffId(),null,false);
                if (!r.isSuccess()) {
                    return r;
                }
            }
        } else if (batchOpt == 2) {                                //终止流程
            for (ResultRecord resultRecord : resultRecords) {
                if (!StringUtil.in(resultRecord.getStatus(),1,2,3,5,6)) {
                    return R.error("您的提交记录中有状态不正确，请重新选择");
                }
            }
            for (ResultRecord resultRecord : resultRecords) {
                r = resultRecordService.approval(resultRecord.getId(), resultRecord.getCurrentApprovalStaffId(), 7, true);
                if (!r.isSuccess()) {
                    return r;
                }
            }
        } else if (batchOpt == 3 || batchOpt == 4 ) {   // 3 申述无效,直接驳回 ,4 领导重新打分
            for (ResultRecord resultRecord : resultRecords) {
                if (!StringUtil.in(resultRecord.getStatus(),6)) {
                    return R.error("您的提交记录中有状态不正确，请重新选择");
                }
            }
            if(batchOpt == 3 ){
                for (ResultRecord resultRecord : resultRecords) {
                    r = resultRecordService.approval(resultRecord.getId(), resultRecord.getCurrentApprovalStaffId(),null,false);
                    if (!r.isSuccess()) {
                        return r;
                    }
                }
            } else if(batchOpt == 4 ){
                for (ResultRecord resultRecord : resultRecords) {
                    List<FlowRecord> list = flowRecordService.selectFlowRecordByResultRecordIdType(resultRecord.getId(), 2);
                    for (int i = list.size() - 1; i >= 0; i--) {
                        FlowRecord flowRecord = list.get(i);
                        Long roleId = recordAuthService.getRoleIdByStaffRoleInfo(flowRecord.getFlowStaffIdRole(), flowRecord.getApprovalStaffId());
                        List<RecordAuth> listAuth = recordAuthService.selectAuthInfo(roleId);
                        Auth auth = recordAuthService.getAuth(listAuth);
                        if (auth.getEditScore() > 0) {//表示是评分
                            resultRecord.setFlowStaffIdRole(flowRecord.getFlowStaffIdRole());
                            resultRecord.setCurrentApprovalStaffId(flowRecord.getApprovalStaffId());
                            resultRecord.setCurrentApprovalStaffName(flowRecord.getApprovalStaffName());
                            resultRecord.setStatus(1);
                            // 直接还原权限
                            resultRecordService.updateResultRecordById(resultRecord);
                            break;
                        } else {
                            flowRecord.setStatus(1);//如果不是领导打分的话，直接删除掉
                            flowRecordService.updateFlowRecordById(flowRecord);
                        }
                    }
                }
            }
        }
        if (r != null && r.isSuccess()) {//批量提交
            StaffEntity mySelf = (StaffEntity) r.get("from");
            StaffEntity toSelf = (StaffEntity) r.get("to");
            WorkMsgTypeEnum workMsgTypeEnum = (WorkMsgTypeEnum) r.get("type");
            resultRecordService.sendWorkMSG(mySelf, toSelf, workMsgTypeEnum, 0L, 2);
        }

        return R.ok("批量提交成功");
    }

    /**
     * 信息
     */
    @RequestMapping("/weightCheck")
    public R weightCheck(ResultRecordReq req) {
        List<ResultDetail> resultDetails = resultDetailService.selectByRecordIdType(req.getRecordResultId(), req.getType());
        double compare = 0.3; //如果类型是文化价值观
        if (req.getType() == 1) { //类型是业绩
            compare = 0.7;
        }
        if (CollectionUtils.isEmpty(resultDetails)) {
            if (req.getId() > 0) { // 编辑验证
                if (req.getWeight().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() > compare) {
                    return R.error("权重不能大于" + compare);
                }
            } else { // 添加验证
                if (req.getWeight().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() > compare) {
                    return R.error("权重不能大于" + compare);
                }
            }
        } else {
            double sum = resultDetails.stream()
                    .filter(p -> !p.getId().equals(req.getId()))
                    .mapToDouble(n -> NumberUtil.objToDoubleWithDefault(n.getCheckWeight(), 0d)).summaryStatistics().getSum();
            if (req.getId() > 0) { //编辑验证
                if (new BigDecimal(sum).add(req.getWeight()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() > compare) {
                    return R.error("权重之和不能大于" + compare);
                }
            } else { //添加验证
                if (new BigDecimal(sum).add(req.getWeight()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() > compare) {
                    return R.error("权重之和不能大于" + compare);
                }
            }
        }
        return R.ok("验证成功");
    }

    /**
     * 信息
     */
    @RequestMapping("/preWeightCheck")
    public R preWeightCheck(ResultRecordReq req) {
        List<ResultDetail> resultDetails = resultDetailService.selectByRecordIdType(req.getRecordResultId(), req.getType());
        double compare = 0.3; //如果类型是文化价值观
        if (req.getType() == 1) { //类型是业绩
            compare = 0.7;
        }
        if (CollectionUtils.isEmpty(resultDetails)) {
            if (req.getId() > 0) { // 编辑验证
                if (req.getWeight().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() > compare) {
                    return R.error("权重不能大于" + compare);
                }
            } else { // 添加验证
                if (req.getWeight().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() >= compare) {
                    return R.error("权重不能大于" + compare);
                }
            }
        } else {
            double sum = resultDetails.stream()
                    .filter(p -> !p.getId().equals(req.getId()))
                    .mapToDouble(n -> NumberUtil.objToDoubleWithDefault(n.getCheckWeight(), 0d)).summaryStatistics().getSum();
            if (req.getId() > 0) { //编辑验证
                if (new BigDecimal(sum).add(req.getWeight()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() > compare) {
                    return R.error("权重之和不能大于" + compare);
                }
            } else { //添加验证
                if (new BigDecimal(sum).add(req.getWeight()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() >= compare) {
                    return R.error("权重之和不能大于" + compare);
                }
            }
        }
        return R.ok("验证成功");
    }

    /**
     * 信息
     */
    @RequestMapping("/detailAddOrUpdate")
    public R detailAddOrUpdate(ResultDetailReq req) {
        ResultRecord resultRecord = resultRecordService.selectResultRecordById(req.getRecordId());
        req.setKeyResult(StringUtil.decodeBase64(req.getKeyResult()));
        req.setKeyResult35(StringUtil.decodeBase64(req.getKeyResult35()));
        req.setKeyResult37(StringUtil.decodeBase64(req.getKeyResult37()));
        req.setCheckResult(StringUtil.decodeBase64(req.getCheckResult()));
        req.setScoreComment(StringUtil.decodeBase64(req.getScoreComment()));
        ResultDetail old = resultDetailService.selectResultDetailById(req.getId());
        if (old != null) {
            com.lz.modules.app.utils.BeanUtils.copyProperty(old, req, false);
            if(old.getType().equals(2)){
                old.setTarget(Constant.WENHUAJIAZHIGUAN);
            }
            resultDetailService.updateResultDetailById(old);
        } else {
            ResultDetail resultDetail = new ResultDetail();
            BeanUtils.copyProperties(req, resultDetail);
            resultDetail.setRecordId(resultRecord.getId());
            resultDetail.setStaffId(resultRecord.getStaffId());
            if(req.getType().equals(2)){
                resultDetail.setTarget(Constant.WENHUAJIAZHIGUAN);
            }
            resultDetailService.insertResultDetail(resultDetail);
        }
        List<ResultDetail> resultDetails = resultDetailService.selectByRecordId(resultRecord.getId());
        if (CollectionUtils.isNotEmpty(resultDetails)) {
            BigDecimal sum = BigDecimal.ZERO;
            for (ResultDetail resultDetail : resultDetails) {
                BigDecimal checkWeight = NumberUtil.objToBigDecimalDefault(resultDetail.getCheckWeight(), BigDecimal.ZERO);
                BigDecimal acquireScore = NumberUtil.objToBigDecimalDefault(resultDetail.getAcquireScore(), BigDecimal.ZERO);
                sum = sum.add(checkWeight.multiply(acquireScore));
            }
            sum = BigDecimalUtil.setScale(sum, 3);
            String scoreLevel = resultDetailService.getScoreLevel(sum.doubleValue());
            resultRecord.setLastScore(sum);
            resultRecord.setAllScore(sum);
            resultRecord.setScoreLevel(scoreLevel);
            resultRecordService.updateResultRecordById(resultRecord);
        }
        return R.ok("保存成功").put("recordId", resultRecord.getId());
    }
    /**
     * 保存
     */
    @RequestMapping("/save")
    @RequiresPermissions("user:lzresultrecord:save")
    public R save(@RequestBody ResultRecord lzResultRecord) {
        lzResultRecordService.insertResultRecord(lzResultRecord);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("user:lzresultrecord:update")
    public R update(@RequestBody ResultRecord lzResultRecord) {
        lzResultRecordService.updateResultRecordById(lzResultRecord);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/deleteRecord")
    @RequiresPermissions("user:lzresultrecord:delete")
    public R deleteRecord(String ids) {
        if(StringUtil.isBlank(ids)){
            return R.error("请选择 ids");
        }
        String is[] = ids.split(",");
        for(String i : is ){
            ResultRecord resultRecord = resultRecordService.selectResultRecordById(NumberUtil.objToLongDefault(i,0l));
            if(resultRecord !=null){
                resultRecord.setIsDelete(1);
                resultRecordService.updateResultRecordById(resultRecord);
            }
        }
        return R.ok();
    }



    /**
     * 删除
     */
    @RequestMapping("/addRecordAjudex")
    public R addRecordAjudex(String type) {
        ResultRecord resultRecord = resultRecordService.selectCurrentMonthResultRecordByStaffIdType(getUserId(),NumberUtil.objToIntDefault(type,2));
        if(resultRecord !=null){
            return R.error("当月己经存在绩效，请编辑。");
        }
        return  R.ok();
    }



    /**
     * 删除
     */
    @RequestMapping("/getUploadFileList")
    public R getUploadFileList(ResultDetailReq req) {
        PageUtils page = recordFileService.queryPage(req, getUser());
        return R.ok()
                .put("page", page);
    }

    /**
     * 删除
     */
    @RequestMapping("/deleteFile")
    public R deleteFile(ResultDetailReq req) {
        RecordFile recordFile = recordFileService.selectRecordFileById(req.getId());
        recordFile.setIsDelete(1);
        recordFileService.updateRecordFileById(recordFile);
        return R.ok();
    }


    /**
     * 删除
     */
    // 审批：http://localhost:8080/lz_management/user/lzresultrecord/new/approval?resultRecordId=215&status=1&comment=xxx&menuName=bbb
    // 跳过：http://localhost:8080/lz_management/user/lzresultrecord/new/approval?resultRecordId=215&status=4&menuName=bbb&flowRecordId=360
    // 转交：http://localhost:8080/lz_management/user/lzresultrecord/new/approval?resultRecordId=215&status=8&menuName=bbb&flowRecordId=360&transferStaffId=294

    // 重置：http://localhost:8080/lz_management/user/lzresultrecord/new/approval?resultRecordId=3702&status=9&menuName=cccc&flowRecordId=33987&resetFlag=0
    @RequestMapping("/new/approval")
    public R approval(ApprovalDto approvalDto) {
        try {
            if (getUser() != null) {
                approvalDto.setLoginUserId(getUserId());
            }
            return resultRecordService.newApproval(approvalDto);
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    /**
     * 删除
     */
    // http://localhost:8080/lz_management/user/lzresultrecord/new/resultRecordDetail?resultRecordId=593&loginUserId=322
    @RequestMapping("/new/resultRecordDetail")
    public R newResultRecordList(RecordDetailDto recordDetailDto) {
        if(recordDetailDto.getLoginUserId() ==null && getUser() !=null ){
            recordDetailDto.setLoginUserId(getUserId());
        }
        return resultRecordService.newResultRecordList(recordDetailDto);

    }





    // http://localhost:8080/lz_management/user/lzresultrecord/get/reset/data?resultRecordId=593&loginUserId=322
    @RequestMapping("/get/reset/data")
    public R getResetData(RecordDetailDto recordDetailDto) {
        if(recordDetailDto.getLoginUserId() ==null && getUser() !=null ){
            recordDetailDto.setLoginUserId(getUserId());
        }
        return resultRecordService.getResetData(recordDetailDto);
    }





    @ApiOperation("导出绩效详情报表")
    @GetMapping("/recordDetailExport")
    @ApiResponses({@ApiResponse(code = 200,message = "成功",response = ResultRecordDetailDto.class)})
    public R recordDetailExport(Long recordId){
        Map map = Maps.newHashMap();
        map.put("id",recordId);
        return getDetail(map);
    }


    @ApiOperation("保存绩效详情报表计划")
    @PostMapping("/recordDetailExplan")
    @ApiResponses({@ApiResponse(code = 200,message = "成功")})
    public R recordDetailExport(@RequestBody List<RecordDetailExplanReq> reqs){
        if(CollectionUtils.isEmpty(reqs)){
            return R.error("添加数据为空");
        }
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String time = dtf.format(now);
        List<Print> prints = Lists.newArrayList();
        int i =1;
        Resource resource = resourceService.selectResourceByTypeAndSecType(TYPE, SEC_TYPE);
        for(RecordDetailExplanReq recordDetailExplanReq:reqs){
            Print print = new Print();
            BeanUtils.copyProperties(recordDetailExplanReq,print);
            print.setBatchNo(time + "_" + recordDetailExplanReq.getRecordId() + "_" + i++);
            Optional.ofNullable(resource).ifPresent(resource1 -> print.setUrl(resource1.getValue()));
            prints.add(print);
        }

        if(!printService.saveBatch(prints)){
            return R.error("保存失败");
        }

        return R.ok();
    }








}
