package com.goafanti.weChat.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.goafanti.admin.bo.AdminListBo;
import com.goafanti.admin.bo.AdminPublicReviewerBo;
import com.goafanti.admin.service.DepartmentService;
import com.goafanti.business.bo.InputRestrictProject;
import com.goafanti.common.bo.EmailBo;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.*;
import com.goafanti.common.enums.NoticeStatus;
import com.goafanti.common.error.BusinessException;
import com.goafanti.common.model.*;
import com.goafanti.common.utils.*;
import com.goafanti.common.utils.weChat.WeChatUtils;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.shiro.token.TokenManager;
import com.goafanti.core.websocket.SystemWebSocketHandler;
import com.goafanti.customer.bo.FollowBusinessBo;
import com.goafanti.customer.service.CustomerService;
import com.goafanti.order.bo.TOrderNewBo;
import com.goafanti.order.service.OrderNewService;
import com.goafanti.weChat.bo.*;
import com.goafanti.weChat.service.PublicReleaseService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.socket.TextMessage;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Service
public class PublicReleaseServiceImpl extends BaseMybatisDao<PublicReleaseMapper> implements PublicReleaseService {
	@Autowired
	private PublicReleaseMapper	publicReleaseMapper;
	@Autowired
	private PublicReleaseLogMapper publicReleaseLogMapper;
	@Autowired
	private CustomerService customerService;
	@Autowired
	private PublicReleaseDetailsMapper publicReleaseDetailsMapper;
	@Autowired
	private WeChatUtils weChatUtils;
	@Autowired
	private AdminMapper adminMapper;
	@Autowired
	private	AsyncUtils asyncUtils;
	@Autowired
	private	UserMapper	userMapper;
	@Autowired
	private OrganizationContactBookMapper	organizationContactBookMapper;
	@Autowired
	private SystemWebSocketHandler	systemWebSocketHandler;
	@Autowired
	private TOrderNewMapper tOrderNewMapper;
	@Autowired
	private DepartmentService	departmentService;
	@Autowired
	private PublicExamineMapper publicExamineMapper;
	@Autowired
	private AdminUserCountMapper adminUserCountMapper;
	@Autowired
	private PublicReleaseClockMapper publicReleaseClockMapper;
	@Autowired
	private PublicReleaseDateClockMapper publicReleaseDateClockMapper;
	@Autowired
	private TOrderPublicReleaseCountMapper tOrderPublicReleaseCountMapper;

	@Autowired
	private RestrictProjectMapper restrictProjectMapper;
	@Autowired
	private OrderYearMaxDurationMapper orderYearMaxDurationMapper;
	@Autowired
	private TTaskMemberMapper tTaskMemberMapper;
	@Autowired
	private OrderNewService orderNewService;
	@Autowired
	private AdminPublicReviewerMapper adminPublicReviewerMapper;
	@Autowired
	private PublicAssistAdviceMapper publicAssistAdviceMapper;
	@Autowired
	private UserLimitCheckMapper userLimitCheckMapper;
	@Autowired
	private UserArchivesMapper userArchivesMapper;
	@Autowired
	private OrganizationIdentityMapper organizationIdentityMapper;
	@Autowired
	private UserSuperEvaluateMapper userSuperEvaluateMapper;
	@Autowired
	private OrderPublicReleaseLogMapper orderPublicReleaseLogMapper;
	@Autowired
	private PublicConfigMapper publicConfigMapper;
	@Autowired
	private UserFirstInterviewMapper userFirstInterviewMapper;
	@Autowired
	private UserArchivesInterviewMapper userArchivesInterviewMapper;
	@Autowired
	private UserInterviewProjectMapper userInterviewProjectMapper;

	@Override
	@Transactional
	public Map<String, Object> addPublicRelease(InputPublicRelease in) {
		Date date =new Date();
		if (in.getPublicAgain()==null)in.setPublicAgain(0);
		in.setCreateTime(date);
		in.setPublicType(0);
		in.setTechStartProcess(0);
		in.setStatus(1);
		AdminListBo my = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
		Map checkOrderNo =null;
		List<PublicReleaseDetails> prdList=new ArrayList<>();
		List<User> users=new ArrayList<>();
		StringBuilder str =new StringBuilder();
		//判定是单独协单还是一起协单
		in.setAid(TokenManager.getAdminId());
		in.setAname(my.getName());
		if (in.getAssist()==1){
//			in.setAssistAidName(getAssistAidName(in.getAssistAid()));
			in.setMainName(my.getName());
			in.setAssistProcess(1);
		}
		if (in.getType() == 1) {
			//技术公出
			checkOrderNo = checkOrderNoDuration(in,my,1);
			boolean isValid = (boolean) checkOrderNo.get("code");
			if (isValid){
				in.setTechStartProcess(0);
			}else {
				in.setTechStartProcess(1);
			}
		}
		in.setProcessStatus(1);
		publicReleaseMapper.insertSelective(in);
		if (in.getType()==1&&in.getOrderNo()!=null){
			TOrderNew tOrderNew = tOrderNewMapper.queryById(in.getOrderNo());
			orderNewService.pushOrderPublicReleaseCount(tOrderNew);
		}
		addPRD(in, users, str, prdList);
		addPublicReleaseDateClock(in);
		if (in.getType()==0&&in.getUids()!=null){
			pushUserArchivesInterview(in);
		}
		String userNames=str.substring(0,str.length()-1);
		in.setUserNames(userNames);
		PublicRelease updateName=new PublicRelease();
		updateName.setId(in.getId());
		updateName.setUserNames(userNames);
		publicReleaseMapper.update(updateName);
		addpublicLog(in.getId(), PublicReleaseLog.states.fq.getCode(), "发起外出申请");
		//公出信息抄送
		pushPublicCarbonCopy(in, my, userNames);
		//协单抄送
		if (in.getAssist()==1){
			pushPublicAssistCarbonCopy(in, my, userNames);

		}
		return (Map<String, Object>) addPublicReleaseLog(my, in,userNames,date,users,checkOrderNo);
	}

	private void pushPublicAssistCarbonCopy(InputPublicRelease in, AdminListBo my, String userNames) {
		String[] split = in.getAssistAid().split(",");
		for (String aid2 : split) {
			AdminListBo my2 = adminMapper.getDeptNameByAid(aid2);
			PublicRelease p=new PublicRelease();
			p.setId(in.getId());
			p.setAid(aid2);
			p.setAname(my2.getName());
			p.setReleaseStart(in.getReleaseStart());
			p.setReleaseEnd(in.getReleaseEnd());
			p.setPlan(in.getPlan());
			p.setType(3);
			pushPublicCarbonCopy(p, my2, userNames);
		}
	}


	private void pushUserArchivesInterview(InputPublicRelease in) {
		if (in.getUids()!=null){
			String[] split1 = in.getUais().split(",");
			if (split1.length>0&&StringUtils.isNotBlank(split1[0])){
				List<UserArchivesInterview> userArchivesInterviews = userArchivesInterviewMapper.selectByIds(split1);
				List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(in.getId());
				//根据不同客户，绑定不同公出
				for (OutPublicReleaseDetails e : outPublicReleaseDetails) {
					for (UserArchivesInterview uai : userArchivesInterviews) {
						if (e.getUid().equals(uai.getUid())){
							uai.setPrdid(e.getId());
							userArchivesInterviewMapper.update(uai);
						}
					}
					//根据客户判定出来本次公出，如果有则标记有效
					List<UserInterviewProjectBo> userInterviewProjectBos = userInterviewProjectMapper.selectByAid(null, e.getUid());
					List<UserInterviewProjectBo> collect = userInterviewProjectBos.stream().filter(e2 -> e2.getType() == 0&&e2.getStatus()==0).collect(Collectors.toList());
					if (!collect.isEmpty()){
						OutPublicReleaseDetails newPRD=new OutPublicReleaseDetails();
						newPRD.setId(e.getId());
						newPRD.setInterviewStatus(1);
						publicReleaseDetailsMapper.update(newPRD);
						//需要添加首次面谈表
						UserFirstInterview userFirstInterview=new UserFirstInterview();
						userFirstInterview.setUid(e.getUid());
						userFirstInterview.setAid(TokenManager.getAdminId());
						userFirstInterview.setPrdid(e.getId());
						userFirstInterview.setFirstTime(in.getReleaseStart());
						userFirstInterviewMapper.insert(userFirstInterview);
						//将首次面谈项目状态改为非本次项目并添加绑定的公出详情
						for (UserInterviewProjectBo userInterviewProjectBo : collect) {
							UserInterviewProject userInterviewProject=new UserInterviewProject();
							userInterviewProject.setId(userInterviewProjectBo.getId());
							userInterviewProject.setPrdid(e.getId());
							userInterviewProject.setType(1);
							userInterviewProjectMapper.update(userInterviewProject);
						}
					}

				}

			}
		}

	}

	private void addPRD(InputPublicRelease in, List<User> users, StringBuilder str, List<PublicReleaseDetails> prdList) {

		if (in.getUids()!=null){
			List<String> split = Arrays.asList(in.getUids().split(","));
			int userCount=split.size();
			Double duration = in.getDuration();
			//计算平均
			double d = durationSum(duration, userCount);
			int index=1;
			//获取非已企业公出需要的审核人员
			for (String s : split) {
				PublicReleaseDetails prd=new PublicReleaseDetails();
				User u=userMapper.queryById(s);
					users.add(u);
				str.append(u.getNickname()).append(",");
				if (u!=null&&u.getShareType()==2){
					prd.setNewUser(1);
				}else {
					prd.setNewUser(0);
				}
				if (u.getAid().equals(in.getAid())){
					prd.setMainStatus(1);
				}else {
					prd.setMainStatus(0);
				}
				prd.setPrid(in.getId());
				prd.setUid(s);
				prd.setSignSum(0);
				prd.setClockIn(0);
				prd.setDistrictName(in.getDistrictName());
				prd.setLatitude(in.getLatitude());
				prd.setLongitude(in.getLongitude());
				prd.setAddressName(in.getAddressName());
				if (index<userCount){
					if (duration==0){
						prd.setDuration(duration);
					} else {
						prd.setDuration(d);
						duration=duration-d;
					}
					index++;
				}else {
					prd.setDuration(duration);
				}
				prdList.add(prd);
			}
			publicReleaseDetailsMapper.insertBatch(prdList);
		}
	}
	private void pushPublicCarbonCopy(PublicRelease p, AdminListBo my, String userNames) {
		List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(my.getId())
				.stream().filter(e -> e.getType() == 3).collect(Collectors.toList());
		if (adminPublicReviewerBos.size()>0){
			for (AdminPublicReviewerBo e : adminPublicReviewerBos) {
				//公出信息
				if (StringUtils.isNotEmpty(e.getReviewerId())){
					String startTime = DateUtils.formatDateChineseYYYYMMddHH(p.getReleaseStart());
					String endTime = DateUtils.formatDateChineseYYYYMMddHH(p.getReleaseEnd());
					//分类 0业务 1技术 2行政 3 技术协单 4 技术助手
					String typeName=null;
					if(p.getType()==0)typeName="业务公出";
					else if(p.getType()==1)typeName="技术公出";
					else if(p.getType()==2)typeName="行政公出";
					else if(p.getType()==3)typeName="技术协单";
					String str=String.format("%s，%s - %s，将公出%s，请知悉！", my.getName(),
							startTime,
							endTime,
							userNames);
					String str2=String.format("协单%s，请知悉！",
							userNames);
					asyncUtils.addNoticAndEmail(NoticeStatus.PUBLIC_CARBON_COPY.getCode(), e.getReviewerId()
							,str);
					asyncUtils.sendCarbonCopyWeChat(e.getReviewerId(), p.getId(),
							my.getName(), startTime,
							endTime,
							typeName,
							str2);
				}

			}
		}



	}

	private void pushPublicCarbonCopy(InputPublicRelease in, AdminListBo my, String userNames) {
		PublicRelease p=new PublicRelease();
		p.setId(in.getId());
		p.setAid(in.getAid());
		p.setAname(in.getAname());
		p.setReleaseStart(in.getReleaseStart());
		p.setReleaseEnd(in.getReleaseEnd());
		p.setPlan(in.getPlan());
		p.setType(in.getType());
		pushPublicCarbonCopy(p, my, userNames);
	}


	private void addPublicExamine(Integer id, String aid) {
		Admin admin = adminMapper.selectById(aid);
		addPublicExamine(id,admin);
	}

	private void addPublicExamine(Integer id, Admin a) {
		List<PublicExamine> publicExamines = publicExamineMapper.selectByPrid(id);
		boolean flag=false;
		for (PublicExamine pe : publicExamines) {
			if (pe.getAid().equals(a.getId())){
				flag=true;
			}
		}
		if (!flag){
			PublicExamine pe=new PublicExamine();
			pe.setPrid(id);
			pe.setAid(a.getId());
			pe.setAname(a.getName());
			pe.setStatus(0);
			publicExamineMapper.insertSelective(pe);
		}
	}


	private  double durationSum(Double duration, Integer sum) {
			Double counts= Math.floor(duration/0.5);
			//计算当前时间
			Double my=Math.floor(counts/sum)*0.5;
			if (my<0.5)return 0.5;
			return my;
	}



	/**
	 *
	 * @param my 我的相关人员
	 * @param in 公出信息
	 * @param nickname	客户名称
	 * @param date	时间
	 */
	private Map<String, Object> addPublicReleaseLog(AdminListBo my,PublicRelease in,String nickname,Date date,List<User> users,
													Map<String,Object>  checkOrderNo) {
			Map<String, Object>map=new HashMap<String, Object>();
			//无需订单负责人审核
		if (in.getTechStartProcess()==0){
//			Admin a=adminMapper.selectById(my.getReviewer());
			//订单审核换成多人
			List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(in.getAid());
			adminPublicReviewerBos=adminPublicReviewerBos.stream().filter(e -> e.getType() == 0).collect(Collectors.toList());
			String str="["+my.getName()+"]发起["+nickname+"]的外出申请,请及时审核。";
			//默认上级审核
			AtomicReference<Integer> status= new AtomicReference<>(1);
			String formatDate = DateUtils.formatDate(in.getCreateTime(), AFTConstants.YYYYMMDDHHMMSS);
			//业务公出
			if (in.getType()==0||in.getType()==2){
				//不是业务员
				if (my.getPublicPurview()==0){
                    for (User u : users) {
						//不是自己的客户
						if (!u.getAid().equals(my.getId())) {
							StringBuilder str2 = new StringBuilder();
							Admin admin = adminMapper.selectById(u.getAid());
							//业务公出限定项目直接公出，不是业务项目审核公出
							if(in.getType()==0){
									List<RestrictProject> list = restrictProjectMapper.selectListByParam(new InputRestrictProject(u.getId(), my.getId()));
									if (!list.isEmpty()){
										String start = DateUtils.formatDate(in.getReleaseStart(), AFTConstants.MMDDHHMM);
										String end = DateUtils.formatDate(in.getReleaseEnd(), AFTConstants.MMDDHHMM);
										str2.append("限定项目所属人营销员").append(my.getName()).append("于")
												.append(start).append("至").append(end).append("公出你的企业[").append(u.getNickname()).append("]请悉知！");
										sendEmailAndNoticeAndSoucket(u.getAid(), 3, str2.toString());
									}else {
										str2.append(my.getName()).append("(需审核)，准备公出您的企业")
												.append("[").append(u.getNickname()).append("]。");
										//添加审核
										addPublicExamine(in.getId(), admin);
										if (in.getPublicType() == null || in.getPublicType() == 0) in.setPublicType(1);
										//审核通知
										pushNoticeAndSoucketAndEmail(my, in, date, admin, str, map);
										status.set(0);
									}
									//行政公出通知
							}else if (in.getType()==2){
									str2.append(my.getName()).append("，准备[行政公出]您的企业")
											.append("[").append(u.getNickname()).append("]。");
									addPublicExamine(in.getId(), admin);
									//审核通知
									pushNoticeAndSoucketAndEmail(my, in, date, admin, str, map);

							}
						}



                    }
                }else {
					users.forEach(u->{
						if (!u.getAid().equals(my.getId())){
							addNoticeAndSoucket(my, u, formatDate);
						}
					});

				}
			} else if (in.getType()==1) {
				users.forEach(u->{
					if (!u.getAid().equals(my.getId())){
						addNoticeAndSoucket(my, u, formatDate);
					}
				});
			}
			if (status.get()==1){
				for (AdminPublicReviewerBo adminPublicReviewerBo : adminPublicReviewerBos) {
					Admin admin = adminMapper.selectById(adminPublicReviewerBo.getReviewerId());
					pushNoticeAndSoucketAndEmail(my, in, date, admin, str, map);
				}

			}
			publicReleaseMapper.update(in);
		}else {
			TOrderNew tOrderNew = tOrderNewMapper.queryById(in.getOrderNo());
			String salesmanId = tOrderNew.getSalesmanId();
			Admin a = adminMapper.selectById(salesmanId);
			addPublicExamine(in.getId(),a);
			CheckOrderNoOut data = (CheckOrderNoOut) checkOrderNo.get("data");
			String format = getString(my, data,tOrderNew);
			pushNoticeAndSoucketAndEmail(my, in, date, a, format, map);
		}
		OutPublicRelease outPublicRelease = publicReleaseMapper.selectDtails(in.getId());
		List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(outPublicRelease.getAid());
		StringBuffer sb=new StringBuffer();
		adminPublicReviewerBos.forEach(e->{
			if (e.getType()==0)sb.append(e.getReviewerName()).append("，");
		});
		if(sb.length()>0)outPublicRelease.setReviewerName(sb.toString());
		map.put("data", outPublicRelease);
		return map;
	}

