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<CostRuleMapper, CostRule> implements CostRuleService {
|
@Override
|
public double getMoney(Integer parkId, LocalDateTime startTime, LocalDateTime endTime, int isJun) throws ParseException {
|
QueryWrapper<CostRule> wrapper = new QueryWrapper<>();
|
wrapper.lambda()
|
.eq(CostRule::getParkId,parkId);
|
List<CostRule> 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()<d1st2.getTime()){
|
Date d2 =DateUtilOther.stringToDate(format+" "+cet1,null);
|
//都处在第一规则里
|
if(endTime.getTime()<d2.getTime()){
|
double v = money3(costRule, endTime.getTime() - startTime.getTime(), costRule.getCost1(), costRule.getMaxCost1()) + sum;
|
if(dynum == 0){
|
if((v + 2.5) <costRule.getMaxCost1()){
|
return v + 2.5;
|
}else {
|
return costRule.getMaxCost1();
|
}
|
}else {
|
return v;
|
}
|
|
}else {
|
//如果超过了时间段1的结束时间,判断是否在第二时间段
|
double money = money3(costRule,d2.getTime() - startTime.getTime(), costRule.getCost1(), costRule.getMaxCost1());
|
if(money < costRule.getMaxCost1() && dynum==0){
|
if((money+2.5) < costRule.getMaxCost1()){
|
money = money+2.5;
|
}else {
|
money = costRule.getMaxCost1();
|
}
|
}
|
dynum++;
|
//判断第二个时间段是否跨天
|
if(Integer.valueOf(s2) > 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) <costRule.getMaxCost1()){
|
return v + 2.5;
|
}else {
|
return costRule.getMaxCost1();
|
}
|
}else {
|
return v;
|
}
|
}else {
|
double money = money3(costRule,d22.getTime() - startTime.getTime(), costRule.getCost2(), costRule.getMaxCost2());
|
if(money < costRule.getMaxCost2() && dynum==0){
|
if((money+2.5) < costRule.getMaxCost2()){
|
money = money+2.5;
|
}else {
|
money = costRule.getMaxCost2();
|
}
|
}
|
dynum++;
|
Date d12 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cet1,null);
|
Date d11 = DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cst1,null);
|
if(endTime.getTime() < d12.getTime()){
|
double money1 = money3(costRule,endTime.getTime() - d11.getTime(), costRule.getCost1(), costRule.getMaxCost1());
|
dynum++;
|
return money1+money+sum;
|
}else {
|
double money2 = money3(costRule,d12.getTime() - d11.getTime(), costRule.getCost1(), costRule.getMaxCost1());
|
dynum++;
|
Calendar calendar = new GregorianCalendar();
|
calendar.setTime(DateUtilOther.stringToDate(DateUtilOther.getYearMoneyDay3(format)+" "+cst2,null));
|
// 把日期往后增加一天,整数 往后推,负数往前移动
|
// 这个时间就是日期往后推一天的结果
|
startTime = calendar.getTime();
|
format = sdf.format(startTime);
|
sum = money2 + money +sum;
|
}
|
}
|
}
|
}else {
|
//处于第二天凌晨
|
if(Integer.valueOf(s2) > 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) <costRule.getMaxCost2()){
|
return v + 2.5;
|
}else {
|
return costRule.getMaxCost2();
|
}
|
}else {
|
return v;
|
}
|
}else {
|
double money = money3(costRule,d22.getTime() - startTime.getTime(), costRule.getCost2(), costRule.getMaxCost2());
|
if(money < costRule.getMaxCost2() && dynum==0){
|
if((money+2.5) < costRule.getMaxCost2()){
|
money = money+2.5;
|
}else {
|
money = costRule.getMaxCost2();
|
}
|
}
|
dynum++;
|
Date d12 = DateUtilOther.stringToDate(format+" "+cet1,null);
|
Date d11 = DateUtilOther.stringToDate(format+" "+cst1,null);
|
if(endTime.getTime() < d12.getTime()){
|
double money1 = money3(costRule,endTime.getTime() - d11.getTime(), costRule.getCost1(), costRule.getMaxCost1());
|
dynum++;
|
return money1+money+sum;
|
}else {
|
double money2 = money3(costRule,d12.getTime() - d11.getTime(), costRule.getCost1(), costRule.getMaxCost1());
|
dynum++;
|
Calendar calendar = new GregorianCalendar();
|
calendar.setTime(DateUtilOther.stringToDate(format+" "+cst2,null));
|
// 这个时间就是日期往后推一天的结果
|
startTime = calendar.getTime();
|
format = sdf.format(startTime);
|
sum = money2 + money;
|
}
|
|
}
|
}
|
}
|
|
}
|
}
|
}
|
return sum;
|
}
|
|
private double jiSuan(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")));
|
boolean flag = true;
|
while(flag){
|
//时间段1
|
String cst1 = costRule.getChargeStartTime1();
|
String cet1 = costRule.getChargeEndTime1();
|
|
//时间段2
|
String cst2 = costRule.getChargeStartTime2();
|
String cet2 = costRule.getChargeEndTime2();
|
|
//时间段3
|
String cst3 = costRule.getChargeStartTime3();
|
String cet3 = costRule.getChargeEndTime3();
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
String format = sdf.format(startTime);
|
|
if(StringUtils.isNotBlank(cst1)&&StringUtils.isNotBlank(cet1)&&costRule.getCost1()!=null){
|
String s1 = cst1.substring(0,2);
|
String e1 = cet1.substring(0,2);
|
|
//如果是不夸天的
|
if(Integer.valueOf(s1) < Integer.valueOf(e1)){
|
Date d1 = DateUtilOther.stringToDate(format+" "+cst1,null);
|
//如果停车开始日期在设定的开始日期之后,则按照逻辑顺序按天依次计算。
|
if(startTime.getTime()>=d1.getTime()){
|
Date d2 =DateUtilOther.stringToDate(format+" "+cet1,null);
|
if(endTime.getTime()<d2.getTime()){
|
//如果在时间段1之间
|
return money(costRule,endTime.getTime() - startTime.getTime(),costRule.getCost1(),costRule.getMaxCost1())+sum;
|
}else{
|
//如果超过了时间段1的结束时间,判断是否在第二时间段
|
double money = money(costRule,d2.getTime() - startTime.getTime(), costRule.getCost1(), costRule.getMaxCost1());
|
|
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+" "+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));
|
}
|
}
|