package com.zteits.bill.biz.discount; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import cn.hutool.cache.impl.TimedCache; import com.clouds.common.constants.CarTypeEnum; import com.clouds.common.constants.HolidayEnum; import com.clouds.common.utils.BeanValidatorsUtils; import com.clouds.common.utils.ResultUtils; import com.github.pagehelper.util.StringUtil; import com.zteits.bill.configuration.TimedCacheFactory; import com.zteits.bill.dao.discount.ActivityDiscountDao; import com.zteits.bill.dao.discount.ActivityDiscountRuleDao; import com.zteits.bill.domain.DiscontRuleForParkDO; import com.zteits.bill.domain.TActivityDiscountRule; import com.zteits.clouds.api.apibase.bean.BizResult; import com.zteits.clouds.api.apibase.constants.BasicEnum; import com.zteits.clouds.api.apibase.constants.ErrorType; import com.zteits.clouds.api.apibase.constants.ParkDetailTypeEnum; import com.zteits.clouds.api.apibase.constants.PayTypeEnum; import com.zteits.clouds.api.apibase.exception.BizException; import com.zteits.clouds.api.dto.bill.discount.dto.ActivityDiscountRuleDTO; import com.zteits.clouds.api.dto.bill.discount.dto.BillingOfDiscountDTO; import com.zteits.clouds.api.dto.bill.discount.dto.DiscontRuleForParkDTO; import com.zteits.clouds.api.dto.bill.discount.dto.TActivityDiscountSpecialCarDTO; import com.zteits.clouds.api.dto.bill.discount.param.BillingOfDiscountReq; import com.zteits.clouds.api.dto.bill.discount.param.CheckDiscountUniqueByPlNoRequest; import com.zteits.clouds.api.dto.bill.discount.param.QueryDiscountRuleRequest; import com.zteits.clouds.api.dto.bill.discount.param.QueryDiscountSpecialCarRequest; import com.zteits.clouds.api.dto.bill.holiday.dto.SpHolidaysDTO; import com.zteits.clouds.api.dto.bill.holiday.param.DaysInfoQueryReq; import com.zteits.clouds.api.dto.bill.vipcard.param.NewEnergyCarDiscountQueryReq; import com.zteits.clouds.api.dto.bill.whitelist.CarNumIsFreeDTO; import com.zteits.clouds.api.dto.bill.whitelist.param.QueryCarNumIsWhitelistRequest; import com.zteits.clouds.api.service.bill.billrule.DiscountSpecialCarService; import com.zteits.clouds.api.service.bill.discount.DiscountService; import com.zteits.clouds.api.service.bill.holiday.HolidayService; import com.zteits.clouds.api.service.bill.whitelist.WhitelistService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; /** * Copyright: Copyright (c) 2017 zteits * * @ClassName: com.zteits.billing.biz.discount * @Description: * @version: v1.0.0 * @author: atao * @date: 2017/11/6 下午1:49 * Modification History: * Date Author Version Description * ---------------------------------------------------------* * 2017/11/6 atao v1.0.0 创建 */ @Service("com.zteits.bill.biz.discount.DiscountServiceImpl") public class DiscountServiceImpl implements DiscountService { private static final Logger logger = LoggerFactory.getLogger(DiscountServiceImpl.class); @Autowired private ActivityDiscountRuleDao activityDiscountRuleDao; @Autowired private ActivityDiscountDao activityDiscountDao; @Autowired private HolidayService holidayService; @Autowired private WhitelistService whitelistService; @Autowired private DiscountSpecialCarService discountSpecialCarService; /** * 是否有时间限制:1:是 0:否. */ private static final Integer IS_TIMME_LIMIT = 1; @Override public BizResult billingOfDiscount(BillingOfDiscountReq req) { if (StringUtils.isEmpty(req.getDiscountRuleNo())) { throw new BizException(ErrorType.PARAMM_NULL, "折扣规则编码"); } if (null == req.getFee()) { throw new BizException(ErrorType.PARAMM_NULL, "应收金额"); } BillingOfDiscountDTO result = new BillingOfDiscountDTO(); TActivityDiscountRule discountRule = activityDiscountRuleDao.queryDiscountRuleByDiscNo(req.getDiscountRuleNo()); if (null == discountRule) { //没有折扣规则 result.setDiscountRuleDTO(null); result.setDiscValue(null); result.setRealFee(req.getFee()); result.setReceFee(req.getFee()); } else { //有折扣规则 ActivityDiscountRuleDTO dto = new ActivityDiscountRuleDTO(); BeanUtils.copyProperties(discountRule, dto); result.setDiscountRuleDTO(dto); result.setDiscValue(dto.getDiscValue()); result.setRealFee(req.getFee() * Math.round(Double.valueOf(dto.getDiscValue()) / 10)); result.setReceFee(req.getFee()); } return new BizResult<>(result); } /** * 通过停车场编码,折扣类型,终端来源,车辆类型,出场时间查询停车场所有折扣规则.
* * @param request * @return */ @Override public BizResult> queryDiscontRuleForList(QueryDiscountRuleRequest request) throws Exception { logger.info("---begin停车场所有折扣规则,入参={}", JSONObject.toJSON(request)); List listDTO = new ArrayList(); //查询车辆是否属于每天只收一次费用 的白名单车辆 try { QueryCarNumIsWhitelistRequest queryCarNumIsWhitelistRequest = new QueryCarNumIsWhitelistRequest(); queryCarNumIsWhitelistRequest.setPlNo(request.getPlNo()); queryCarNumIsWhitelistRequest.setCarNumber(request.getCarNo()); queryCarNumIsWhitelistRequest.setCarType(request.getDisCarTpye()); BizResult carNumIsFreeDTOBizResult = whitelistService.queryCarNumIsOnlyOneFeeEveryDay( queryCarNumIsWhitelistRequest); CarNumIsFreeDTO carNumIsFreeDTO = ResultUtils.getBizResultData(carNumIsFreeDTOBizResult); logger.info("查询车辆信息是否属于每天只收一次费用的白名单车辆用户信息 carNumber={},plNo={},响应为:{}", request.getCarNo(), request.getPlNo(), JSONObject.toJSONString(carNumIsFreeDTOBizResult)); if (null != carNumIsFreeDTO.getFreeReason() && ParkDetailTypeEnum.WhiteListCar.equals( carNumIsFreeDTO.getFreeReason())) { return new BizResult<>(listDTO); } } catch (Exception e) { logger.error("查询车辆信息是否属于每天只收一次费用的白名单车辆用户信息 carNumber={},plNo={}, 捕获异常:", request.getCarNo(), request.getPlNo(), e); throw new BizException(ErrorType.BIZ_ERROR,"查询白名单车辆用户信息失败!"); } //折扣缓存1分钟 TimedCache timedCache = TimedCacheFactory.getTimedCache(); String key = ""; if (StringUtils.isEmpty(request.getCarNo())) { key = request.getPlNo() + request.getDiscTerminalRes() + request.getDisCarTpye() + request.getDiscType(); } else { key = request.getPlNo() + request.getDiscTerminalRes() + request.getDisCarTpye() + request.getDiscType() + request.getCarNo(); } if(request.getPayType() != null){ key += request.getPayType(); // getPayType V5 V36 } logger.info("缓存对应折扣key"+key); String value = timedCache.get(key, false); logger.info("缓存对应折扣value"+value); if (StringUtils.isEmpty(value)) { logger.info("缓存没有找到对应折扣,调用服务查询"); listDTO = getDiscontRuleForParkDTOS(request); if (CollectionUtils.isEmpty(listDTO)) { timedCache.put(key, "no discont"); } timedCache.put(key, JSON.toJSONString(listDTO)); logger.info("缓存timedCache put"); return new BizResult>(listDTO); } logger.info("缓存中已经存在折扣值:" + value); if (!"no discont".equals(value)) { listDTO = JSON.parseArray(value, DiscontRuleForParkDTO.class); } return new BizResult>(listDTO); } private List getDiscontRuleForParkDTOS(QueryDiscountRuleRequest request) throws ParseException { //判断是否为新能源车,位数大于7 且不是无牌车 if (request.getCarNo().length() > 7 && !request.getCarNo().startsWith("无")) { request.setDisCarTpye(CarTypeEnum.GREEN_ENERGY_CAR.val()); } //小型货车取小型车计费折扣 if (CarTypeEnum.TRUCK_SMALL_CAR.val().equals(request.getDisCarTpye())) { request.setDisCarTpye(CarTypeEnum.SMALL_CAR.val()); } //大型货车取大型车型车计费折扣 if ( CarTypeEnum.TRUCK_LARGE_CAR.val().equals(request.getDisCarTpye())) { request.setDisCarTpye(CarTypeEnum.LARGE_CAR.val()); } if (CarTypeEnum.GREEN_ENERGY_CAR.val().equals(request.getDisCarTpye())) { //新能源车折扣,调用白名单获取,后续修改为放到折扣规则中,暂时求稳定,过个好年 NewEnergyCarDiscountQueryReq newEnergyCarDiscountQueryReq = new NewEnergyCarDiscountQueryReq(); newEnergyCarDiscountQueryReq.setPlNo(request.getPlNo()); newEnergyCarDiscountQueryReq.setCarNum(request.getCarNo()); newEnergyCarDiscountQueryReq.setSysCode(BasicEnum.SYS_CODE.getValue()); BizResult integerBizResult = whitelistService.queryNewEnergyCarDiscount( newEnergyCarDiscountQueryReq); //新能源车折扣 String newEngerdis = ResultUtils.getBizResultData(integerBizResult); //返回折扣信息 if (StringUtils.isEmpty(newEngerdis)) { return new ArrayList<>(); } else { //模拟折扣返回列表返回新能源车折扣 DiscontRuleForParkDTO discontRuleForParkDTO = new DiscontRuleForParkDTO(); discontRuleForParkDTO.setDisCarTpye(request.getDisCarTpye()); discontRuleForParkDTO.setDiscNo("GREEN_CAR_DISC_NO");//新能源车折扣编码 discontRuleForParkDTO.setDiscRuleNo("GREEN_CAR_DISC_RULE_NO");//新能源车折扣规则编码 discontRuleForParkDTO.setDiscPayType(-1);//支付方式不限 discontRuleForParkDTO.setDiscTerminalRes(request.getDiscTerminalRes()); discontRuleForParkDTO.setDiscType(request.getDiscType()); discontRuleForParkDTO.setDiscValue(newEngerdis); discontRuleForParkDTO.setPlNo(request.getPlNo()); return Arrays.asList(discontRuleForParkDTO); } } //其他车辆类型折扣查询 SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss"); //校验入参数 BeanValidatorsUtils.validateWithException(request); List listDTO = new ArrayList(); Date parkOutTime = null; if (request.getParkOutTime() == null) { throw new BizException(ErrorType.PARAMM_NULL, "出场厂时间为空!"); } parkOutTime = format.parse(request.getParkOutTime().substring(request.getParkOutTime().length() - 8)); /**判断是否为节假日非工作日():true ,false:工作日.*/ Boolean isHolidays = this.queryDaysInfoOfSolar(request.getParkOutTime()); /**通过停车场编码,折扣类型,终端来源,车辆类型,出场时间查询停车场所有折扣规则.*/ List list = activityDiscountRuleDao.queryDiscontRuleForList(request); logger.info("查询停车场所有折扣规则list:" + JSONObject.toJSON(list)); if (CollectionUtils.isNotEmpty(list)) { for (DiscontRuleForParkDO discontRuleDO : list) { //有时间限制 if (discontRuleDO != null && IS_TIMME_LIMIT.equals(discontRuleDO.getIsTLimit())) { //出场时间(HH:mm:ss) 不在在限制时间范围内 if (parkOutTime.getTime() <= discontRuleDO.getEffDate().getTime() || parkOutTime.getTime() >= discontRuleDO.getExpDate().getTime()) { continue; } //判断节假日限制是否符合 特征日标识: -1:不限 1:工作日 2:非工作日 if ((discontRuleDO.getSpecialDayType() == HolidayEnum.IS_NOT_HOLIDAY.value() && isHolidays) || (discontRuleDO.getSpecialDayType() == HolidayEnum.IS_HOLIDAY.value() && !isHolidays)) { continue; } } DiscontRuleForParkDTO discontRuleDTO = new DiscontRuleForParkDTO(); BeanUtils.copyProperties(discontRuleDO, discontRuleDTO); listDTO.add(discontRuleDTO); } } else { logger.info("没有符合条件的停车场所有折扣规则"); } //判断该车场是否有特殊用户折扣,且该车牌是否为特定车牌,如果是,则获取特定用户折扣规则;否则获取停车场折扣规则 List discontRuleForParkDTOs = this.getRealDiscountRuleByCarNo(request.getCarNo(), listDTO); return discontRuleForParkDTOs; } /** * 判断该车场是否有特殊用户折扣,且该车牌是否为特定车牌,如果是,则获取特定用户折扣规则;否则获取停车场折扣规则 * * @param carNo * @param discontRuleForParkDTOS * @return */ private List getRealDiscountRuleByCarNo(String carNo, List discontRuleForParkDTOS) { if (CollectionUtils.isEmpty(discontRuleForParkDTOS)) { return null; } /**折扣类型:1.停车支付活动 2:购买会员卡活动 3:特殊用户折扣*/ Map> map = discontRuleForParkDTOS.stream().collect( Collectors.groupingBy(DiscontRuleForParkDTO::getDiscType, Collectors.toList())); //判断是否有特定用户折扣 if (map.containsKey(3)) { List specifieDiscountRules = map.get(3); DiscontRuleForParkDTO specifieDiscountDto = specifieDiscountRules.get(0); //判断该车辆是否为特定车辆 QueryDiscountSpecialCarRequest queryDiscountSpecialCarRequest = new QueryDiscountSpecialCarRequest(); queryDiscountSpecialCarRequest.setSysCode(BasicEnum.SYS_CODE.getValue()); queryDiscountSpecialCarRequest.setPlNo(specifieDiscountDto.getPlNo()); queryDiscountSpecialCarRequest.setCarNumber(carNo); queryDiscountSpecialCarRequest.setDiscNo(specifieDiscountDto.getDiscNo()); BizResult bizResult = discountSpecialCarService .queryDiscountSpecialCarByCarNumber(queryDiscountSpecialCarRequest); if (ResultUtils.getBizResultData(bizResult) != null && ResultUtils.getBizResultData(bizResult).getId() != null) { //是特定车辆 return specifieDiscountRules; } } if (map.containsKey(1)) { return map.get(1); } return null; } /** * 查询制定日期是否为节假日. * * @param parkOutTime * @return */ private Boolean queryDaysInfoOfSolar(String parkOutTime) { logger.info("begin查询给定日期是否节假日,入参={}", parkOutTime); Boolean flg = false; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /**查询是否为节假日.*/ DaysInfoQueryReq req = new DaysInfoQueryReq(); List dataList = new ArrayList<>(); try { dataList.add(format.parse(parkOutTime)); req.setQueryDates(dataList); BizResult> holidaysRestlt = holidayService.queryDaysInfoOfSolar(req); if (holidaysRestlt != null && CollectionUtils.isNotEmpty(holidaysRestlt.getData())) { for (SpHolidaysDTO holidaysDTO : holidaysRestlt.getData()) { if (holidaysDTO != null && HolidayEnum.IS_HOLIDAY.value().equals(holidaysDTO.getIsHolidays())) { flg = true; break; } } } } catch (ParseException e) { e.printStackTrace(); throw new BizException(ErrorType.BIZ_ERROR, "查询是否是节假日"); } logger.info("begin查询给定日期是否节假日,结果:{} true=非工作日,false=工作日", flg); return flg; } @Override public BizResult>> queryDiscontRuleForMap( QueryDiscountRuleRequest request) throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); logger.info("---begin停车场所有折扣规则,入参={}", JSONObject.toJSON(request)); //校验入参数 BeanValidatorsUtils.validateWithException(request); List listDTO = new ArrayList(); Date parkOutTime = format.parse(request.getParkOutTime()); /**判断是否为节假日非工作日():true ,false:工作日.*/ Boolean isHolidays = this.queryDaysInfoOfSolar(request.getParkOutTime()); /**通过停车场编码,折扣类型,终端来源,车辆类型,出场时间查询停车场所有折扣规则.*/ List list = activityDiscountRuleDao.queryDiscontRuleForList(request); if (CollectionUtils.isNotEmpty(list)) { for (DiscontRuleForParkDO discontRuleDO : list) { //有时间限制 if (discontRuleDO != null && IS_TIMME_LIMIT.equals(discontRuleDO.getIsTLimit())) { //出场时间(HH:mm:ss) 不在在限制时间范围内 if (parkOutTime.getTime() <= discontRuleDO.getEffDate().getTime() || parkOutTime.getTime() >= discontRuleDO.getExpDate().getTime()) { continue; } //判断节假日限制是否符合 特征日标识: -1:不限 1:工作日 2:非工作日 if ((discontRuleDO.getSpecialDayType() == HolidayEnum.IS_NOT_HOLIDAY.value() && isHolidays) || (discontRuleDO.getSpecialDayType() == HolidayEnum.IS_HOLIDAY.value() && !isHolidays)) { continue; } } DiscontRuleForParkDTO discontRuleDTO = new DiscontRuleForParkDTO(); BeanUtils.copyProperties(discontRuleDO, discontRuleDTO); listDTO.add(discontRuleDTO); } } else { logger.info("没有符合条件的停车场所有折扣规则"); } logger.info("---begin停车场所有折扣规则"); Map> dataMap = Optional.ofNullable(listDTO).orElse(new ArrayList<>()) .stream() .collect(Collectors.groupingBy(DiscontRuleForParkDTO::getPlNo)); return new BizResult>>(dataMap); } /** * 通过停车场编码校验折扣唯一性.
* * @param request * @return 2018年1月15日 wangfs.
*/ @Override public BizResult checkDiscountUniqueByPlNo(CheckDiscountUniqueByPlNoRequest request) { logger.info("begin通过停车场编码校验折扣唯一性,入参={}", JSONObject.toJSON(request)); //校验入参数 BeanValidatorsUtils.validateWithException(request); Boolean flg = activityDiscountDao.checkDiscountUniqueByPlNo(request); logger.info("end通过停车场编码校验折扣唯一性,结果={}", flg + "。"); return new BizResult(flg); } }