	private void addNoticeAndSoucket(AdminListBo my, User u, String formatDate) {
		StringBuffer str2=new StringBuffer();
		str2=str2.append(my.getName()).append("计划公出您的企业").append(u.getNickname())
				.append(",").append(formatDate).append("【小程序端广播提示】");
		sendNoticeAndSoucket(u.getAid(),3,str2.toString());
	}

	private String getString(AdminListBo my, CheckOrderNoOut data,TOrderNew tOrderNew) {
		String amountName=data.getAmountName();
		String amountType=data.getAmountType();
		String format = String.format("%s准备公出%s（%s），" +
						"总计公出：%s人，%s次，%s时。%s，本次申请，%s。请确认是否同意本次公出？", my.getName(), data.getUserName(), data.getContractNo(),
				data.getPeopleCount(), data.getTimesCount(), data.getDurationCount().stripTrailingZeros().toPlainString(), amountName,
				amountType);
		return format;
	}

	/**
	 *
	 * @param my 发送人信息
	 * @param in 公出信息
	 * @param date 时间
	 * @param a  接受者信息
	 * @param str  站内信内容
	 * @param map 返回实体
	 */
	private void pushNoticeAndSoucketAndEmail(AdminListBo my, PublicRelease in, Date date, Admin a,  String str, Map<String, Object> map) {
		System.out.println("================================="+1);
		sendNoticeAndSoucket(a.getId(),1, str);
		if (a.getOpenId() !=null) {
			//间隔一秒发送
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
			Integer res= weChatUtils.addNotice(a.getOpenId(), in.getStatus(), in.getId(), date, my.getName(),"["+ my.getName()+"]发起外出申请");
			if (res!=0) {
				sendEmail(my, a,1);
			}
			map.put("code", res);
		}else {
			sendEmail(my, a,1);
			map.put("code", 2);
		}
	}

	private String getAssistAidName(String assistAid) {
		String [] ss=assistAid.split(",");
		StringBuffer sb=new StringBuffer();
		for (String s : ss) {
			Admin a=adminMapper.selectById(s);
			if (a!=null&&a.getName()!=null)sb=sb.append(a.getName()).append(",");
		}
		if (sb.length()<1)return "";
		return  sb.deleteCharAt(sb.length() - 1).toString();
	}

	private void sendEmailAndNoticeAndSoucket(String id,Integer type,String content){
		sendNoticeAndSoucket(id,type,content);
		Admin admin = adminMapper.selectById(id);
		String title="暂无标题";
		if (type==3)title=NoticeStatus.PUBLIC_OTHERS_USER.getDesc();
		EmailBo emailBo=new EmailBo(title,admin.getEmail(),content);
		asyncUtils.send(emailBo);

	}

	/**
	 *
	 * @param id 接受者编号
	 * @param type 状态 0驳回 1发起 2同意 3 公出他人企业
	 * @param content 内容
	 */
	private void sendNoticeAndSoucket(String id,Integer type,String content) {
		Integer noticeType=NoticeStatus.PUBLIC_RELEASE_START.getCode();
		if(type==0)noticeType=NoticeStatus.PUBLIC_RELEASE_NO.getCode();
			else if (type==2)noticeType=NoticeStatus.PUBLIC_RELEASE_YES.getCode();
			else if (type==3)noticeType=NoticeStatus.PUBLIC_OTHERS_USER.getCode();
			//触发通知有未读消息
		systemWebSocketHandler.sendMessageToUser(id, new TextMessage("unread"));
		Notice n =new Notice();
		n.setId(UUID.randomUUID().toString());
		n.setAid(id);
		n.setNoticeType(noticeType);
		n.setContent(content);
		n.setReaded(0);//未读
		asyncUtils.addNotice(n);
	}

	/**
	 *
	 * @param my 发送人
	 * @param a 接受者
	 * @param type 类型
	 */
	private void sendEmail(AdminListBo my, Admin a,Integer type) {
		StringBuffer title=new StringBuffer();
		if (type==0) title=title.append("外出申请驳回提醒");
		else if (type==1) title=title.append("外出申请提醒");
		else if (type==2) title=title.append("外出申请同意提醒");
		if (SendEmailUtil.isEmail(a.getEmail())) {
			EmailBo email=new EmailBo(title.toString(),a.getEmail() , my.getDepartmentName(), my.getName(),"详情请登录微信打卡小程序查看,谢谢!") ;
			asyncUtils.send(email);
		}
	}



	@Override
	public int updatePublicRelease(InputPublicRelease in) {
		Date date = new Date();
		try {
			if(in.getReleaseStarts()!=null)in.setReleaseStart(DateUtils.parseDate(in.getReleaseStarts(), AFTConstants.YYYYMMDDHHMMSS));
			if(in.getReleaseEnds()!=null)in.setReleaseEnd(DateUtils.parseDate(in.getReleaseEnds(), AFTConstants.YYYYMMDDHHMMSS));
		} catch (ParseException e) {
			e.printStackTrace();
			throw new BusinessException("转换异常");
		}
		Map checkOrderNo =null;

		List<User> uses=null;
		PublicRelease use = publicReleaseMapper.selectById(in.getId());
		in.setCreateTime(use.getCreateTime());
		String userNames=publicReleaseDetailsMapper.getNamesByPrid(in.getId());
		PublicReleaseLog log=new PublicReleaseLog(in.getId(),TokenManager.getAdminId(),null,in.getReason(),date);
		in.setUserNames(userNames);
		if(in.getStatus()==null||in.getStatus()!=3) {
			if (in.getType() == 1) {
				checkOrderNo = checkOrderNoDuration(in,null,2);
				boolean isValid = (boolean) checkOrderNo.get("code");
				if (isValid){
					in.setTechStartProcess(0);
				}else {
					in.setTechStartProcess(1);
				}

			}else {
				in.setTechStartProcess(0);
			}

			if (in.getAssist()==1){
				in.setAssistProcess(1);
				//在有协单的情况下，新增是审核完成才新增，修改是审核完成才修改。
				//如果是删除，则需要判定
				String[] assistAid = in.getAssistAid().split(",");
				List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainId(in.getId(), null, null);
				for (PublicRelease e : publicReleases) {
					boolean flag = false;
					for (String aid : assistAid) {
						if (e.getAid().equals(aid)){
							flag = true;
							break;
						}
					}
					if (!flag&&e.getClockIn()==1){
						throw new BusinessException("该公出已签到，无法取消");
					}
				}
			}else if (in.getAssist()==0){
				publicReleaseMapper.updateAssist(in);
				in.setAssistProcess(0);
				List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainId(in.getId(), null, null);
				for (PublicRelease e : publicReleases) {
					if (e.getClockIn()==1){
						throw new BusinessException("该协单公出已打卡，无法取消");
					}
				}
			}
			//处理修改公出
			pushUpdatePublic(in, uses, use, log, userNames, date, checkOrderNo);
			//处理修改发起，将面谈信息与项目恢复
			pushUpdatePublicInterviewAndProject( use);
		}else {
			List<PublicRelease> list = publicReleaseMapper.selectByMainId(in.getId(),3,null);
			List<PublicRelease> list2 = publicReleaseMapper.selectByMainId(in.getId(),4,null);
			log.setStatus(PublicReleaseLog.states.cx.getCode());
			for (PublicRelease out : list) {
				addpublicLog(out.getId(), PublicReleaseLog.states.sc.getCode(), "修改撤销协单");
				out.setStatus(3);
				publicReleaseMapper.update(out);
			}

			for (PublicRelease out : list2) {
				addpublicLog(out.getId(), PublicReleaseLog.states.sc.getCode(), "修改撤销协单助手");
				out.setStatus(3);
				publicReleaseMapper.update(out);
			}
			pushPublicInterview(use);
		}
		addPublicReleaseDateClock(in);
		publicReleaseLogMapper.insertSelective(log);
		//设置回不需要审核，理论上按流程变更
		in.setProcessStatus(0);
		publicReleaseMapper.update(in);
		if (in.getOrderNo()!=null){
			TOrderNew tOrderNew = tOrderNewMapper.queryById(in.getOrderNo());
			orderNewService.pushOrderPublicReleaseCount(tOrderNew);
		}
		return 1;
	}

	private void pushUpdatePublicInterviewAndProject(PublicRelease use) {
		List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(use.getId());
		for (OutPublicReleaseDetails e : outPublicReleaseDetails) {
			//撤销后取消面谈项目,如果项目已存在则不恢复，不存在则恢复
			List<UserInterviewProjectBo> prdList = userInterviewProjectMapper.selectByPrdId(e.getId());
			List<UserInterviewProjectBo> userList = userInterviewProjectMapper.selectByAid(use.getAid(), e.getUid());
			if (!userList.isEmpty() && !prdList.isEmpty()) {
				prdList.forEach(e1 -> {
					boolean flag = false;
					userList.forEach(e2 -> {
						//如果不是同一个面谈项目
						if (e1.getPid().equals(e2.getPid())) {
							PublicReleaseDetails prdUpdate = new PublicReleaseDetails();
							prdUpdate.setId(e.getId());
							//是一个公出则恢复，不是则不恢复并且去掉有效
							if (e1.getPrdid()!=null&&(e1.getPrdid().equals(e2.getPrdid()))) {
								UserInterviewProject update = new UserInterviewProject();
								update.setId(e1.getId());
								update.setStatus(0);
								userInterviewProjectMapper.update(update);
								prdUpdate.setInterviewStatus(1);
								publicReleaseDetailsMapper.update(prdUpdate);
							}

						}
					});
				});
			}
		}
	}

	private void pushUpdatePublic(InputPublicRelease in, List<User> uses, PublicRelease use, PublicReleaseLog log, String userNames, Date date, Map checkOrderNo) {
		if (in.getUids()!=null){
			List<String> split = Arrays.asList(in.getUids().split(","));
			List<OutPublicReleaseDetails> prList = publicReleaseDetailsMapper.selectByPrid(in.getId());
			uses =pushPublicReleaseDetails(split,prList, use, in);
		}
		in.setStatus(1);
		log.setStatus(PublicReleaseLog.states.xg.getCode());
		in.setUpdateStatus(1);
		//如果是业务切公出则撤销营销审核与审核人
		pushUpdateType(in, use);
		//如果是业务公出，切审核状态为其他，则重置审核
		if(in.getType()==0&&(use.getPublicType()==2|| use.getPublicType()==3)){
			in.setPublicType(1);
			PublicExamine pe=new PublicExamine();
			pe.setPrid(in.getId());
			pe.setStatus(0);
			publicExamineMapper.updateByPridSelective(pe);
		}
		//处理协单，修改，正常不存在协单，反想操作有协单需要单独处理
		List<PublicRelease> list = publicReleaseMapper.selectByMainId(in.getId(),3,null);
		String[] split = in.getAssistAid().split(",");
		if (split.length==0){
			for (PublicRelease e : list) {
				if (e.getClockIn()==1){
					throw new BusinessException("协单打卡不能删除");
				}
			}
			for (PublicRelease e : list) {
				publicReleaseMapper.deleteById(e.getId());
			}
		}
//			List<PublicRelease> list2 = publicReleaseMapper.selectByMainId(in.getId(),4,null);

//			for (PublicRelease out : list) {
//				addpublicLog(out.getId(), PublicReleaseLog.states.xg.getCode(), "修改公出信息，协单自动更改状态");
//				out.setStatus(1);
//				publicReleaseMapper.updateByPrimaryKeySelective(out);
//			}
//			for (PublicRelease out : list2) {
//				addpublicLog(out.getId(), PublicReleaseLog.states.xg.getCode(), "修改公出信息，协单助手自动更改状态");
//				out.setStatus(1);
//				publicReleaseMapper.updateByPrimaryKeySelective(out);
//			}
		AdminListBo my = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
		pushPublicCarbonCopy( in,  my,  userNames);
		if (in.getAssist()==1){
			String[] split2 = in.getAssistAid().split(",");
			for (String aid2 : split2) {
				AdminListBo my2 = adminMapper.getDeptNameByAid(aid2);
				PublicRelease p=new PublicRelease();
				p.setId(in.getId());
				p.setAid(aid2);
				p.setAname(my2.getName());
				p.setReleaseStart(in.getReleaseStart());
				p.setReleaseEnd(in.getReleaseEnd());
				p.setPlan(in.getPlan());
				p.setType(3);
				pushPublicCarbonCopy(p, my2, userNames);
			}

		}
		//重新发起
		addPublicReleaseLog(my, in, in.getUserNames(), date, uses, checkOrderNo);
	}


	private void pushUpdateType(InputPublicRelease in, PublicRelease use) {
		//营销切换成技术
		if(use.getType()==0&&in.getType()==1){
			in.setPublicType(0);
		}
		if(use.getType()==1&&in.getType()==0){
			in.setTechStartProcess(0);
		}
		publicExamineMapper.deletePrid(in.getId());
	}

	private List<User> pushPublicReleaseDetails(List<String> split, List<OutPublicReleaseDetails> prList, PublicRelease use, InputPublicRelease in) {
		//先删除，再修改个，再新增，有利于减少计算
		deletePRD(split,prList);
		publicReleaseDetailsMapper.updateDistrictByPrid(in);
		List<User> users = addPRD(split, prList, use,in);


		return users;
	}



	private void deletePRD(List<String> split, List<OutPublicReleaseDetails> prdList) {
		for (OutPublicReleaseDetails prd : prdList) {
			boolean flag=true;

			for (String s : split) {
				if (prd.getUid().equals(s)){
					flag=false;
				}
			}
			if (flag){
				publicReleaseDetailsMapper.deleteById(prd.getId());
			}
		}
	}

	/**
	 *  @param split 修改后客户集
	 * @param prdList 修改前客户集
	 * @param use 原订单信息
	 */
	private List<User>  addPRD(List<String> split, List<OutPublicReleaseDetails> prdList, PublicRelease use, InputPublicRelease in) {
		List<PublicReleaseDetails> addPrdList=new ArrayList<>();
		List<User> users=new ArrayList<>();
		Integer publicType = use.getPublicType();
		//计算平均
		Integer userCount=split.size();
		Integer index=0;
		Double duration= in.getDuration();
 		double d = durationSum(duration,userCount );
		for (String s : split) {
			User u=userMapper.queryById(s);
			users.add(u);
			boolean flag=true;
			Integer id=null;
			String districtName=null,latitude=null,longitude=null;
			for (OutPublicReleaseDetails prd : prdList) {
				if (id==null)id=prd.getPrid();
				if (districtName==null)districtName=prd.getDistrictName();
				if (latitude==null)latitude=prd.getLatitude();
				if (longitude==null)longitude=prd.getLongitude();
				if (s.equals(prd.getUid())){
					flag=false;

				}
			}
			//计算下
			if (flag){
				PublicReleaseDetails prd=new PublicReleaseDetails();
				if (u!=null&&u.getShareType()==2){
					prd.setNewUser(1);
				}else {
					prd.setNewUser(0);
				}
				if (u.getAid().equals(use.getAid())){
					prd.setMainStatus(1);
				}else {
					prd.setMainStatus(0);
				}
				prd.setPrid(id);
				prd.setUid(s);
				prd.setSignSum(0);
				prd.setDistrictName(districtName);
				prd.setAddressName(in.getAddressName());
				prd.setLatitude(latitude);
				prd.setLongitude(longitude);
				prd.setClockIn(0);
				addPrdList.add(prd);
				//设置时长
				if (index<userCount){
					if (in.getDuration()==0){
						prd.setDuration(in.getDuration());
					} else {
						prd.setDuration(d);
						duration=duration-d;
					}
				}else {
					prd.setDuration(duration);
				}
				index++;
				//修改公出判定是否需要他人审核
				//先只有业务公出才有，再看是否是业务员，再看是否是限定客户
				if (in.getType()==null)in.setType(use.getType());
				if (in.getType()==0){
					AdminListBo my = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
					if (my.getPublicPurview()==0){
						int countRestrictProject = userMapper.getCountRestrictProject(u.getId(), my.getId());
						if (countRestrictProject==0){
							if (!use.getAid().equals(u.getAid())){
								addPublicExamine(use.getId(), u.getAid());
								if (publicType==1)publicType=1;
							}
						}
					}
				}

			}else {
				InputPublicRelease inp=new InputPublicRelease();
				inp.setId(in.getId());
				inp.setUid(s);
				PublicReleaseDetails publicReleaseDetails = publicReleaseDetailsMapper.selectBypridAndUid(inp);
				PublicReleaseDetails newprd =new PublicReleaseDetails();
				newprd.setId(publicReleaseDetails.getId());
				//设置时长
				if (index<userCount){
					if (in.getDuration()==0){
						newprd.setDuration(in.getDuration());
					} else {
						newprd.setDuration(d);
						duration=duration-d;
					}
				}else {
					newprd.setDuration(duration);
				}
				index++;
				publicReleaseDetailsMapper.update(newprd);
			}
		}
		StringBuffer str=new StringBuffer();
		for (User u : users) {
			str=str.append(use.getUserNames()).append(",");
		}
		if (publicType!=use.getPublicType()){
			PublicRelease newP=new PublicRelease();
			newP.setId(use.getId());
			if (str.length()>1)newP.setUserNames(str.substring(0,str.length()-1));
			newP.setPublicType(publicType);
			publicReleaseMapper.update(newP);
		}
		if (!addPrdList.isEmpty())publicReleaseDetailsMapper.insertBatch(addPrdList);
		return users;
	}


