package com.boying.service.impl; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.boying.entity.CostRule; import com.boying.mapper.CostRuleMapper; import com.boying.service.CostRuleService; import com.boying.util.DateUtilOther; import org.springframework.stereotype.Service; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; /** * @author kdq * @version 1.0.0 * @ClassName CostRuleServiceImpl.java * @Description TODO * @createTime 2022年11月20日 22:56:00 */ @Service public class CostRuleServiceImpl extends ServiceImpl implements CostRuleService { @Override public double getMoney(Integer parkId, LocalDateTime startTime, LocalDateTime endTime, int isJun) throws ParseException { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda() .eq(CostRule::getParkId,parkId); List list = list(wrapper); if(list.size()==0){ return 0; }else{ CostRule costRule = list.get(0); //判断是否是军牌免费 if(costRule.getArmyCar()==isJun){ return 0; } //如果在免费时间内,不收费 long l = (endTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() - startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()) / (1000 * 60); if(Math.abs(l)<=costRule.getFreeTime()){ return 0; } return jiSuan2(costRule,startTime,endTime,0.0); } } private double jiSuan2(CostRule costRule, LocalDateTime startDate, LocalDateTime endDate, double sum)throws ParseException { Date startTime = Date.from(startDate.toInstant(ZoneOffset.of("+8"))); Date endTime = Date.from(endDate.toInstant(ZoneOffset.of("+8"))); Calendar cal = Calendar.getInstance(); cal.setTime(startTime); cal.add(Calendar.MINUTE,costRule.getFreeTime()); startTime = cal.getTime(); int dynum = 0; //时间段1 String cst1 = costRule.getChargeStartTime1(); String cet1 = costRule.getChargeEndTime1(); String s1 = cst1.substring(0,2); String e1 = cet1.substring(0,2); //时间段2 String cst2 = costRule.getChargeStartTime2(); String cet2 = costRule.getChargeEndTime2(); String s2 = cst2.substring(0,2); String e2 = cet2.substring(0,2); //时间段3 String cst3 = costRule.getChargeStartTime3(); String cet3 = costRule.getChargeEndTime3(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String format = sdf.format(startTime); boolean flag = true; while(flag){ //判断开始时间处于哪个时间段 if(Integer.valueOf(s1) < Integer.valueOf(e1)){ Date d1 = DateUtilOther.stringToDate(format+" "+cst1,null); Date d1st2 = DateUtilOther.stringToDate(format+" "+cst2,null); //时间大于第一规则开始时间小于第二规则开始时间 if(startTime.getTime()>=d1.getTime() && startTime.getTime() Integer.valueOf(e2)){ //如果第二个时间段夸天了 //例如:2022-12-23 08:00:00 Date d22 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet2,null); if(endTime.getTime()<=d22.getTime()){ //在第二个时间段里 double money1 = money3(costRule,endTime.getTime() - d1st2.getTime(), costRule.getCost2(), costRule.getMaxCost2()); dynum++; return money1+money+sum; }else { //如果超过了第二时间段的结束时间,则跨天 double money2 = money3(costRule,d22.getTime() - d1st2.getTime(), costRule.getCost2(), costRule.getMaxCost2()); dynum++; Calendar calendar = new GregorianCalendar(); calendar.setTime(DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet2,null)); // 这个时间就是日期往后推一天的结果 startTime = calendar.getTime(); format = sdf.format(startTime); sum += money2 + money; } } } }else { Calendar calendar1 = Calendar.getInstance(); calendar1.setTime(startTime); int i = calendar1.get(Calendar.HOUR_OF_DAY); if(i <= 24 && i >= Integer.parseInt(s2)){ //处于第一天 //则开始时间处于第二规则里 if(Integer.valueOf(s2) > Integer.valueOf(e2)){ Date d22 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet2,null); if(endTime.getTime() < d22.getTime()){ //全部处于第二时间段 double v = money3(costRule,endTime.getTime() - startTime.getTime(),costRule.getCost2(),costRule.getMaxCost2())+sum; if(dynum == 0){ if((v + 2.5) Integer.valueOf(e2)){ Date d22 = DateUtilOther.stringToDate(format+" "+cet2,null); if(endTime.getTime() < d22.getTime()){ //全部处于第二时间段 double v = money3(costRule,endTime.getTime() - startTime.getTime(),costRule.getCost2(),costRule.getMaxCost2())+sum; if(dynum == 0){ if((v + 2.5) =d1.getTime()){ Date d2 =DateUtilOther.stringToDate(format+" "+cet1,null); if(endTime.getTime() Integer.valueOf(e2)){ //如果第二个时间段夸天了 Date d21 = DateUtilOther.stringToDate(format+" "+cst2,null); Date d22 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet2,null); if(endTime.getTime()<=d22.getTime()){ //如果在第二时间段内 double money1 = money2(costRule,endTime.getTime() - d21.getTime(), costRule.getCost2(), costRule.getMaxCost2()); return money1+money+sum; }else{ //如果超过了第二时间段的结束时间,判断是否在第三时间段 double money2 = money2(costRule,d22.getTime() - d21.getTime(), costRule.getCost2(), costRule.getMaxCost2()); if(StringUtils.isNotBlank(cst3)&&StringUtils.isNotBlank(cet3)&&costRule.getCost3()!=null){ String s3 = cst3.substring(0,2); String e3 = cet3.substring(0,2); //必须是不夸天的 Date d31 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cst3,null); Date d32 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet3,null); if(endTime.getTime()<=d32.getTime()){ //如果在第三时间段内 double money1 = money2(costRule,endTime.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); return money1+money2+sum; }else{ //如果不在,日期+1循环 double money3 = money2(costRule,d32.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); sum+=money+money2+money3; //jiSuan(costRule,DateUtil.getYearMoneyDay4(format,cst1),endTime,sum); startTime = DateUtilOther.getYearMoneyDay4(format,cst1); } }else{ sum+=money+money2; startTime = DateUtilOther.getYearMoneyDay4(format,cst1); } } }else{ //如果没夸天 Date d21 = DateUtilOther.stringToDate(format+" "+cst2,null); Date d22 = DateUtilOther.stringToDate(format+" "+cet2,null); if(endTime.getTime()<=d22.getTime()){ //如果在第二时间段内 double money1 = money2(costRule,endTime.getTime() - d21.getTime(), costRule.getCost2(), costRule.getMaxCost2()); return money1+money+sum; }else{ //如果超过了第二时间段的结束时间,判断是否在第三时间段 double money2 = money2(costRule,d22.getTime() - d21.getTime(), costRule.getCost2(), costRule.getMaxCost2()); if(StringUtils.isNotBlank(cst3)&&StringUtils.isNotBlank(cet3)&&costRule.getCost3()!=null){ String s3 = cst3.substring(0,2); String e3 = cet3.substring(0,2); //如果是不夸天的 if(Integer.valueOf(s3) < Integer.valueOf(e3)){ Date d31 = DateUtilOther.stringToDate(format+" "+cst3,null); Date d32 = DateUtilOther.stringToDate(format+" "+cet3,null); if(endTime.getTime()<=d32.getTime()){ //如果在第三时间段内 double money1 = money2(costRule,endTime.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); return money+money1+money2; }else{ //如果还是超出第三时间段的结束时间,那么日期+1继续执行一遍这个动作 double money3 = money2(costRule,d32.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); sum+=money+money2+money3; startTime = DateUtilOther.getYearMoneyDay4(format,cst1); } }else{ //如果夸天了 Date d31 = DateUtilOther.stringToDate(format+" "+cst3,null); Date d32 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet3,null); if(endTime.getTime()<=d32.getTime()){ //如果在第三时间段内 double money1 = money2(costRule,endTime.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); return money+money1+money2+sum; }else{ //如果还是超出第三时间段的结束时间,那么日期+1继续执行一遍这个动作 double money3 = money2(costRule,d32.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); sum+=money+money2+money3; startTime = DateUtilOther.getYearMoneyDay4(format,cst1); } } }else{ sum+=money+money2; startTime = DateUtilOther.getYearMoneyDay4(format,cst1); } } } }else{ sum+=money; startTime = DateUtilOther.getYearMoneyDay4(format,cst1); } } }else{ //如果停车开始日期在设定的开始日期之后,则按照逻辑顺序按天依次计算。 if(StringUtils.isNotBlank(cst2)&&StringUtils.isNotBlank(cet2)&&costRule.getCost2()!=null) { String s2 = cst2.substring(0,2); String e2 = cet2.substring(0,2); //判断第二个时段是否夸天 if(Integer.valueOf(s2) > Integer.valueOf(e2)){ //如果第二个时间段夸天了 Date d21 = DateUtilOther.stringToDate(format+" 00:00:00",null); Date d22 = DateUtilOther.stringToDate(format+" "+cet2,null); if(endTime.getTime()<=d22.getTime()){ //如果在第二时间段内 double money1 = money2(costRule,endTime.getTime() - startTime.getTime(), costRule.getCost2(), costRule.getMaxCost2()); return money1+sum; }else{ //如果超过了第二时间段的结束时间,判断是否在第三时间段 double money2 = money2(costRule,d22.getTime() - startTime.getTime(), costRule.getCost2(), costRule.getMaxCost2()); if(StringUtils.isNotBlank(cst3)&&StringUtils.isNotBlank(cet3)&&costRule.getCost3()!=null){ String s3 = cst3.substring(0,2); String e3 = cet3.substring(0,2); if(Integer.valueOf(s3) > Integer.valueOf(e3)){ return 0; } //必须是不夸天的 Date d31 = DateUtilOther.stringToDate(format+" "+cst3,null); Date d32 = DateUtilOther.stringToDate(format+" "+cet3,null); if(endTime.getTime()<=d32.getTime()){ //如果在第三时间段内 double money1 = money2(costRule,endTime.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); return money1+money2+sum; }else{ //如果不在,日期+1循环 double money3 = money2(costRule,d32.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); sum+=money2+money3; startTime = DateUtilOther.stringToDate(format+" "+cst1,null); } }else{ sum+=money2; startTime = DateUtilOther.stringToDate(format+" "+cst1,null); } } }else{ if(StringUtils.isNotBlank(cst3)&&StringUtils.isNotBlank(cet3)&&costRule.getCost3()!=null){ String s3 = cst3.substring(0,2); String e3 = cet3.substring(0,2); //如果是不夸天的 if(Integer.valueOf(s3) < Integer.valueOf(e3)){ startTime = DateUtilOther.stringToDate(format+" "+cst1,null); }else{ //如果夸天了 Date d31 = DateUtilOther.stringToDate(format+" 00:00:00",null); Date d32 = DateUtilOther.stringToDate(format+" "+cet3,null); if(endTime.getTime()<=d32.getTime()){ //如果在第三时间段内 double money1 = money2(costRule,endTime.getTime()- d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); return money1+sum; }else{ //如果还是超出第三时间段的结束时间,那么日期+1继续执行一遍这个动作 double money3 = money2(costRule,d32.getTime() - d31.getTime(), costRule.getCost3(), costRule.getMaxCost3()); sum+=money3; startTime = DateUtilOther.stringToDate(format+" "+cst1,null); } } }else{ startTime = DateUtilOther.stringToDate(format+" "+cst1,null); } } }else{ startTime = DateUtilOther.stringToDate(format+" "+cst1,null); } } } } } return sum; } private double money(CostRule costRule,long l, Double cost, Integer maxCost) { l=l/(1000*60)-costRule.getFreeTime(); int time = 0; if(((l*1.0)/30)>(l/30)){//判断停车时间是否要加1 time = Long.valueOf(l / 30 + 1).intValue(); }else{ time = Long.valueOf(l / 30).intValue(); } if(maxCost!=null){ if(time*cost+2.5>maxCost){//大于封顶价格 return maxCost; }else { return time*cost+2.5; } }else { return time*cost+2.5; } } private double money2(CostRule costRule,long l, Double cost, Integer maxCost) { l=l/(1000*60); int time = 0; if(((l*1.0)/30)>(l/30)){//判断停车时间是否要加1 time = Long.valueOf(l / 30 + 1).intValue(); }else{ time = Long.valueOf(l / 30).intValue(); } if(maxCost!=null){ if(time*cost>maxCost){//大于封顶价格 return maxCost; }else { return time*cost; } }else { return time*cost; } } private double money3(CostRule costRule,long l, Double cost, Integer maxCost) { l=l/(1000*60); int time = 0; if(((l*1.0)/30)>(l/30)){//判断停车时间是否要加1 time = Long.valueOf(l / 30 + 1).intValue(); }else{ time = Long.valueOf(l / 30).intValue(); } if(maxCost!=null){ if(time*cost>maxCost){//大于封顶价格 return maxCost; }else { return time*cost; } }else { return time*cost; } } public static void main(String[] args) { // System.out.println(((30*1.0)/30)>(30/30)); } }