	/**
	 * in.type 查看类型 0我的公出 1公出审核 2管理员 3协单（技术财税总监看全部） 4 公出企业负责人审核 5 技术公出审核 6=协单审核
	 * @return
	 */
	@Override
	public Pagination<OutPublicReleaseList> listPublicRelease(InputPublicReleaseList in) {
		Map<String,Object> map =new HashMap<String, Object>();
		map.put("type", in.getType()==null?0:in.getType());
		OutPublicConfig config=null;
		if (in.getType()==7){
			config=publicConfigMapper.selectDetails();
			String aid=TokenManager.getAdminId();
			int configType=9;
			if (aid.equals(config.getTechAuditor())){
				configType=1;
			}else if (aid.equals(config.getFinanceAuditor())){
				configType=2;
			}else if (aid.equals(config.getOtherAuditor())){
				configType=3;
			}
			map.put("configType", configType);
			if (in.getMaxProcessStatus()!=null)map.put("maxProcessStatus", in.getMaxProcessStatus());
		}
// 		if(in.getType()==4)map.put("type", 5);
		if (in.getType()==3) {
			in.setAssist(2);
			if (!TokenManager.hasRole(AFTConstants.TECH_FINANCE_DIRECTOR))map.put("aid",TokenManager.getAdminId());
		}else{
			map.put("aid",TokenManager.getAdminId());
		}
		if (StringUtils.isNotEmpty(in.getClockTime()))	map.put("clockTime", in.getClockTime());
		if(StringUtils.isNotEmpty(in.getReleaseStarts()))	map.put("releaseStarts", in.getReleaseStarts());
		if(StringUtils.isNotEmpty(in.getReleaseEnds()))	map.put("publicEnd", in.getReleaseEnds()+" 23:59:59");
		if(StringUtils.isNotEmpty(in.getUserName()))	map.put("userName", in.getUserName());
		if(in.getStatus()!=null)	map.put("status", in.getStatus());
		if(in.getClockIn()!=null)	map.put("clockIn", in.getClockIn());
		map.put("assist",in.getAssist()==null?0:in.getAssist());
		Pagination<OutPublicReleaseList> p=(Pagination<OutPublicReleaseList>) findPage("listPublicRelease", "countPublicRelease", map, in.getPageNo(), in.getPageSize());
		//处理审核人
		if (in.getType()==7){
			pushMaxExamines(p,config);
		}else {
			pushExamines(p);
		}
		return p;
	}

	private void pushMaxExamines(Pagination<OutPublicReleaseList> p,OutPublicConfig config) {
		List<OutPublicReleaseList> list = (List<OutPublicReleaseList>) p.getList();
		if (config==null)config=config=publicConfigMapper.selectDetails();
		for (OutPublicReleaseList e : list) {
			if (e.getOrderNo()!=null){
				if (e.getMaxProcess()==1){
					e.setAdminExamine(config.getTechAuditorName());
				}else if (e.getMaxProcess()==2){
					e.setAdminExamine(config.getFinanceAuditorName());
				}else if (e.getMaxProcess()==3){
					e.setAdminExamine(config.getOtherAuditorName());
				}
			}
		}
	}

	private void pushExamines(Pagination<OutPublicReleaseList> p) {
		List<OutPublicReleaseList> list = (List<OutPublicReleaseList>) p.getList();
		if (!list.isEmpty()){
			List<Integer> ids=new ArrayList<>();
			list.forEach(e ->{ ids.add(e.getId()); });
			List<PublicExamine> publicExamines = publicExamineMapper.selectByIds(ids);
			for (OutPublicReleaseList e : list) {
				if (e.getStatus()==1){
					List<AdminPublicReviewerBo> adminPublicReviewerBos=null;
					if (e.getType()==3){
						adminPublicReviewerBos= adminPublicReviewerMapper.selectByAid(e.getAid());
						StringBuffer str =new StringBuffer();
						for (AdminPublicReviewerBo ap : adminPublicReviewerBos) {
							if(ap.getType()==1)str=str.append(ap.getReviewerName()+",");
						}
						if(str.length()>1)e.setAdminExamine(str.substring(0,str.length()-1)+" 未审核");
					}else {
						if (((e.getPublicType()==0||e.getPublicType()==2)
								&&(e.getTechStartProcess()==0||e.getTechStartProcess()==2))
								&&(e.getAssistProcess()==0||e.getAssistProcess()==1)
						){
							StringBuffer str =new StringBuffer();
							adminPublicReviewerBos= adminPublicReviewerMapper.selectByAid(e.getAid());
							if (e.getProcessStatus()==0||e.getProcessStatus()==1){
								for (AdminPublicReviewerBo ap : adminPublicReviewerBos) {
									if(ap.getType()==0)str=str.append(ap.getReviewerName()+",");
								}
							}else if (e.getProcessStatus()==2){
								for (AdminPublicReviewerBo ap : adminPublicReviewerBos) {
									if(ap.getType()==4)str=str.append(ap.getReviewerName()+",");
								}
							}
							if (str.length()>1)e.setAdminExamine(str.substring(0,str.length()-1)+" 未审核");
						}else if (e.getType()==0&&e.getAssistProcess()==2){
							//获取技术协单
							List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainId(e.getId(), null, null);
							StringBuffer str =new StringBuffer();
							for (PublicRelease e2 : publicReleases) {
								if (e2.getStatus()==1){
									adminPublicReviewerBos= adminPublicReviewerMapper.selectByAid(e2.getAid());
									List<AdminPublicReviewerBo> collect = adminPublicReviewerBos.stream().filter(e1 -> e1.getType() == 1).collect(Collectors.toList());
									for (AdminPublicReviewerBo e1 : collect) {
										str.append(e1.getReviewerName()+",");
									}
								}
							}
							if (str.length()>1)e.setAdminExamine(str.substring(0,str.length()-1)+" 未审核");
						} else {
							String s = publicReleaseDetailsMapper.selectUserAdminByPrid(e.getId());
							e.setAdminExamine(s+" 未审核");
						}
					}
				}else if (e.getStatus()==0) {
					e.setAdminExamine("");
				}else {
					if (!publicExamines.isEmpty()){
						if (e.getStatus()==2){
							e.setAdminExamine("");
						}else{
							StringBuffer str =new StringBuffer();
							for (PublicExamine pe : publicExamines) {
								if (e.getId().equals(pe.getPrid())){
									str=str.append(pe.getAname());
									if (pe.getStatus()==0)str=str.append(" 未审核,");
									if (pe.getStatus()==1)str=str.append(" 已审核,");
								}
								if (str.length()>1) e.setAdminExamine(str.substring(0,str.length()-1));
							}
						}
					}
				}
				if(e.getType()==3){
					List<PublicAssistAdvice> publicAssistAdvices = publicAssistAdviceMapper.selectList(e.getId(), 0);
					if (publicAssistAdvices.isEmpty()){
						e.setPublicAssistAdvice(0);
					}else {
						e.setPublicAssistAdvice(publicAssistAdvices.size());
					}
				}else if(e.getType()==0){
					List<PublicAssistAdvice> publicAssistAdvices = publicAssistAdviceMapper.selectList(e.getId(), 1);
					if (publicAssistAdvices.isEmpty()){
						e.setPublicAssistAdvice(0);
					}else {
						e.setPublicAssistAdvice(publicAssistAdvices.size());
					}
				}



			}
		}


	}

	/**
	 *
	 * @param id
	 * @param status 状态 0驳回 1发起 2同意 3 撤销 4技术驳回
	 * @param remarks
	 * @param examineType 0上级审核 1营销员审核 2技术审核 3二级审核
	 * @param evaluateType 0不存指导意见 1存指导意见
	 * @return
	 */
	@Override
	@Transactional
	public int pushExaminePublicRelease(Integer id, Integer status, String remarks,Integer examineType,Integer evaluateType) {
		PublicRelease p=new PublicRelease();
		Date date =new Date();
		String aid=TokenManager.getAdminId();
		p.setId(id);
		PublicRelease use=publicReleaseMapper.selectById(id);
		if (use.getStatus()!=1) {
			throw new BusinessException("只能修改发起的状态公出");
		}
		if((use.getTechStartProcess()==1||use.getTechStartProcess()==3)&&(examineType==0||examineType==1)){
			if(use.getTechStartProcess()!=0) throw new BusinessException("技术公出先需营销审核。");

		}
		//当前审核人员
		Admin ad=adminMapper.selectById(aid);
		//公出负责人
		Admin a;
		Admin publicAdmin =adminMapper.selectById(use.getAid());
		a=publicAdmin;
		StringBuffer str=new StringBuffer();
		str=str.append("（").append(ad.getName()).append("）");
		StringBuffer content=new StringBuffer().append("[").append(use.getUserNames()).append("]公司的外出申请,");
		//上级审核
		if(examineType==0){
			p.setStatus(status);
				if (status==0){
					addpublicLog(id, status, remarks);
					str=str.append("驳回，");
					if (use.getAssist()==2){
						content=content.append("技术协单被[").append(ad.getName()).append("]拒绝!");
					}else {
						content=content.append("未通过公出审核!");
					}
					if(use.getPublicType()>1){
						p.setPublicType(1);
						PublicExamine inpe=new PublicExamine();
						inpe.setStatus(0);
						inpe.setPrid(use.getId());
						publicExamineMapper.updateStatusByPrid(inpe);
					}
				}else if(status==2){//同意区分是1级审核还是二级审核
					str=str.append("同意，");
					addpublicLog(id, status, remarks);
					content=content.append("已通过审核!");
					//新增二级审核
					List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(use.getAid());
					adminPublicReviewerBos=adminPublicReviewerBos.stream().filter(e -> e.getType() == 4).collect(Collectors.toList());
					if (adminPublicReviewerBos.isEmpty()){
						p.setStatus(2);
						p.setProcessStatus(3);
						//如果是协单公出主公出，在审核通过
						if (use.getAssist()==1){
							pushPublicReleaseAssist(use, p, date, a);
						}else if (use.getAssist()==0){
							publicReleaseMapper.updateStatusByMainId(3,use.getId(),null,null);
						}
						addpublicLog(id, status, "无需二级审核直接通过");
					}else {
						if(use.getProcessStatus()==0||use.getProcessStatus()==1){
							//一级审核
							p.setStatus(1);
							p.setProcessStatus(2);
							str=str.append(remarks);
							p.setAuditInfo(str.toString());
							p.setAuditTime(date);
							p.setRejectName(ad.getName());
							for (AdminPublicReviewerBo e : adminPublicReviewerBos) {
								sendNoticeAndSoucket(e.getReviewerId(),status,content.toString());
							}
						}else if (use.getProcessStatus()==2){
							//二级审核，新增判定是否是审核人
							boolean flag = false;
							for (AdminPublicReviewerBo e : adminPublicReviewerBos) {
								if (e.getReviewerId().equals(aid)){
									flag = true;
								}
							}
							if (!flag){
								throw new BusinessException("请勿重复审核,二级审核错误！");
							}
							p.setStatus(2);
							p.setProcessStatus(3);
							//如果是协单公出主公出，在审核通过
							if (use.getAssist()==1){
								pushPublicReleaseAssist(use, p, date, a);
							}else if (use.getAssist()==0){
								publicReleaseMapper.updateStatusByMainId(3,use.getId(),null,null);
							}
							str=str.append(remarks);
							p.setAuditInfo(str.toString());
							p.setAuditTime(date);
							p.setRejectName(ad.getName());
							sendNoticeAndSoucket(a.getId(),status,content.toString());
						}
					}
				}
				str=str.append(remarks);
				p.setAuditInfo(str.toString());
				p.setAuditTime(date);
				p.setRejectName(ad.getName());
				sendNoticeAndSoucket(a.getId(),status,content.toString());
				List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(id);
				//添加上级评价
				if (use.getProcessStatus()==1&&evaluateType==1){
					addUserSuperEvaluate(remarks, outPublicReleaseDetails, date);
				}
			//营销员审核
		}else if (examineType==1){
			//通知公出人切换成公出人审核人
			if (status==2){
				if (use.getPublicType()!=1){
					throw new BusinessException("当前状态不是客户归属人审核，请刷新页面");
				}
				List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(a.getId());
				adminPublicReviewerBos=adminPublicReviewerBos.stream().filter(e -> e.getType() == 0).collect(Collectors.toList());

				//审核通过
				str=str.append("同意公出我的企业，").append(remarks);
				content=content.append("已通过审核,请尽快审核。");
				List<PublicExamine> publicExamines = publicExamineMapper.selectByPrid(use.getId());
				int x=0;
				for (PublicExamine pe : publicExamines) {
					if (pe.getAid().equals(aid)){
						pe.setStatus(1);
						PublicExamine newp=new PublicExamine();
						newp.setId(pe.getId());
						newp.setStatus(1);
						publicExamineMapper.updateByPrimaryKeySelective(newp);
						x++;
					}else {
						if (pe.getStatus()==1){
							x++;
						}
					}
				}
				if (x==publicExamines.size()){
					p.setPublicType(2);
				}
				addpublicLog(id, status, str.toString());
				//将信息发送给审核人
				for (AdminPublicReviewerBo adminPublicReviewerBo : adminPublicReviewerBos) {
					sendNoticeAndSoucket(adminPublicReviewerBo.getReviewerId(),status,content.toString());
				}

			}else if (status==0){//审核驳回
				//切换通知人公出负责人
				a=publicAdmin;
				str=str.append("不同意公出我的企业，").append(remarks);;
				content=content.append("未通过审核,请修改后重新发起。");
				p.setPublicType(3);
				p.setStatus(0);
				p.setAuditInfo(str.toString());
				p.setRejectName(ad.getName());
				addpublicLog(id, 0, str.toString());
				sendNoticeAndSoucket(a.getId(),status,content.toString());
			}
		}else if (examineType==2){
			//技术审核
			if (status==2){//审核通过
				str=str.append("同意公出我的企业，").append(remarks);
				content=content.append("已通过审核,请尽快审核。");
				List<PublicExamine> publicExamines = publicExamineMapper.selectByPrid(use.getId());
				int x=0;
				for (PublicExamine pe : publicExamines) {
					if (pe.getAid().equals(aid)){
						pe.setStatus(1);
						PublicExamine newp=new PublicExamine();
						newp.setId(pe.getId());
						newp.setStatus(1);
						publicExamineMapper.updateByPrimaryKeySelective(newp);
						x++;
					}else {
						if (pe.getStatus()==1){
							x++;
						}
					}
				}
				if (x==publicExamines.size()){
					p.setTechStartProcess(2);
					List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(a.getId());
					adminPublicReviewerBos=adminPublicReviewerBos.stream().filter(e -> e.getType() == 0).collect(Collectors.toList());
					for (AdminPublicReviewerBo adminPublicReviewerBo : adminPublicReviewerBos) {
						sendNoticeAndSoucket(adminPublicReviewerBo.getReviewerId(),status,content.toString());
					}
				}
				addpublicLog(id, status, str.toString());
			}else if (status==0){
				//审核驳回
				//切换通知人公出负责人
				a=publicAdmin;
				str=str.append("不同意公出我的企业，").append(remarks);;
				content=content.append("未通过审核,请修改后重新发起。");
				p.setTechStartProcess(3);
				p.setStatus(0);
				p.setAuditInfo(str.toString());
				p.setRejectName(ad.getName());
				addpublicLog(id, 0, str.toString());
				sendNoticeAndSoucket(a.getId(),status,content.toString());
			}
		}
		AdminListBo my = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
		if (p.getStatus()!=null||p.getPublicType()!=null||p.getTechStartProcess()!=null){
			publicReleaseMapper.update(p);
		}
		//驳回业务公出，需要取消标记首次面谈，取消本次面谈项目，取消标记有效面谈
		if(status==0&&use.getType()==0){
			pushPublicInterview(use);
		}

		if (a.getOpenId()!=null) {
			if (remarks.length()>19) {
				remarks=remarks.substring(0, 15)+"...";
			}
			Integer res=weChatUtils.addNotice(a.getOpenId(),status,p.getId(),date,my.getName(),remarks);
			if (res!=0) {
				sendEmail( my,  a, status);

			}
			return res;
		}
			return 1;
	}

	/**
	 * 驳回的时候将首次面谈，本次面谈项目，有效面谈取消
	 * @param use
	 */
	private void pushPublicInterview(PublicRelease use) {
		List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(use.getId());
		for (OutPublicReleaseDetails e : outPublicReleaseDetails) {
			//撤销后取消面谈项目
			userInterviewProjectMapper.updateByPrdId(e.getId(),1);
			//将有效面谈去掉
			PublicReleaseDetails p=new PublicReleaseDetails();
			p.setInterviewStatus(0);
			p.setId(e.getId());
			publicReleaseDetailsMapper.update(p);
			//删除首次面谈数据
			userFirstInterviewMapper.deleteByPrdId(e.getId());
		}
	}

	/**
	 * 添加上级评价
	 * @param remarks
	 * @param outPublicReleaseDetails
	 * @param date
	 */
	private void addUserSuperEvaluate(String remarks, List<OutPublicReleaseDetails> outPublicReleaseDetails, Date date) {
		List<UserSuperEvaluate> addLsit=new ArrayList<>();
		for (OutPublicReleaseDetails e : outPublicReleaseDetails) {
			UserSuperEvaluate addUSE=new UserSuperEvaluate();
			addUSE.setAid(TokenManager.getAdminId());
			addUSE.setUid(e.getUid());
			addUSE.setContent(remarks);
			addUSE.setCreateTime(date);
			addLsit.add(addUSE);
		}
		userSuperEvaluateMapper.insertBatch(addLsit);
	}


	@Override
	public Object updateAssistExamine(Integer id, Integer status, String remarks,Integer evaluateType) {
		PublicRelease use = publicReleaseMapper.selectById(id);
		if (use.getAssistProcess()!=2){
			throw new BusinessException("该公出不是待协单审核的公出。");
		}
		List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainIdAndReviewer(id, TokenManager.getAdminId());
		String content=use.getUserNames()+"公司的外出协单申请";
		PublicRelease newPublic=new PublicRelease();
		if (status==0){
			content+="已被驳回。";
			newPublic.setId(use.getId());
			newPublic.setStatus(status);
			publicReleaseMapper.update(newPublic);
			addpublicLog(id, status, remarks);
			for (PublicRelease e : publicReleases) {
				PublicRelease newPublic2=new PublicRelease();
				newPublic2.setId(e.getId());
				newPublic2.setStatus(status);
				publicReleaseMapper.update(newPublic2);
				addpublicLog(e.getId(), status, remarks);
			}
		}else if(status==2){
			content+="已通过审核。";
			addpublicLog(id, status, remarks);
			for (PublicRelease e : publicReleases) {
				PublicRelease newPublic2=new PublicRelease();
				newPublic2.setId(e.getId());
				newPublic2.setStatus(status);
				publicReleaseMapper.update(newPublic2);
				addpublicLog(e.getId(), status, remarks);
			}
			//审核需看是否所有人审核
			List<PublicRelease> newList = publicReleaseMapper.selectByMainId(use.getId(),3,null);
			int count = 0;
			for (PublicRelease e : newList) {
				if (e.getStatus()==2){
					count++;
				}
			}
			if(count==newList.size()){
				PublicRelease newPublic2=new PublicRelease();
				newPublic2.setId(use.getId());
				newPublic2.setStatus(2);
				publicReleaseMapper.update(newPublic2);
				sendNoticeAndSoucket(use.getAid(),status,content.toString());
			}else {
				PublicRelease newPublic2=new PublicRelease();
				newPublic2.setId(use.getId());
				newPublic2.setStatus(1);
				publicReleaseMapper.update(newPublic2);
			}
			if (evaluateType==1){
				List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(id);
				addUserSuperEvaluate(remarks, outPublicReleaseDetails, new Date());
			}
		}
		return 1;
	}



	@Override
	public Object assistUnaudited() {
		String aid=TokenManager.getAdminId();
		int unaudited = publicReleaseMapper.selectCountByUnaudited(aid);
		int assistUnaudited = publicReleaseMapper.selectCountByAssistUnaudited(aid);
		int otherUnaudited = publicReleaseMapper.selectCountByOtherUnaudited(aid);
		Map<String,Object> i=new HashMap<>();
		i.put("unaudited",unaudited);
		i.put("assistUnaudited",assistUnaudited);
		i.put("otherUnaudited",otherUnaudited);
		return i;
	}

	@Override
	public boolean checkPublicReviewer(InputPublicRelease in) {
		List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(TokenManager.getAdminId());
		if (adminPublicReviewerBos.isEmpty()){
			return true;
		}
		return false;
	}

	@Override
	public int pushLimitUser(String uid, Integer hours) {
		User user = userMapper.queryById(uid);
		if (!user.getAid().equals(TokenManager.getAdminId())){
			return 0;
		}
		long l = System.currentTimeMillis();
		if (hours==null)hours=2;
		l=l+hours*60*60*1000;
		UserLimitCheck userLimitCheck = userLimitCheckMapper.selectByUid(uid);
		if (userLimitCheck==null){
			UserLimitCheck ulc=new UserLimitCheck();
			ulc.setUid(uid);
			ulc.setCheckTime(new Date(l));
			userLimitCheckMapper.insert(ulc);
		}else {
			userLimitCheck.setCheckTime(new Date(l));
			userLimitCheckMapper.update(userLimitCheck);
		}

		return 1;
	}

	@Override
	public boolean checkUserArchives(String uid) {
		User user = userMapper.queryById(uid);
		UserArchives userArchives = userArchivesMapper.queryByUid(uid);
		if (user.getNewChannel()==0){
			if (userArchives==null||
					StringUtils.isBlank(userArchives.getFinancialData())||
					StringUtils.isBlank(userArchives.getEarlyCommunication())||
					StringUtils.isBlank(userArchives.getInterviewIdeas())){
				return false;
			}
		}else {
			OrganizationIdentity organizationIdentity = organizationIdentityMapper.selectOrgIdentityByUserId(uid);
			Integer i = organizationContactBookMapper.checkContacts(uid, null, user.getAid());
			if (i==null||i<1){
				return false;
			}
			if (userArchives==null||
					userArchives.getEnterpriseCount()==null||
					StringUtils.isBlank(organizationIdentity.getIntendedProject())||
					StringUtils.isBlank(userArchives.getChannelIndicators())||
					StringUtils.isBlank(userArchives.getInterviewDistribution())||
					StringUtils.isBlank(userArchives.getInterviewIdeas())){
				return false;
			}
		}

		return true;
	}

	@Override
	public Object updateMaxDuration(String orderNo, Double maxDuration,String remarks) {
		TOrderPublicReleaseCount in =new TOrderPublicReleaseCount();
		TOrderPublicReleaseCount use = tOrderPublicReleaseCountMapper.selectByOrderNo(orderNo);
		if (use.getMaxProcess()==1||use.getMaxProcess()==2||use.getMaxProcess()==3){
			throw new BusinessException("该最大公出已经是待审核的状态。");
		}
		in.setOrderNo(orderNo);
		in.setMaxDuration(maxDuration);
		in.setMaxProcess(1);
		in.setMaxStatus(1);
		addOrderPublicReleaseLog(orderNo,0,0,remarks,use.getMaxDuration(),maxDuration);
		PublicConfig publicConfig = publicConfigMapper.queryById(1);
		TOrderNewBo order = tOrderNewMapper.getSaleIdByOno(orderNo);
		StringBuilder str=new StringBuilder();
		str.append("合同编号[").append(order.getContractNo()).append("]最大公出限制审核");
		str.append("需要审核，请尽快审核。");
		if (publicConfig.getTechAuditorStauts()==0){
			if (publicConfig.getFinanceAuditorStauts()==0){
				if (publicConfig.getOtherAuditorStauts()==0){
					//当3个都未设置直接通过
					in.setMaxProcess(5);
					addOrderPublicReleaseLog(orderNo,1,5,"未设置审核人直接全部通过");
				}else {
					addNoticeAndEmail(publicConfig.getOtherAuditor(),NoticeStatus.PUBLIC_MAX_DURATION.getCode(), str.toString());
				}
			}else {
				addNoticeAndEmail(publicConfig.getFinanceAuditor(),NoticeStatus.PUBLIC_MAX_DURATION.getCode(), str.toString());
			}
		}else {
			addNoticeAndEmail(publicConfig.getTechAuditor(),NoticeStatus.PUBLIC_MAX_DURATION.getCode(), str.toString());
		}
		tOrderPublicReleaseCountMapper.updateByOrderNo(in);
		return 1;
	}

	@Override
	public Object pushExamineMaxDuration(String orderNo,Integer status, String remarks) {
		TOrderPublicReleaseCount in =new TOrderPublicReleaseCount();
		TOrderPublicReleaseCount use = tOrderPublicReleaseCountMapper.selectByOrderNo(orderNo);
		in.setOrderNo(orderNo);
		PublicConfig publicConfig = publicConfigMapper.queryById(1);
		TOrderNewBo order = tOrderNewMapper.getSaleIdByOno(orderNo);
		in.setMaxProcess(use.getMaxProcess());
		String aid=TokenManager.getAdminId();
		 if (use.getMaxProcess()==1){
				if (publicConfig.getTechAuditorStauts()==1&&TokenManager.getAdminId().equals(publicConfig.getTechAuditor())) {
					addOrderPublicReleaseLog(orderNo,status,1,remarks);
				}else {
				throw new BusinessException("审核人错误，必须是设置的审核人员才能审核。");
				}
		}else if (use.getMaxProcess()==2){
			if (publicConfig.getFinanceAuditorStauts()==1&&TokenManager.getAdminId().equals(publicConfig.getFinanceAuditor())) {
				addOrderPublicReleaseLog(orderNo,status,2,remarks);
			}else {
				throw new BusinessException("审核人错误，必须是设置的审核人员才能审核。");
			}
		}else if (use.getMaxProcess()==3){
			 if (publicConfig.getOtherAuditorStauts()==1&&TokenManager.getAdminId().equals(publicConfig.getOtherAuditor())) {
				 addOrderPublicReleaseLog(orderNo,status,3,remarks);

			 }else {
				 throw new BusinessException("审核人错误，必须是设置的审核人员才能审核。");
			 }
		}
		pushPublicConfigSendNoticeAndEmail(publicConfig, in, aid, order, status);
		return tOrderPublicReleaseCountMapper.updateByOrderNo(in);
	}

	private void pushPublicConfigSendNoticeAndEmail(PublicConfig publicConfig, TOrderPublicReleaseCount in, String aid, TOrderNewBo order,Integer status) {
		StringBuilder str=new StringBuilder();
		str.append("合同编号[").append(order.getContractNo()).append("]最大公出限制审核");
		int noticeStatus=0;
		if (status==1){
			noticeStatus=NoticeStatus.PUBLIC_MAX_DURATION_YES.getCode();
		}else if (status==2){
			noticeStatus=NoticeStatus.PUBLIC_MAX_DURATION_NO.getCode();
		}
		//处理当前审核状态确定发送人
		pushPublicConfig(publicConfig, in);
		String str1="需要审核，请尽快审核。";
		if (in.getMaxProcess()==2){
			aid = publicConfig.getFinanceAuditor();
		} else if (in.getMaxProcess()==3){
			aid = publicConfig.getOtherAuditor();
		}
		else if (in.getMaxProcess()==5){
			str1="审核通过。";
			aid = order.getSalesmanId();
		}
		str.append(str1);
		addNoticeAndEmail(aid, noticeStatus, str.toString());
		if (in.getMaxProcess()==5){
			pushCompleteMaxDuration( in.getOrderNo());
		}
	}

	private void pushPublicConfig(PublicConfig config, TOrderPublicReleaseCount in) {
		if (in.getMaxProcess()==1){
			if (config.getFinanceAuditorStauts()==0){
				if (config.getOtherAuditorStauts()==0){
					in.setMaxProcess(5);
				}else {
					in.setMaxProcess(3);
				}
			}else {
				in.setMaxProcess(2);
			}
		}else if (in.getMaxProcess()==2){
			if (config.getOtherAuditorStauts()==0){
				in.setMaxProcess(5);
			}else {
				in.setMaxProcess(3);
			}
		} else if (in.getMaxProcess()==3) {
			in.setMaxProcess(5);
		}
	}

	@Override
	public Object maxDurationLog(String orderNo) {
		return orderPublicReleaseLogMapper.queryByOrderNo(orderNo);
	}

	@Override
	public Object updatePublicConfig(PublicConfig in) {
		in.setId(1);
		return publicConfigMapper.update(in);
	}

	@Override
	public Object getPublicConfig() {
		return publicConfigMapper.selectDetails();
	}

	private void pushCompleteMaxDuration(String orderNo) {
		List<OrderPublicReleaseLog> orderPublicReleaseLogs = orderPublicReleaseLogMapper.queryByOrderNo(orderNo);
		List<PublicRelease> publicReleases = publicReleaseMapper.selectByOrderNo(orderNo);
		for (PublicRelease e : publicReleases) {
			//只比对审核中的
			if (e.getStatus()==1){
				boolean flag = false;
				//审核中的公出审核人，是公出审核人
				List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(e.getAid());
				for (OrderPublicReleaseLog log : orderPublicReleaseLogs) {
					for (AdminPublicReviewerBo e2 : adminPublicReviewerBos) {
						if (log.getAuditor().equals(e2.getReviewerId())){
							flag = true;
							break;
						}
					}
				}
				if (flag){
					//有审核人，需要审核
					PublicRelease newP=new PublicRelease();
					newP.setId(e.getId());
					newP.setStatus(2);
					addpublicLog(e.getId(),2,"公出审核人已经审核最大公出小时，跳过审核");
					addNoticeAndEmail(e.getAid(), NoticeStatus.PUBLIC_RELEASE_YES.getCode(), "公出审核人已经审核最大公出小时，跳过审核");
					publicReleaseMapper.update(e);
				}
			}
		}
	}

	private void addNoticeAndEmail(String aid, Integer noticeStatus, String remarks) {
		asyncUtils.addNoticAndEmail(noticeStatus,aid,remarks);
	}

	private void addNotice(String aid, Integer noticeType, String content) {
		Notice n =new Notice();
		n.setId(UUID.randomUUID().toString());
		n.setAid(aid);
		n.setNoticeType(noticeType);
		n.setContent(content);
		n.setReaded(0);//未读
		asyncUtils.addNotice(n);
	}
	private void addOrderPublicReleaseLog(String orderNo, Integer status, Integer process, String remarks) {
		addOrderPublicReleaseLog(orderNo,status,process,remarks,null,null);
	}
	private void addOrderPublicReleaseLog(String orderNo, Integer status, Integer process, String remarks,Double useDuration,Double newDuration) {
		Admin admin = adminMapper.selectById(TokenManager.getAdminId());
		OrderPublicReleaseLog log = new OrderPublicReleaseLog();
		log.setOrderNo(orderNo);
		log.setProcessStatus(process);
		log.setStatus(status);
		log.setAuditor(admin.getId());
		log.setAuditorName(admin.getName());
		log.setRemarks(remarks);
		log.setNewDuration(newDuration);
		log.setUseDuration(useDuration);
		log.setCreateTime(new Date());
		orderPublicReleaseLogMapper.insert(log);
	}



	private void addpublicLog(Integer id, Integer status, String remarks) {
		PublicReleaseLog log = new PublicReleaseLog(id, TokenManager.getAdminId(), status, remarks, new Date());
		publicReleaseLogMapper.insertSelective(log);
	}

	@Override
	public int pushTechReject(Integer id,  String remarks) {
		Integer status=0;
		PublicRelease use=publicReleaseMapper.selectById(id);
		PublicRelease mainPublic= publicReleaseMapper.selectById(use.getMainId());
		Admin ad=adminMapper.selectById(TokenManager.getAdminId());
		StringBuffer str=new StringBuffer();
		if (use.getAssist()!=2){
			throw  new BusinessException("只有技术公出能发起技术驳回");
		}
		str=str.append("拒绝技术协单，").append(remarks);
		PublicRelease newMain=new PublicRelease();
		newMain.setId(mainPublic.getId());
		newMain.setStatus(4);
		newMain.setRejectName(ad.getName());
		newMain.setAuditInfo(str.toString());
		addWeChatNotice(mainPublic.getAid(),0,str.toString(),mainPublic.getId());
		publicReleaseMapper.update(newMain);
		PublicRelease up=new PublicRelease();
		up.setId(id);
		up.setAuditInfo(str.toString());
		up.setStatus(3);
		addpublicLog(id, status, remarks);
		publicReleaseMapper.update(up);
		deleteAssistantPulicRelease(use,null);
		return addNoticeAndWeChat(mainPublic.getId(), mainPublic.getAid(), str.toString(), status);
	}

	/**
	 * 新增日志、站内信、微信提醒
	 * @param id 日志公出编号
	 * @param aid 接受者
	 * @param remarks 日志内容
	 * @param status 0驳回
	 * @return
	 */
	private Integer addNoticeAndWeChat(Integer id,String aid, String remarks,  Integer status) {
		AdminListBo my = adminMapper.getDeptNameByAid(aid);
		Admin a = adminMapper.selectById(TokenManager.getAdminId());
		if (my.getOpenId()!=null) {
			if (remarks.length()>19) {
				remarks=remarks.substring(0, 15)+"...";
			}
			return weChatUtils.addNotice(my.getOpenId(),status,id,new Date(),my.getName(), remarks);
		}else {
			sendEmail( my,  a, status);
			return 1;
		}
	}

	/**
	 *
	 * @param use 原始公出信息
	 * @param date 时间
	 * @param a
	 */
	private void pushPublicReleaseAssist(PublicRelease use,PublicRelease update,Date date,Admin a) {
		if (use.getAssistAid()!=null){
			updatePushassist(use, update, date,a);
			if(use.getAssistantAid()!=null){
				updatepushAssistant(use,a);
			}

		}
	}

	/**
	 * 处理技术协单
	 * @param use
	 * @param date
	 */
	private void updatePushassist(PublicRelease use, PublicRelease updatePR, Date date, Admin a) {

		//协单
		List<PublicRelease> list = publicReleaseMapper.selectByMainId(use.getId(),3,null);
		String []ss= use.getAssistAid().split(",");
		//数据库与传入比对，如果不存在就标记撤销 ，如果存在就修改成
		for (PublicRelease out : list) {
			boolean flag=false;
			for (String s : ss) {
				if (out.getAid().equals(s)){
					flag=true;
					break;
				}
			}
			//不存在则取消公出
			if (!flag){
				PublicRelease in = new PublicRelease();
				in.setId(out.getId());
				in.setStatus(3);
				publicReleaseMapper.update(in);
				StringBuffer str = new StringBuffer("[").append(a.getName()).append("]取消公出").append("[").append(use.getUserNames()).append("]。");
				PublicReleaseLog log = new PublicReleaseLog(in.getId(), TokenManager.getAdminId(), PublicReleaseLog.states.cx.getCode(), str.toString(), date);
				publicReleaseLogMapper.insertSelective(log);
				sendNoticeAndSoucket(out.getAid(),in.getStatus(),str.toString());
			}else {
				//存在则修改公出
				PublicRelease np = new PublicRelease();
				BeanUtils.copyProperties(use,np);
				np.setId(out.getId());
				np.setMainId(null);
				np.setType(null);
				np.setAssist(2);
				pushAssist(use, date, a, out, np);
				StringBuffer str = new StringBuffer("[").append(a.getName()).append("]修改了公出").append("[").append(use.getUserNames()).append("]。");
				PublicReleaseLog log = new PublicReleaseLog(np.getId(), TokenManager.getAdminId(), PublicReleaseLog.states.xg.getCode(),str.toString(), date);
				publicReleaseLogMapper.insertSelective(log);
				sendNoticeAndSoucket(out.getAid(),np.getStatus(),str.toString());
			}
		}
		//有新增则新增公出
		for (String s : ss) {
			boolean flag2 = false;
			for (PublicRelease o : list) {
				if (s.equals(o.getAid())) {
					flag2 = true;
				}
			}
			if (!flag2) {
				PublicRelease np = new PublicRelease();
				BeanUtils.copyProperties(use,np);
				AdminListBo my2 = adminMapper.getDeptNameByAid(s);
				np.setAssist(2);
				np.setAid(s);
				np.setAname(my2.getName());
				//协单审核，判定是否跳过的逻辑
				np.setType(3);
				np.setMainId(use.getId());
				np.setId(null);
				pushAssist(use, date, a, np, np);
				StringBuffer str = new StringBuffer("[").append(a.getName()).append("]邀请你技术协单").append("[").append(use.getUserNames()).append("]。");
				PublicReleaseLog log = new PublicReleaseLog(np.getId(), TokenManager.getAdminId(), PublicReleaseLog.states.fq.getCode(), str.toString(), date);
				sendNoticeAndSoucket(s,np.getStatus(),str.toString());
				publicReleaseLogMapper.insertSelective(log);

			}
		}
		//判定是审核还是完成，取决于协单是否通过
		List<PublicRelease> newList = publicReleaseMapper.selectByMainId(use.getId(),3,null);
		int count = 0;
		for (PublicRelease e : newList) {
			//如果是完成或者拒绝则标记，全中断则修改状态
			if (e.getStatus()==2||e.getStatus()==3){
				count++;
			}
		}
		if(count==newList.size()){
			updatePR.setStatus(2);
			updatePR.setAssistProcess(4);
		}else {
			updatePR.setStatus(1);
			updatePR.setAssistProcess(2);
		}
	}

	private void pushAssist(PublicRelease use, Date date, Admin a, PublicRelease out, PublicRelease np) {
		//协单审核，判定是否跳过的逻辑
		List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(out.getAid());
		adminPublicReviewerBos = adminPublicReviewerBos.stream().filter(e -> e.getType() == 1).collect(Collectors.toList());
		//协单人
		Admin admin = adminMapper.selectById(out.getAid());
		int x=pushAssist(np, use,adminPublicReviewerBos);
		if (np.getId() == null){
			publicReleaseMapper.insertSelective(np);
		}else {
			np.setAid(null);
			publicReleaseMapper.update(np);
		}
		updatePublicReleaseDtails(use, np);
		if (x==2||x==3){
			String remarks="";
			if (x==2){
				remarks="协单未设置审核人，自动通过";
			}else if (x==3){
				remarks="协单审核人重复，自动通过";
			}
			PublicReleaseLog log2 = new PublicReleaseLog(np.getId(), "1", PublicReleaseLog.states.ty.getCode(), remarks, new Date());
			publicReleaseLogMapper.insertSelective(log2);
			PublicReleaseLog log3 = new PublicReleaseLog(use.getId(), "1", PublicReleaseLog.states.ty.getCode(), remarks, new Date());
			publicReleaseLogMapper.insertSelective(log3);
		}
//		通知协单上级审核
		if(x==1){
			for (AdminPublicReviewerBo e : adminPublicReviewerBos) {
				StringBuffer str = new StringBuffer("[").append(a.getName()).append("]发起了协单审核，协单人：").append(admin.getName()).append("。");
				sendNoticeAndSoucket(e.getAid(), np.getStatus(),str.toString());
				//协单通知人
				Admin ad = adminMapper.selectById(e.getAid());
				weChatUtils.addNotice(ad.getOpenId(),1, use.getId(), date, a.getName(),str.toString());
			}

		}
	}

	/**
	 * 协单审核判定是否跳过的逻辑
	 * 如果未设置跳过审核，如果已审核跳过
	 *
	 * @param np 新协单公出信息
	 * @param use 原公出信息
	 */
	private int pushAssist( PublicRelease np, PublicRelease use,List<AdminPublicReviewerBo> collect) {
		int res=0;
		if (!collect.isEmpty()){
			//公出发起人
			List<outPublicReleaseLog> outPublicReleaseLogs = publicReleaseLogMapper.listPublicReleaseLog(use.getId(), null);
			List<outPublicReleaseLog> collect1 = outPublicReleaseLogs.stream().filter(e -> e.getStatus() == 2).collect(Collectors.toList());
			boolean flag = false;
			for (AdminPublicReviewerBo e : collect) {
				for (outPublicReleaseLog log : collect1) {
					if (log.getAid().equals(e.getReviewerId())){
						flag=true;
						break;
					}
				}
				if(flag){
					break;
				}

			}
			if (flag){
				np.setStatus(2);
				res=3;
			}else {
				np.setStatus(1);
				res=1;
			}
		}else {
			np.setStatus(2);
			res=2;
		}
		//res 1=未完成全部审核，2=未设置跳过审核，3=已审核全部跳过
		return res;
	}

	private void updatePublicReleaseDtails(PublicRelease use, PublicRelease in) {

		List<OutPublicReleaseDetails> list = publicReleaseDetailsMapper.selectByPrid(use.getId());
		List<OutPublicReleaseDetails> list2 = publicReleaseDetailsMapper.selectByPrid(in.getId());
		//打卡信息重新梳理

		//查找新增的
		for (OutPublicReleaseDetails out : list) {
			boolean flag=true;
			for (OutPublicReleaseDetails out2 : list2) {
				if (out.getUid().equals(out2.getUid())){
					flag=false;
				}
			}
			if (flag){
				OutPublicReleaseDetails prd=new OutPublicReleaseDetails();
				BeanUtils.copyProperties(out,prd);
				prd.setId(null);
				prd.setPrid(in.getId());
				prd.setClockIn(0);
				prd.setClockInTime(null);
				prd.setClockInRemarks(null);
				prd.setUfid(null);
				publicReleaseDetailsMapper.insertSelective(prd);
			}
		}

		for (OutPublicReleaseDetails out2 : list2) {
			boolean flag=true;
			for (OutPublicReleaseDetails out : list) {
				if (out2.getUid().equals(out.getUid())){
					flag=false;
				}
			}
			if (flag){
				publicReleaseDetailsMapper.deleteById(out2.getId());
			}
		}
		//信息补充，修改时没有打卡信息
		if(in.getValidDate()==null)in.setValidDate(use.getValidDate());
		//最后再来处理打卡信息
		addPublicReleaseDateClock(in);
	}

	private void addpublicReleaseDtails(PublicRelease use, PublicRelease in) {
		List<OutPublicReleaseDetails> list = publicReleaseDetailsMapper.selectByPrid(use.getId());
		for (OutPublicReleaseDetails out : list) {
			OutPublicReleaseDetails prd=new OutPublicReleaseDetails();
			BeanUtils.copyProperties(out,prd);
			prd.setId(null);
			prd.setPrid(in.getId());
			prd.setClockIn(0);
			prd.setClockInTime(null);
			prd.setMainStatus(0);
			publicReleaseDetailsMapper.insertSelective(prd);
		}
		addPublicReleaseDateClock(in);
	}

	/**
	 * 处理技术助手
	 * @param use
	 */
	private void updatepushAssistant(PublicRelease use,Admin a) {
		List<PublicRelease> uselist = publicReleaseMapper.selectByMainId(use.getId(),4,null);
		for (PublicRelease p : uselist) {
					if(!use.getReleaseStart().equals(p.getReleaseStart()))p.setReleaseStart(use.getReleaseStart());
					if (!use.getReleaseEnd().equals(p.getReleaseEnd()))p.setReleaseEnd(use.getReleaseEnd());
					p.setStatus(2);
					p.setAssistantAid(use.getAssistantAid());
					p.setAssistantName(use.getAssistantName());
					p.setUserNames(use.getUserNames());
					publicReleaseMapper.update(p);
					StringBuffer str = new StringBuffer("[").append(a.getName()).append("]修改了").append("[").append(use.getUserNames()).append("]。");
					PublicReleaseLog log = new PublicReleaseLog(p.getId(), TokenManager.getAdminId(), PublicReleaseLog.states.ty.getCode(), str.toString(), new Date());
					sendNoticeAndSoucket(p.getAid(),p.getStatus(),str.toString());
					publicReleaseLogMapper.insertSelective(log);
		}
	}

	@Override
	public List<outPublicReleaseLog> listPublicReleaseLog(Integer id,String ufid) {
		List<outPublicReleaseLog> list=new ArrayList<>();
		List<outPublicReleaseLog> log=publicReleaseLogMapper.listPublicReleaseLog(id,ufid);
		PublicRelease e = publicReleaseMapper.selectById(id);
		List<PublicExamine> publicExamines = publicExamineMapper.selectByPrid(id);
		if (e.getStatus()==1){
			outPublicReleaseLog outPublicReleaseLog = new outPublicReleaseLog();
			outPublicReleaseLog.setStatus(6);
				List<AdminPublicReviewerBo> adminPublicReviewerBos=null;
				if (e.getType()==3){
					adminPublicReviewerBos= adminPublicReviewerMapper.selectByAid(e.getAid());
					StringBuffer str =new StringBuffer();
					for (AdminPublicReviewerBo ap : adminPublicReviewerBos) {
						if(ap.getType()==1)str=str.append(ap.getReviewerName()+",");
					}
					if(str.length()>1){

						outPublicReleaseLog.setAname(str.substring(0,str.length()-1));
						list.add(outPublicReleaseLog);
					}
				}else {
					if (((e.getPublicType()==0||e.getPublicType()==2)
							&&(e.getTechStartProcess()==0||e.getTechStartProcess()==2))
							&&(e.getAssistProcess()==0||e.getAssistProcess()==1)
					){
						StringBuffer str =new StringBuffer();
						adminPublicReviewerBos= adminPublicReviewerMapper.selectByAid(e.getAid());

						for (AdminPublicReviewerBo ap : adminPublicReviewerBos) {
							if((e.getProcessStatus()==0||e.getProcessStatus()==1)&&ap.getType()==0)str=str.append(ap.getReviewerName()+",");
							if((e.getProcessStatus()==2)&&ap.getType()==4)str=str.append(ap.getReviewerName()+",");
						}
						if(str.length()>1){
							outPublicReleaseLog.setAname(str.substring(0,str.length()-1));
							list.add(outPublicReleaseLog);
						}
					}else if (e.getType()==0&&e.getAssistProcess()==2){
						//获取技术协单
						List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainId(e.getId(), null, null);
						StringBuffer str =new StringBuffer();
						for (PublicRelease e2 : publicReleases) {
							if (e2.getStatus()==1){
								adminPublicReviewerBos= adminPublicReviewerMapper.selectByAid(e2.getAid());
								List<AdminPublicReviewerBo> collect = adminPublicReviewerBos.stream().filter(e1 -> e1.getType() == 1).collect(Collectors.toList());
								for (AdminPublicReviewerBo e1 : collect) {
									str.append(e1.getReviewerName()+",");
								}
							}
						}
						if(str.length()>1){
							outPublicReleaseLog.setAname(str.substring(0,str.length()-1));
							list.add(outPublicReleaseLog);
						}
					} else {
						String s = publicReleaseDetailsMapper.selectUserAdminByPrid(e.getId());
						outPublicReleaseLog.setAname(s);
						list.add(outPublicReleaseLog);
					}
				}
		}
		list.addAll(log);
		return list;
	}


	@Override
	public int pushPublicReleaseClockIn(Integer id,String photoUrl,Integer clockIn ,String clockInRemarks ,String uid) {
		if (clockIn == null) clockIn = 1;
		PublicRelease use = publicReleaseMapper.selectById(id);
		if (use.getPublicType()==1||use.getPublicType()==3) {
			return -1;
		}
		if (use.getStatus()!=2){
			return -2;
		}
		if(use.getType()==3){
			List<PublicAssistAdvice> publicAssistAdvices = publicAssistAdviceMapper.selectList(id, 0);
			if(publicAssistAdvices.isEmpty()){
				return -3;
			}
		}
		List<OutPublicReleaseDetails> prdList = publicReleaseDetailsMapper.selectByPrid(id);
		List<PublicReleaseDateClock> prdcList = publicReleaseDateClockMapper.selectByPrid(id);
		pushDateClockDetails(prdList,prdcList);
		String str = "";
		Date date = new Date();
		boolean flag=false;
		Integer clockCount=0;
		PublicReleaseClock pc=new PublicReleaseClock();
		pc.setPrid(id);
		pc.setPhotoUrl(photoUrl);
		pc.setClockInTime(date);
		for (OutPublicReleaseDetails prd : prdList) {
			if (prd.getUid().equals(uid)){
				String aid = TokenManager.getAdminId();
				pc.setPrdid(prd.getId());
				pc.setLatitude(prd.getLatitude());
				pc.setLongitude(prd.getLongitude());
				pc.setDistrictName(prd.getDistrictName());
				prd.setClockInRemarks(clockInRemarks);
				prd.setPhotoUrl(photoUrl);
				prd.setClockInTime(date);
				int  count=0;
				for (PublicReleaseDateClock ep : prd.getPrdcList()) {
					if (DateUtils.isSameDay(prd.getClockInTime(), ep.getClockInTime())){
						if (ep.getStatus()==0){
							ep.setStatus(1);
							FollowBusinessBo fbb = new FollowBusinessBo();
							fbb.setUid(prd.getUid());
							fbb.setContactType("5");
							fbb.setResult(use.getRemarks());
							OrganizationContactBook ub = organizationContactBookMapper.getMajor(prd.getUid(), aid);
							if (ub != null) {
								fbb.setOcbId(ub.getId());
							}
							fbb.setFollowTime(DateUtils.formatDate(prd.getClockInTime(), AFTConstants.YYYYMMDDHHMMSS));
							String ufid = UUID.randomUUID().toString();
							prd.setUfid(ufid);
							customerService.addFollow(fbb, ufid, prd.getMainStatus(),0,null);
							if (clockIn==1){
								str = "公出人员打卡";
							}else if (clockIn==2) {
								str = "公出人员异常打卡";
							}
							count++;
							publicReleaseDateClockMapper.updateByPrimaryKeySelective(ep);
						}else {
							if (clockIn==1){
								str = "刷新打卡";
							}else if (clockIn==2) {
								str = "刷新打卡，公出人员异常打卡";
							}
							count++;
						}
					}else {
						if (ep.getStatus()==1){
							count++;
						}
					}

				}
				if(prd.getPrdcList().size() == count){
					prd.setClockIn(1);
				}
				PublicReleaseLog log = new PublicReleaseLog(id, aid, PublicReleaseLog.states.dk.getCode(), str, new Date());
				log.setPhotoUrl(photoUrl);
				publicReleaseLogMapper.insertSelective(log);
				publicReleaseDetailsMapper.update(prd);
				flag=true;
				clockCount++;
			}else if (prd.getClockIn()==1){
				clockCount++;
			}
		}
		if (prdList.size()==clockCount){
			PublicRelease newp=new PublicRelease();
			newp.setId(id);
			newp.setClockIn(1);
			publicReleaseMapper.update(newp);
		}
		publicReleaseClockMapper.insertSelective(pc);
		if (!flag){
			return 0;
		}
		return 1;
	}

	@Override
	public OutPublicRelease dtails(Integer id) {
		String aid=TokenManager.getAdminId();
		//如果不是本人和审核人员则不返回信息
		OutPublicRelease out=publicReleaseMapper.selectDtails(id);
		List<PublicExamine> ps = publicExamineMapper.selectByPrid(out.getId());
		out.setPeList(ps);
		List<AdminPublicReviewerBo> adminPublicReviewerBos=null;
		if(out!=null){
			//详情查看权限
			boolean flag=false;
			//客户文档查看权限
			boolean flag2=false;
			//自己、审核人员与部门负责人可以查看
			AdminListBo ab=adminMapper.getDeptNameByAid(out.getAid());
			//获取设置公出最大值的
			if(out.getType()==1){
				TOrderPublicReleaseCount tOrderPublicReleaseCount = tOrderPublicReleaseCountMapper.selectByOrderNo(out.getOrderNo());
				if(tOrderPublicReleaseCount!=null){
					out.setMaxDuration(BigDecimal.valueOf(tOrderPublicReleaseCount.getMaxDuration()));
					out.setMaxProcess(tOrderPublicReleaseCount.getMaxProcess());
					out.setMaxType(tOrderPublicReleaseCount.getMaxType());
				}else {
					out.setMaxDuration(BigDecimal.ZERO);
					out.setMaxProcess(0);
					out.setMaxType(0);
				}
			}
			//自己、部门负责人与技术财税管理员可以查看
			if (aid.equals( out.getAid())||
					aid.equals(ab.getDepManager())||
					TokenManager.hasRole(AFTConstants.TECH_FINANCE_DIRECTOR)){
				flag=true;
			}
			//技术公出 财务与技术管理员可以查看
			if(out.getType()==1&&
					( TokenManager.hasRole(AFTConstants.FINANCE_ADMIN)||
							TokenManager.hasRole(AFTConstants.TECH_ADMIN))){
				flag=true;
			}

			//自己可以查看文档
			if (aid.equals(out.getAid())){
				if (out.getType()==0||out.getType() == 1){
					flag2=true;
				}
			}
			out.setMyExamine(0);
			if (out.getType()==0||out.getType()==1||out.getType()==2){
				if (adminPublicReviewerBos==null)adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(out.getAid());
				//判定是否是上级审核人
				boolean myFlag = false;
				List<AdminPublicReviewerBo> collect = new ArrayList<>();
				if (out.getProcessStatus()==0||out.getProcessStatus()==1){
					collect = adminPublicReviewerBos.stream().filter(e -> e.getType() == 0).collect(Collectors.toList());
				}else if (out.getProcessStatus()==2){
					 collect = adminPublicReviewerBos.stream().filter(e -> e.getType() == 4).collect(Collectors.toList());
					 //逻辑未完成先搁置
				}
				//如果是审核人可以查看
				for (AdminPublicReviewerBo e : collect) {
					if (e.getReviewerId().equals(aid)){
						flag=true;
						if (out.getType()==0){
							flag2=true;
						}
						myFlag=true;
						break;
					}
				}
				//新增所有审核人就是查看权限
				for (AdminPublicReviewerBo e : adminPublicReviewerBos) {
					if ((e.getType()==0||e.getType()==4)
							&&aid.equals(e.getReviewerId())){
						flag=true;
						flag2=true;
					}
				}
				//判定是否是上级审核状态
				if((out.getPublicType()==0|| out.getPublicType()==2)&&
						(out.getTechStartProcess()==0|| out.getTechStartProcess()==2)&&
						(out.getAssistProcess()==0|| out.getAssistProcess()==1)&&
						(out.getAssist()==0|| out.getAssist()==1)&& out.getStatus()==1
				){
					if (myFlag){
						out.setMyExamine(1);
					}
					if(out.getPublicType()==2){
						for (PublicExamine p : ps) {
							if (p.getAid().equals(aid)){{
								flag = true;
								break;
							}

						}
					}
				}
				} else if (out.getPublicType()==1) {
					//他人公出审核
					if (!ps.isEmpty()){
						for (PublicExamine p : ps) {
							if (p.getAid().equals(aid)){
								flag=true;
								if (out.getPublicType()==1&&out.getStatus()==1){
									if (p.getStatus()==0)out.setMyExamine(1);
									else out.setMyExamine(0);
									break;
								}
							}

						}
					}
				}else if ((out.getTechStartProcess()==1||out.getTechStartProcess()==2)&&out.getStatus()==1) {
					List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(out.getId());
					boolean myExamine = false;
					for (OutPublicReleaseDetails ord : outPublicReleaseDetails) {
						User user = userMapper.queryById(ord.getUid());
						if (user.getAid().equals(aid)){
							flag=true;
							if (out.getTechStartProcess()==1)myExamine=true;

						}
					}
					if (myExamine)out.setMyExamine(1);
				} else if (out.getAssistProcess()==2||out.getAssistProcess()==3||out.getAssistProcess()==4) {
					//添加协单审核人可以查看
					List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainId(out.getId(), null, null);
					for (PublicRelease e : publicReleases) {
						List<AdminPublicReviewerBo> sonAPRList =  adminPublicReviewerMapper.selectByAid(e.getAid());
						List<AdminPublicReviewerBo> collect2 = sonAPRList.stream().filter(e2 -> e2.getType() == 1).collect(Collectors.toList());
						for (AdminPublicReviewerBo e2 : collect2) {
							if (e2.getReviewerId().equals(aid)){
								flag=true;
								if((out.getAssistProcess()==2||out.getAssistProcess()==3)&&
										out.getStatus()==1
								){
									out.setMyExamine(1);
									break;
								}
							}
						}
					}
				}
			}else if(out.getType()==3){
				//如果是协单，如果是审核人则不可以查看
				if (adminPublicReviewerBos==null)adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(out.getAid());
				List<AdminPublicReviewerBo> collect = adminPublicReviewerBos.stream().filter(e -> e.getType() == 1).collect(Collectors.toList());
				for (AdminPublicReviewerBo e : collect) {
					if (e.getReviewerId().equals(aid)){
						flag=true;
						break;
					}
				}
				String[] split = out.getAssistAid().split(",");
				for (String s : split) {
					if (s.equals(aid)){
						flag2=true;
						break;
					}
				}

			}
			//客户档案设置查看权限
			if (flag2){
				out.setViewPermission(1);
			}else {
				out.setViewPermission(0);
			}

			//处理返回
			if(flag){
				if(aid.equals(out.getAid())) {
					out.setPermission(0);
				}else {
					out.setPermission(1);
				}
			}else {
				out=null;
				return out;
			}
		}
		//设置审核人
		pushExamine(out, adminPublicReviewerBos, ps);
		List<OutPublicReleaseDetails> prdList = publicReleaseDetailsMapper.selectByPrid(id);
		List<PublicReleaseDateClock> prdcList = publicReleaseDateClockMapper.selectByPrid(id);
		pushDateClockDetailsToday(prdList,prdcList);
		out.setPrdList(prdList);
		//判定公出协单意见有没有的权限
		List<PublicAssistAdvice> publicAssistAdvices = publicAssistAdviceMapper.selectList(out.getId(), 0);
		if (publicAssistAdvices.isEmpty()){
			out.setPublicAssistAdvice(0);
		}else {
			out.setPublicAssistAdvice(publicAssistAdvices.size());

		}
		return out;
	}




	/**
	 * 设置审核人
	 * @param out
	 * @param adminPublicReviewerBos
	 * @param ps
	 */
	private void pushExamine(OutPublicRelease out, List<AdminPublicReviewerBo> adminPublicReviewerBos, List<PublicExamine> ps) {
		//设置审核人
		if (out.getStatus()==1&&
				((out.getPublicType()==0|| out.getPublicType()==2)&&(out.getTechStartProcess()==0|| out.getTechStartProcess()==2)))
		{

			if (adminPublicReviewerBos ==null) adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(out.getAid());
			StringBuffer str =new StringBuffer();
			//技术协单，获取协单审核人
			if(out.getType()==3){
				List<AdminPublicReviewerBo> collect = adminPublicReviewerBos.stream().filter(e -> e.getType() == 1).collect(Collectors.toList());
				for (AdminPublicReviewerBo e : collect) {
					str.append(e.getReviewerName()+",");
				}
				//业务公出且协单部分审核（看着流程有点问题）
			}else if (out.getType()==0&& out.getAssistProcess()==2){
				//获取技术协单
				List<PublicRelease> publicReleases = publicReleaseMapper.selectByMainId(out.getId(), null, null);
				List<String> names=new ArrayList<>();
				List<String> ids=new ArrayList<>();
				for (PublicRelease e : publicReleases) {
					if (e.getStatus()==1){
						adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(e.getAid());
						List<AdminPublicReviewerBo> collect = adminPublicReviewerBos.stream().filter(e1 -> e1.getType() == 1).collect(Collectors.toList());
						for (AdminPublicReviewerBo e1 : collect) {
							if (!names.contains(e1.getReviewerName())){
								names.add(e1.getReviewerName());
								ids.add(e1.getReviewerId());
							}
						}
					}
				}
				for (String name : names) {
					str.append(name+",");
				}
//				out.setMyExamine(1);
//				for (String s : ids) {
//					if (s.equals(TokenManager.getAdminId())){
//						out.setMyExamine(0);
//					}
//				}
			} else {
				//业务公出，且协单审核完成？
				List<AdminPublicReviewerBo> collect=new ArrayList<>();
				if (out.getProcessStatus()==0||out.getProcessStatus()==1){
					collect = adminPublicReviewerBos.stream().filter(e -> e.getType() == 0).collect(Collectors.toList());
				}else {
					collect = adminPublicReviewerBos.stream().filter(e -> e.getType() == 4).collect(Collectors.toList());
				}
				for (AdminPublicReviewerBo e : collect) {
					str.append(e.getReviewerName()+",");
				}



			}


			if(str.length()>1) out.setAdminExamine(str.substring(0,str.length()-1)+" 未审核");
		}else if (out.getStatus()==0) {
			out.setAdminExamine("");
		}else {
			if (!ps.isEmpty()){
				StringBuffer str =new StringBuffer();
				for (PublicExamine e : ps) {
					if (out.getId().equals(e.getPrid())){
						str.append(e.getAname());
						if (e.getStatus()==0) str.append(" 未审核,");
						if (e.getStatus()==1) str.append(" 已审核,");
					}
					if (str.length()>1) out.setAdminExamine(str.substring(0,str.length()-1));
				}

			}
		}
	}


	@Override
	public OutPublicReleaseAndDetails followDtails(String id) {
		OutPublicReleaseAndDetails out = publicReleaseMapper.selectDtailsByFid( id);
		List<OutPublicReleaseDetails> prdList = publicReleaseDetailsMapper.selectByPrid(out.getId());
		List<PublicReleaseDateClock> prdcList = publicReleaseDateClockMapper.selectByPrid(out.getId());
		pushDateClockDetails(prdList,prdcList);
		out.setPrdList(prdList);
		return out;
	}

	@SuppressWarnings("unchecked")
	@Override
//	@Cacheable(value = "publicReleaseStatistics#300", key = "'publicReleaseStatistics:" +
//			"aid:'+#in.aid+'depId:'+#in.depId+'clockStart:'+#in.clockStart+" +
//			"'clockEnd:'+#in.clockEnd+'createStart:'+#in.createStart+'createEnd'+#in.createEnd+" +
//			"'pageNo:'+#in.pageNo+'pageSzie:'+#in.pageSize")
	public Object publicReleaseStatistics(InputPublicStatistics in) {
		Map<String,Object> map =new HashMap<String, Object>();
		if(in.getAid()!=null)map.put("aid", in.getAid());
		if(in.getDepId()!=null)map.put("depId", in.getDepId());
		if(in.getClockStart()!=null)map.put("clockStart", in.getClockStart());
		if(in.getClockEnd()!=null)map.put("clockEnd", in.getClockEnd()+" 23:59:59");
		if(in.getCreateStart()!=null)map.put("createStart", in.getCreateStart());
		if(in.getCreateEnd()!=null)map.put("createEnd", in.getCreateEnd()+" 23:59:59");
		return (Pagination<OutPublicStatistics>) findPage("listPublicStatistics", "countPublicStatistics", map, in.getPageNo(), in.getPageSize());
	}



	@SuppressWarnings("unchecked")
	@Override
	public List<OutPublicStatistics> publicReleaseStatisticsList(InputPublicStatistics in) {
		Map<String,Object> map =new HashMap<String, Object>();
		if(in.getAid()!=null)map.put("aid", in.getAid());
		if (TokenManager.hasRole(AFTConstants.SUPERADMIN)|| TokenManager.hasRole(AFTConstants.APPROVAL_DECISION)||
				TokenManager.hasRole(AFTConstants.CED)|| TokenManager.hasRole(AFTConstants.CED_ASSISTANT)){
			if(in.getDepId()!=null)map.put("depId", in.getDepId());
		}else if (TokenManager.hasRole(AFTConstants.COMPANY_MANAGER)||TokenManager.hasRole(AFTConstants.PERSONNEL_AUDITOR)){
		}
		if(in.getClockStart()!=null)map.put("clockStart", in.getClockStart());
		if(in.getClockEnd()!=null)map.put("clockEnd", in.getClockEnd()+" 23:59:59");
		if(in.getCreateStart()!=null)map.put("createStart", in.getCreateStart());
		if(in.getCreateEnd()!=null)map.put("createEnd", in.getCreateEnd()+" 23:59:59");
		return (List<OutPublicStatistics>) findList("listPublicStatistics",map, in.getPageNo(), 99999);
	}





	@SuppressWarnings("unchecked")
	@Override
	public Object publicReleaseListDtails(InputPublicDtails in) {
		Map<String,Object> map =new HashMap<String, Object>();
		addParams(in, map);
		Pagination<OutPublicDtails> page = (Pagination<OutPublicDtails>) findPage("listPublicDtails", "countPublicDtails", map, in.getPageNo(), in.getPageSize());
		List<OutPublicDtails> list = (List<OutPublicDtails>)page.getList();
		List<Integer> collect = list.stream().map(OutPublicDtails::getId).collect(Collectors.toList());
		if (!collect.isEmpty()){
			List<PublicReleaseClock> publicReleaseClocks = publicReleaseClockMapper.selectList(collect);
			pushiClockInTime(list, publicReleaseClocks);
		}
		return page;
	}

	private void addParams(InputPublicDtails in, Map<String, Object> map) {
		if(in.getAid()!=null) map.put("aid", in.getAid());
		if(in.getSid()!=null) map.put("sid", in.getSid());
		if(in.getReleaseStart()!=null) map.put("releaseStart", in.getReleaseStart());
		if(in.getReleaseEnd()!=null) map.put("releaseEnd", in.getReleaseEnd()+" 23:59:59");
		if(in.getCreateStart()!=null) map.put("createStart", in.getCreateStart());
		if(in.getCreateEnd()!=null) map.put("createEnd", in.getCreateEnd()+" 23:59:59");
		if(in.getUid()!=null) map.put("uid", in.getUid());
		if(in.getContractNo()!=null) map.put("contractNo", in.getContractNo());
		if(in.getStatus()!=null) map.put("status", in.getStatus());
		if(in.getClockIn()!=null) map.put("clockIn", in.getClockIn());
		if(in.getPublicType()!=null)map.put("publicType",in.getPublicType());
		//type 0私有 1管理权限 2所有权限
		if(TokenManager.hasRole(AFTConstants.SUPERADMIN)||TokenManager.hasRole(AFTConstants.APPROVAL_DECISION)
				||TokenManager.hasRole(AFTConstants.CED_ASSISTANT )||TokenManager.hasRole(AFTConstants.PERSONNEL_AUDITOR)
					||TokenManager.hasRole(AFTConstants.FINANCE_ADMIN)
					||TokenManager.hasRole(AFTConstants.FINANCE)||TokenManager.hasRole(AFTConstants.FINANCE_MANAGER)){
			//添加财务和财务经理。查看客户所有公出
			in.setType(2);
			if(in.getDeps()!=null){
				map.put("deps", departmentService.parseArray(in.getDeps()));
			}
		}else if(TokenManager.hasRole(AFTConstants.COMPANY_MANAGER)||TokenManager.hasRole(AFTConstants.SALESMAN_ADMIN)
				||TokenManager.hasRole(AFTConstants.OPERATION_MANAGER)){
			in.setType(1);
			if (in.getDeps()!=null){
				List<String> list = departmentService.selectSubDeps(in.getDeps());
				if (list.isEmpty()) throw new BusinessException("无权查看此部门信息");
				map.put("deps", list);
			}else {
				map.put("deps",departmentService.selectMyDeps());
			}
		}else{
			in.setType(0);
			if (in.getAid()==null) map.put("aid",TokenManager.getAdminId());
			if(in.getDeps()!=null){
				map.put("deps", departmentService.parseArray(in.getDeps()));
			}
		}
		map.put("type", in.getType());
		if(in.getStatusType()!=null) map.put("statusType", in.getStatusType());
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<OutPublicDtails> publicReleaseListDtailsList(InputPublicDtails in) {
		Map<String,Object> map =new HashMap<String, Object>();
		addParams(in, map);
		return (List<OutPublicDtails>) findList("listPublicDtails", map, in.getPageNo(), 99999);
	}

	@Override
	public int addSupplement(Integer id, String supplement, String nextPlan) {
		PublicRelease pr=new PublicRelease();
		pr.setId(id);
		if (StringUtils.isNotEmpty(supplement)) pr.setSupplement(supplement);
		if (StringUtils.isNotEmpty(nextPlan)) pr.setNextPlan(nextPlan);
		return publicReleaseMapper.update(pr);
	}




	@Override
	public int checkTime(InputPublicRelease in) {
		try {
			in.setReleaseStart(DateUtils.parseDate(in.getReleaseStarts(), AFTConstants.YYYYMMDDHHMMSS));
			in.setReleaseEnd(DateUtils.parseDate(in.getReleaseEnds(), AFTConstants.YYYYMMDDHHMMSS));
		} catch (ParseException e) {
			e.printStackTrace();
			throw new BusinessException("转换异常");
		}
		//如果主协单且一起公出
		if(in.getAssist()==1){
			//如果一起公出先判定发起人，再判定协单人，如果只是协单公出则只需要判定协单
			if (in.getAlone()==1){
				if(checkPublicTime(TokenManager.getAdminId(), in)){
					//第一种，发起人时间重复
					return 1;
//				return true;
				}
			}
			//判定协单时间重复
			Integer x = checkTech(in);
			if (x != null) return x;
		}else {
			//判定当前发起人能发起不
			if(checkPublicTime(TokenManager.getAdminId(), in)){
				//第一种，发起人时间重复
				return 1;
//				return true;
			}
		}

		return 0;
	}

	private Integer checkTech(InputPublicRelease in) {
		String[] split = in.getAssistAid().split(",");
		for (String s : split) {
			//先查审核中和完成的时间有没有冲突的
			if(checTechTime(s, in)){
				//第二种，协单人时间重复
				return 2;
//					return true;
			}
			//再查发起前营销审核中时间有没有冲突的
			Integer x = checkSalesmanExamine(in, s);
			if (x != null) return x;
		}
		return 0;
	}

	private boolean checTechTime(String aid, InputPublicRelease in) {
		List<PublicRelease> is=publicReleaseMapper.checkTime(aid,in.getReleaseStart(),in.getReleaseEnd());
		if (is.size()>1) {
			return true;
		}else  if(is.size()==1){
			//如果id为新增那么直接不允许时间重复
			if (in.getId()==null){
				return true;
			}else {
				//如果有id，与获取id一直，则为当前修改可以
				if (in.getId().equals(is.get(0).getMainId())){
					return false;
				}else {
					return true;
				}
			}

		}
		return false;
	}

	private Integer checkSalesmanExamine(InputPublicRelease in, String s) {
		List<PublicRelease> is = publicReleaseMapper.checkTech(s, in.getReleaseStart(), in.getReleaseEnd());
		if (is.size()>1) {
			return 2;
		}else  if(is.size()==1){
			//如果id为新增那么直接不允许时间重复
			if (in.getId()==null){
				return 2;
			}else {
				//如果有id，与获取id一直，则为当前修改可以
				if (in.getId().equals(is.get(0).getId())){
					return 0;
				}else {
					return 2;
				}
			}
		}
		return null;
	}

	/**
	 *
	 * @param aid
	 * @param in
	 * @return true 已经发起   false 未发起
	 */
	private boolean checkPublicTime(String aid, InputPublicRelease in) {
		List<PublicRelease> is=publicReleaseMapper.checkTime(aid,in.getReleaseStart(),in.getReleaseEnd());
		if (is.size()>1) {
			return true;
		}else  if(is.size()==1){
			//如果id为新增那么直接不允许时间重复
			if (in.getId()==null){
				return true;
			}else {
				//如果有id，与获取id一直，则为当前修改可以
				if (in.getId().equals(is.get(0).getId())){
					return false;
				}else {
					return true;
				}
			}

		}
		return false;
	}


	@Override
	public List<Map<String, Object>> selectOrderByUid(String uid) {
		return tOrderNewMapper.selectOrderByuid(uid);
	}

	@Override
	public List<OutPublicRelease> publicByOrder(String orderNo) {
		return publicReleaseMapper.publicByOrder(orderNo);
	}

	@Override
	public Object getMyNewPublic() {
		List<PublicRelease> myPublic=publicReleaseMapper.selectMyNewPublic(TokenManager.getAdminId());
		if(myPublic.isEmpty())return null;
		Integer id=null;
		long count=999999;
		for (PublicRelease e : myPublic) {
			long nowTime=System.currentTimeMillis();
			long time = Math.abs(nowTime-e.getReleaseStart().getTime())/(1000*60);
			long time2 = Math.abs(e.getReleaseEnd().getTime()-nowTime)/(1000*60);

			//距离当前时间近的开始时间，不大于当前时间
			if (time<count&&e.getReleaseStart().getTime()<nowTime){
				if (e.getAlone()!=1 && e.getAssist()!=1){
					count=time;
					id=e.getId();
				}
			}
			//距离当前时间近的结束时间，不小于当前时间
			if (time2<count&&e.getReleaseEnd().getTime()>nowTime){
				if (e.getAlone()!=1 && e.getAssist()!=1){
					count=time2;
					id=e.getId();
				}
			}
		}
		if (id==null)id=myPublic.get(0).getId();
		OutPublicReleaseList out = publicReleaseMapper.selectOutListBoById(id);
		List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(out.getAid());
		StringBuilder sb = new StringBuilder();
		adminPublicReviewerBos.forEach(e -> {
			if (e.getType()==0){
				sb.append(e.getReviewerName()).append(",");
			}
		});
		if (sb.length()>0) {
			out.setReviewerName(sb.substring(0,sb.length()-1));
		}
		List<OutPublicReleaseDetails> prdList = publicReleaseDetailsMapper.selectByPrid(id);
		List<PublicReleaseDateClock> prdcList = publicReleaseDateClockMapper.selectByPrid(id);
		pushDateClockDetails(prdList,prdcList);
		pushDateClockDetailsToday(prdList,prdcList);
		out.setPrdList(prdList);
		List<PublicAssistAdvice> publicAssistAdvices = publicAssistAdviceMapper.selectList(out.getId(), 0);
		if (publicAssistAdvices.isEmpty()){
			out.setPublicAssistAdvice(0);
		}else {
			out.setPublicAssistAdvice(publicAssistAdvices.size());

		}

		return out;
//		List<OutPublicReleaseList> myPublic = getMyPublic(0,1);
//		if (myPublic.isEmpty()){
//			List<OutPublicReleaseList> myPublic2 = getMyPublic(0,0);
//			if (!myPublic2.isEmpty()){
//				return myPublic2.get(0);
//			}
//		}else {
//			return myPublic.get(0);
//		}
	}

	private void pushDateClockDetailsToday(List<OutPublicReleaseDetails> prdList, List<PublicReleaseDateClock> prdcList) {
		for (OutPublicReleaseDetails out : prdList) {
			List<PublicReleaseDateClock> elist=new ArrayList<>();;
			for (PublicReleaseDateClock prdc : prdcList) {
				if (prdc.getPrdid().equals(out.getId())&&DateUtils.isSameDay(new Date(), prdc.getClockInTime())){
					elist.add(prdc);
				}
			}
			out.setPrdcList(elist);
		}
	}

	private void pushDateClockDetails(List<OutPublicReleaseDetails> prdList, List<PublicReleaseDateClock> prdcList) {
		for (OutPublicReleaseDetails out : prdList) {
			List<PublicReleaseDateClock> elist=new ArrayList<>();;
			for (PublicReleaseDateClock prdc : prdcList) {
				if (prdc.getPrdid().equals(out.getId())){
					elist.add(prdc);
				}
			}
			out.setPrdcList(elist);
		}
	}


	/**
	 *
	 * @param type 查看类型 0我的公出 1公出审核 2管理员 3协单（技术财税总监看全部）
	 * @param dateType 是否含打卡时间  0否 1是
	 * @return
	 */
	public List<OutPublicReleaseList>getMyPublic(Integer type ,Integer dateType){
		Map<String, Object> map = new HashMap<>();
		if (type==null)type=0;
		map.put("type",type);
		//statusType=1情况下
		map.put("statusType",1);
		if (dateType==1){
			Date date = new Date();
			String clockTime=DateUtils.formatDate(date,AFTConstants.YYYYMMDDHHMMSS);
			map.put("clockTime",clockTime);
		}
		map.put("aid",TokenManager.getAdminId());
		List<OutPublicReleaseList> list = (List<OutPublicReleaseList>) findList("listPublicRelease",map,1,1);
		for (OutPublicReleaseList out : list) {
			out.setPrdList(publicReleaseDetailsMapper.selectByPrid(out.getId()));

		}
		return list;
	}

	@Override
	public int addAssistant(Integer id,String aid) {
		PublicRelease p = publicReleaseMapper.selectById(id);
		List<String> list=new ArrayList<>();
		if (StringUtils.isNotEmpty(p.getAssistantAid())){
			list =new ArrayList<>(Arrays.asList(p.getAssistantAid().split(",")));
		}
		String sname = pushAssistant(aid, list,0);
		String said =String.join(",",list);
		p.setAssistantAid(said);
		p.setAssistantName(sname);
		addAssistantPublicRelease(p,aid);
		return updateAssistant(p, said, sname);
	}

	private void addAssistantPublicRelease(PublicRelease p, String aid) {
		List<PublicRelease> list = publicReleaseMapper.selectByMainId(p.getMainId(), 4, null);
		PublicRelease newP= new PublicRelease();
		if(list.isEmpty()){
			BeanUtils.copyProperties(p,newP);
			AdminListBo my2 = adminMapper.getDeptNameByAid(aid);
			newP.setId(null);
			newP.setAid(aid);
			newP.setUserNames(my2.getName());
			newP.setAssist(3);
			newP.setType(4);
			publicReleaseMapper.insertSelective(newP);
			addpublicReleaseDtails(p,newP);
			StringBuffer str=new StringBuffer();
			str=str.append("公出").append("[").append(p.getUserNames()).append("]").append("邀请你协助!");
			addWeChatNotice( aid,1,str.toString(),newP.getId());
		}else {
			for (PublicRelease pr : list) {
					newP.setId(pr.getId());
					newP.setAssistantAid(p.getAssistantAid());
					newP.setAssistantName(p.getAssistantName());
					publicReleaseMapper.update(newP);
					updatePublicReleaseDtails(p,newP);
			}
		}
	}

	/**
	 *	添加微信提示和站内消息
	 * @param aid 接受者
	 * @param type 状态 0驳回 1发起 2同意 3撤销
	 * @param str 备注
	 * @param prid 公出编号
	 */
	private void addWeChatNotice(String aid,Integer type,String str,Integer prid){
		Admin recipient = adminMapper.selectById(aid);
		addWeChatNotice(  recipient, type, str, prid);
	}

	/**
	 *	添加微信提示和站内消息
	 * @param recipient 接受者
	 * @param type 状态 0驳回 1发起 2同意 3撤销
	 * @param str
	 */
	private Integer addWeChatNotice(Admin recipient,Integer type,String str,Integer prid){
			AdminListBo my = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
			String openid=recipient.getOpenId();
			str=new StringBuffer("[").append(my.getName()).append("]").append(str).toString();
			if(type==3){
				addpublicLog(prid,4,str);
			}else {
				addpublicLog(prid,type,str);
			}
			sendNoticeAndSoucket(recipient.getId(),type,str);
			if (type==0||type==2){
				if (openid!=null) {
					Integer res= weChatUtils.addNotice(openid, type,prid,new Date(),my.getName(),str);
					return res;
				}else {
					sendEmail(my, recipient,type);
				}
			}

			return 0;
	}

	private int updateAssistant(PublicRelease p, String said, String sname) {
		PublicRelease newPr=new PublicRelease();
		newPr.setId(p.getId());
		newPr.setAssistantAid(said);
		newPr.setAssistantName(sname);
		if (p.getMainId()!=null){
			PublicRelease mianPr=new PublicRelease();
			mianPr.setId(p.getMainId());
//			mianPr.setAid(said);
			mianPr.setAssistantAid(said);
			mianPr.setAssistantName(sname);
			publicReleaseMapper.update(mianPr);
		}
		return publicReleaseMapper.update(newPr);
	}

	/**
	 *
	 * @param aid  元素
	 * @param list 集合
	 * @param type 0新增 1删除
	 * @return
	 */
	private String pushAssistant(String aid, List<String> list,Integer type) {
		StringBuffer sb=new StringBuffer();
		if(type==0){
			list.add(aid);
		}else if (type==1){
			Iterator<String > it =list.iterator();
			while (it.hasNext()){
				if (it.next().equals(aid))
					it.remove();
			}
		}
		for (String s : list) {
			sb.append(adminMapper.selectById(s).getName()).append(",");
		}
		return sb.length()>0?sb.substring(0,sb.length()-1):sb.toString();
	}



	@Override
	public int deleteAssistant(Integer id, String aid) {
		PublicRelease p = publicReleaseMapper.selectById(id);
		if (p.getAssistantAid()==null){
			throw new BusinessException("人员不存在");
		}
		List<String> list=new ArrayList<>(Arrays.asList(p.getAssistantAid().split(",")));
		if (!list.contains(aid)){
			throw new BusinessException("人员不存在");
		}
		String sname = pushAssistant(aid, list,1);
		String said =String.join(",",list);
		p.setAssistantAid(said);
		p.setAssistantName(sname);
		deleteAssistantPulicRelease(p,aid);
		return updateAssistant(p, said, sname);
	}



	private void deleteAssistantPulicRelease(PublicRelease p, String aid) {
		publicReleaseMapper.updateStatusByMainId(3,4,p.getMainId(),aid);
		List<PublicRelease> list = publicReleaseMapper.selectByMainId(p.getMainId(), 4, null);
		StringBuffer str=new StringBuffer();
		str=str.append("公出").append("[").append(p.getUserNames()).append("]").append("撤销了你的协助!");
		for (PublicRelease pr : list) {
			if (pr.getAid().equals(aid)){
				addWeChatNotice( pr.getAid(),3,str.toString(),pr.getId());
			}else {
				PublicRelease newPr=new PublicRelease();
				newPr.setId(pr.getId());
				newPr.setAssistantAid(p.getAssistantAid());
				newPr.setAssistantName(p.getAssistantName());
				publicReleaseMapper.update(newPr);
			}
		}
	}

	@Override
	public boolean checkdeleteAssistant(Integer id, String aid) {
		PublicRelease p = publicReleaseMapper.selectById(id);
		List<PublicRelease> list = publicReleaseMapper.selectByMainId(p.getMainId(), 4, aid);
		for (PublicRelease use : list) {
//			if (use.getClockIn()==1){
//				return true;
//			}
		}
		return false;
	}

	@Override
	public boolean checkaddAssistant(Integer id, String aid) {
		PublicRelease p = publicReleaseMapper.selectById(id);
		List<PublicRelease> list = publicReleaseMapper.selectByMainId(p.getMainId(), 4, aid);
		for (PublicRelease use : list) {
			if (use.getAid().equals(aid)&&use.getStatus()!=3){
				return true;
			}
		}
		return false;
	}

	@Override
	public int updateLocation(InputPublicRelease in) {
		PublicReleaseDetails prd=publicReleaseDetailsMapper.selectBypridAndUid(in);
		if (prd==null){
			throw  new BusinessException("公出企业不存在");
		}
		PublicReleaseDetails updateprd=new PublicReleaseDetails();
		updateprd.setId(prd.getId());
		updateprd.setLatitude(in.getLatitude());
		updateprd.setLongitude(in.getLongitude());
		updateprd.setDistrictName(in.getDistrictName());
		updateprd.setClockIn(0);
		addpublicLog(in.getId(),5,"发起公出地点修改");
		return publicReleaseDetailsMapper.update(updateprd);
	}

	@Override
	public Object publicReleaseAndCount(InputPublicDtails in) {
		List<OutPublicDtails> list = publicReleaseListDtailsList(in);
			Map<String,Object> map=new HashMap<String, Object>();
		if (list.isEmpty()){
			map.put("list",list);
			map.put("count",0);
			map.put("durationCount",0);
			map.put("peopleCount",0);
		}else {
			//公出次数
			int count=0;
			BigDecimal durationCount=BigDecimal.ZERO;
			List<String> aList =new ArrayList<>();
			for (OutPublicDtails e : list) {
				if (e.getType()==0||e.getType()==1||e.getType()==2){
					count++;
					if (e.getDuration()!=null){
						durationCount=durationCount.add(new BigDecimal(e.getDuration()));
					}
					if (!aList.contains(e.getAname())){
						aList.add(e.getAname());
					}
					if (StringUtils.isNotEmpty(e.getAssistAidName())){
						String[] split = e.getAssistAidName().split(",");
						for (String s : split) {
							if (!aList.contains(s)){
								aList.add(s);
							}
						}
					}
					if (StringUtils.isNotEmpty(e.getAssistantName())){
						String[] split = e.getAssistantName().split(",");
						for (String s : split) {
							if (!aList.contains(s)){
								aList.add(s);
							}
						}
					}
				}


			}
			map.put("list",list);
			map.put("count",count);
			map.put("durationCount",durationCount);
			map.put("peopleCount",aList.size());
		}

		return map;
	}

	/**
	 *
	 * @param in 公出参数
	 * @param a  新增时需哟额外知道当前任务
	 * @param type 0查询 1新增 2修改
	 * @return
	 */
	public Map checkOrderNoDuration( InputPublicRelease in,AdminListBo a,int type) {
		List<PublicRelease> list = publicReleaseMapper.selectByOrderNo(in.getOrderNo());
		TOrderNewBo t = tOrderNewMapper.getOrderNewDetail(in.getOrderNo());
		OutPublicRelease outPublicRelease=null;
		//实际公出
		BigDecimal actualDuration = BigDecimal.ZERO;
		//公出次数
		int frequency=0;
		List<String> peopleList = new ArrayList<>();
		//判定是不是新增获取原数据，是新增数量加1
		if (in.getId()!=null){
			outPublicRelease= publicReleaseMapper.selectDtails(in.getId());
		}else {
			peopleList.add(TokenManager.getAdminId());
			actualDuration=actualDuration.add(BigDecimal.valueOf(in.getDuration()));
			frequency++;
		}
		for (PublicRelease e : list) {
				//新增直接计算
				if (in.getId()==null){
					if (e.getDuration()!=null){
						actualDuration=actualDuration.add(BigDecimal.valueOf(e.getDuration()));
						if (!peopleList.contains(e.getAid())){
							peopleList.add(e.getAid());
						}
						frequency++;
					}
				}else {
					//修改当前数据要从修改后获取
					if (!e.getId().equals(in.getId())){
						if (e.getDuration()!=null){
							actualDuration=actualDuration.add(BigDecimal.valueOf(e.getDuration()));
							if (!peopleList.contains(e.getAid())){
								peopleList.add(e.getAid());
							}
							frequency++;
						}
					}else {
						if (outPublicRelease != null && outPublicRelease.getDuration() != null) {
							actualDuration = actualDuration.add(BigDecimal.valueOf(outPublicRelease.getDuration()));
							if (!peopleList.contains(outPublicRelease.getAid())) {
								peopleList.add(outPublicRelease.getAid());
							}
							frequency++;
						}
					}
				}
		}
		Map map=new HashMap();
		CheckOrderNoOut data= new CheckOrderNoOut();
		if (outPublicRelease!=null){
			data.setPublicReleaseName(outPublicRelease.getAname());
		}
		//新增与修改，需要重新获取实际公出与人数与次数
		if (type==1||type==2){
			TOrderPublicReleaseCount update=new TOrderPublicReleaseCount();
			update.setOrderNo(in.getOrderNo());
			update.setFrequency(frequency);
			update.setActualDuration(actualDuration.doubleValue());
			update.setPeopleCount(peopleList.size());
			tOrderPublicReleaseCountMapper.updateByOrderNo(update);
		}
		List<OrderYearMaxDuration> orderYearMaxDurations = orderYearMaxDurationMapper.selectByOrderNo(in.getOrderNo());
		data.setTimesCount(frequency);
		data.setPeopleCount(peopleList.size());
		data.setUserName(t.getUserName());
		data.setContractNo(t.getContractNo());
		data.setAdminName(t.getSalesmanName());
		data.setDurationCount(actualDuration);
        TOrderPublicReleaseCount releaseCount = tOrderPublicReleaseCountMapper.selectByOrderNo(in.getOrderNo());
        data.setDurationMax(BigDecimal.valueOf(releaseCount.getMaxDuration()));
		TOrderNew tOrderNew = tOrderNewMapper.queryById(in.getOrderNo());
		List<TTaskMember> tTaskMembers = tTaskMemberMapper.selectByOrderNo(tOrderNew.getOrderNo());
		String amountName=null;
		String amountType=null;
		if (releaseCount.getMaxType()==2){
			map.put("code",true);
			map.put("data",null);
		}else {
			if (tTaskMembers.size()<1){
				if (tOrderNew.getTotalAmount().compareTo(BigDecimal.valueOf(1))<0){
					amountName="本合同低于1万";
					amountType="原则上技术人员不可下户";
				}else if (tOrderNew.getTotalAmount().compareTo(BigDecimal.valueOf(3))<0){
					amountName="本合同在1~3万";
					amountType="已超出合同可公出标准"+data.getDurationMax()+"小时";
				}else if (tOrderNew.getTotalAmount().compareTo(BigDecimal.valueOf(5))<0){
					amountName="本合同在3~5万";
					amountType="已超出合同可公出标准"+data.getDurationMax()+"小时";
				}else if (tOrderNew.getTotalAmount().compareTo(BigDecimal.valueOf(10))<0){
					amountName="本合同在5~10万";
					amountType="已超出合同可公出标准"+data.getDurationMax()+"小时";
				}
			}else {
				int yearSum=1;
				for (TTaskMember tTaskMember : tTaskMembers) {
					if (tTaskMember.getYearSum()!=null&&tTaskMember.getYearSum()>yearSum){
						yearSum=tTaskMember.getYearSum();
					}
				}
				BigDecimal divide =BigDecimal.ZERO;
				if (tOrderNew.getTotalAmount().compareTo(BigDecimal.valueOf(0))>0&&yearSum>0){
					divide=tOrderNew.getTotalAmount().divide(BigDecimal.valueOf(yearSum),  BigDecimal.ROUND_HALF_UP);
				}else {
					divide=tOrderNew.getTotalAmount();
				}
				if (divide.compareTo(BigDecimal.valueOf(1))<0){
					amountName="此会员订单，本年度金额低于1万";
					amountType="原则上技术人员不可下户";
				}else if (divide.compareTo(BigDecimal.valueOf(3))<0){
					amountName="此会员订单，本年度金额1~3万";
					amountType="已超出合同可公出标准"+data.getDurationMax()+"小时";
				}else if (divide.compareTo(BigDecimal.valueOf(5))<0){
					amountName="此会员订单，本年度金额3~5万";
					amountType="已超出合同可公出标准"+data.getDurationMax()+"小时";
				}else if (divide.compareTo(BigDecimal.valueOf(10))<0){
					amountName="此会员订单，本年度金额5~10万";
					amountType="已超出合同可公出标准"+data.getDurationMax()+"小时";
				}
			}
			data.setAmountName(amountName);
			data.setAmountType(amountType);
			map.put("releaseCount",releaseCount);
			//如果小于或者等于并且是未发起或者审核完成状态
			if (actualDuration.compareTo(data.getDurationMax())<1&&
					(releaseCount.getMaxProcess()==0||releaseCount.getMaxProcess()==4)
			){
				map.put("code",true);
				map.put("data",null);
			}else {
				map.put("code",false);
				map.put("data",data);
			}
		}
		return map;
	}
	@Override
	public Map checkOrderNoDuration( InputPublicRelease in){
		return checkOrderNoDuration(in,null,0);
	}

	@Override
	public void pushOutPublicDtails(List<OutPublicDtails> list) {
		List<PublicReleaseClock> publicReleaseClocks = publicReleaseClockMapper.selectList(list.stream().map(OutPublicDtails::getId).collect(Collectors.toList()));
		pushiClockInTime(list, publicReleaseClocks);
	}



	private void pushiClockInTime(List<OutPublicDtails> list, List<PublicReleaseClock> publicReleaseClocks) {
		for (OutPublicDtails outPublicDtails : list) {
			if (outPublicDtails.getClockIn()!=null){
				if (outPublicDtails.getAlone()==2&&outPublicDtails.getAssist()==1){
					outPublicDtails.setClockInStr("无需打卡");
				}else if (outPublicDtails.getClockIn()==0)outPublicDtails.setClockInStr("未打卡");
				else if (outPublicDtails.getClockIn()==1)outPublicDtails.setClockInStr("已打卡");
				else if (outPublicDtails.getClockIn()==2)outPublicDtails.setClockInStr("异常打卡");
			}
			List<PublicReleaseClock> colokList =new ArrayList<>();
			StringBuilder sb = new StringBuilder();
			for (PublicReleaseClock e : publicReleaseClocks) {
				if (outPublicDtails.getPrdId().equals(e.getPrdid())){
					sb.append(DateUtils.formatDateYYYYMMddHHmm(e.getClockInTime())).append("\n");
					colokList.add(e);
				}
				colokList.sort(Comparator.comparing(PublicReleaseClock::getClockInTime));
				Collections.reverse(colokList);
				outPublicDtails.setList(colokList);
			}
			outPublicDtails.setClockInTimes(sb.toString());
			List<UserInterviewProjectBo> userInterviewProjectBos = userInterviewProjectMapper.selectByPrdId(outPublicDtails.getPrdId());
			if (userInterviewProjectBos.size()>0){
				StringBuilder builder = new StringBuilder();
				userInterviewProjectBos.forEach(e -> {
					if (e.getName()!=null)builder.append(e.getName());
					if (e.getExamineStatus()!=null){
						if (e.getExamineStatus()==1){
							builder.append("(初次审核)");
						}else if (e.getExamineStatus()==2){
							builder.append("(复审 ").append(e.getExamineStatusOther()).append(")");
						}
					}
					if (e.getBuyStatus()!=null){
						if (e.getBuyStatus()==1){
							builder.append("(新购)");
						}else if (e.getBuyStatus()==2){
							builder.append("(复购 ").append(e.getBuyStatusOther()).append(")");
						}
					}
					builder.append(",");
				});
				outPublicDtails.setInterviewProject(builder.substring(0,builder.length()-1));
			}

		}
	}
	@Override
	public Object pushDateClock() {
		List<PublicRelease> publicReleases = publicReleaseMapper.selectAll();
		for (PublicRelease e : publicReleases) {
			addPublicReleaseDateClock(e);
		}
		return 1;
	}


	private void addPublicReleaseDateClock(PublicRelease e) {
		publicReleaseDateClockMapper.deleteByPrid(e.getId());
		List<PublicReleaseDateClock> list= new ArrayList<>();
		if (e.getValidDate()!=null){
			List<Map> maps = JSONArray.parseArray(e.getValidDate(), Map.class);
			for (Map map : maps) {
				String dates = (String) map.get("value");
				if (dates!=null){
					Date date = DateUtils.parseDate(dates);
					List<OutPublicReleaseDetails> outPublicReleaseDetails = publicReleaseDetailsMapper.selectByPrid(e.getId());
					for (OutPublicReleaseDetails det : outPublicReleaseDetails) {
						PublicReleaseDateClock newPRDC = new PublicReleaseDateClock();
						newPRDC.setClockInTime(date);
						newPRDC.setPrid(e.getId());
						newPRDC.setPrdid(det.getId());
						newPRDC.setStatus(det.getClockIn());
						list.add(newPRDC);
					}

				}

			}
		}
		if(!list.isEmpty()){
			publicReleaseDateClockMapper.insertBatch(list);
			list.clear();
		}
	}




	@Override
	@Cacheable(value = "releaseAndExpenseCount#300", key = "'getCounts:key='+#in.buyerName+#in.contractNo+#in.aid+#in.depId+#in.allStatus+#in.startTime+#in.endTime")
	public List<releaseAndExpenseCountOut> releaseAndExpenseCount(InputreleaseAndExpenseCount in) {
		if (in.getEndTime()!=null)in.setEndTime(in.getEndTime()+" 23:59:59");
		List<releaseAndExpenseCountOut> expenseCountsOrders = publicReleaseMapper.releaseAndExpenseCount(in);
		expenseCountsOrders.forEach(e->{
			if (e.getExceedDuration()!=null){
				double exceedDuration = Double.parseDouble(e.getExceedDuration());
				if (exceedDuration>0){
					e.setExceedType(1);
				}
			}
			if (StringUtils.isNotEmpty(e.getOrderNo())){
				BigDecimal maxDuration = new BigDecimal(e.getMaxDuration());
				if (e.getMaxType()==2){
					e.setMaxDuration("预"+e.getMaxDuration());
				} else if (e.getMaxType()==0) {
					e.setMaxDuration("0");
				}
				if(!e.getActualDuration().equals("0")){
					if (maxDuration.compareTo(new BigDecimal(e.getActualDuration()))>=0){
						e.setExceedDuration("0");
					}else {
						e.setExceedDuration(new BigDecimal(e.getActualDuration()).subtract(maxDuration).toString());
					}
				}
			}
		});
		return expenseCountsOrders;
	}

	@Override
	@CacheEvict(value = "releaseAndExpenseCount#300",allEntries = true)
	public Object releaseAndExpenseCountClear() {
		LoggerUtils.debug(getClass(),"公出&报销缓存清除。");
		return 1;
	}


}
