123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- package com.pj.api.open.service;
- import cn.hutool.cache.CacheUtil;
- import cn.hutool.cache.impl.TimedCache;
- import cn.hutool.core.date.DateUtil;
- import cn.hutool.core.img.ImgUtil;
- import cn.hutool.core.io.FileUtil;
- import cn.hutool.core.util.RandomUtil;
- import cn.hutool.core.util.RandomUtil;
- import cn.hutool.core.util.StrUtil;
- import cn.hutool.log.StaticLog;
- import com.pj.api.open.ResultJson;
- import com.pj.api.open.bo.CheckCarNumberBO;
- import com.pj.api.open.bo.InRecordBO;
- import com.pj.constants.UserTypeEnum;
- import com.pj.current.config.PartConfig;
- import com.pj.current.config.SystemObject;
- import com.pj.current.task.TaskService;
- import com.pj.project.tb_account.AutomaticPay;
- import com.pj.project.tb_business.TbBusiness;
- import com.pj.project.tb_business.TbBusinessService;
- import com.pj.project.tb_business_car.TbBusinessCar;
- import com.pj.project.tb_business_car.TbBusinessCarService;
- import com.pj.project.tb_business_item.TbBusinessItem;
- import com.pj.project.tb_business_item.TbBusinessItemService;
- import com.pj.project.tb_business_people.TbBusinessPeople;
- import com.pj.project.tb_business_people.TbBusinessPeopleService;
- import com.pj.project.tb_car.TbCar;
- import com.pj.project.tb_car.TbCarService;
- import com.pj.project.tb_car_no_color.TbCarNoColor;
- import com.pj.project.tb_car_no_color.TbCarNoColorService;
- import com.pj.project.tb_deduction_bind.TbDeductionBindService;
- import com.pj.project.tb_goods.TbGoods;
- import com.pj.project.tb_goods.TbGoodsService;
- import com.pj.project.tb_item.TbItem;
- import com.pj.project.tb_item_type.TbItemType;
- import com.pj.project4sp.global.BusinessException;
- import com.pj.project4sp.uploadfile.UploadConfig;
- import com.pj.utils.cache.RedisUtil;
- import com.pj.utils.sg.AjaxJson;
- import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.context.annotation.Lazy;
- import org.springframework.scheduling.annotation.Async;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import sun.misc.BASE64Decoder;
- import javax.annotation.Resource;
- import javax.xml.crypto.Data;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.OutputStream;
- import java.math.BigDecimal;
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
- import java.util.Collections;
- import java.util.Date;
- import java.util.List;
- import java.util.Objects;
- import java.util.stream.Collectors;
- @Service
- @Transactional
- @Slf4j
- public class OpenService {
- @Resource
- @Lazy
- private TbBusinessService tbBusinessService;
- @Resource
- @Lazy
- private TbBusinessCarService tbBusinessCarService;
- @Resource
- private TbCarService tbCarService;
- @Resource
- TaskService taskService;
- @Resource
- TbCarNoColorService tbCarNoColorService;
- @Resource
- private TbGoodsService tbGoodsService;
- @Resource
- @Lazy
- AutomaticPay automaticPay;
- @Resource
- private TbDeductionBindService tbDeductionBindService;
- @Resource
- private PartConfig partConfig;
- public ResultJson checkCarNumber(CheckCarNumberBO checkCarNumberBO) {
- String carNo = checkCarNumberBO.getCarNumber();
- int inOrOut = checkCarNumberBO.getInOrOut();
- String image = checkCarNumberBO.getImageData();
- if (inOrOut == 1) {
- handlerIn(carNo, checkCarNumberBO.getChannelName(), image);
- return ResultJson.success();
- }
- return handlerOut(carNo, checkCarNumberBO.getChannelName(), image);
- }
- private void handlerIn(String carNo, String channel, String image) {
- carNo = carNo.toUpperCase();
- if (StrUtil.isNotEmpty(image)) {
- StaticLog.error("缓存入场图片:{}", carNo);
- IMAGE_CACHE.put(carNo, image);
- }
- automaticPay.unbindRun(carNo);
- TbBusinessCar tbBusinessCar = tbBusinessCarService.findTheLastRecord(carNo);
- Date now = new Date();
- TbCar tbCar = tbCarService.findByCardNo(carNo);
- //1、记录不存在;
- // 2、已离场重新入场;
- // 3、抬杆离场
- if (tbBusinessCar == null
- || (tbBusinessCar.getRealInTime() != null && tbBusinessCar.getRealOutTime() != null)
- || (tbBusinessCar.getRealInTime() != null && tbBusinessCar.getRealOutTime() == null)) {
- //=======创建新的放行记录==========
- tbBusinessCar = new TbBusinessCar();
- tbBusinessCar.setCarNo(carNo).setPay(0).setCarSize(0D).setIsLock(0)
- .setCarCompany(tbCar != null ? tbCar.getCustomerName() : "临时")
- .setInChannel(channel).setRealInTime(now).setCarType(TbItem.ItemTypeEnum.EMPTY_TYPE.getType())
- .setBasePartMoney(new BigDecimal("0")).setTimeUpdate(now)
- .setNo(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + RandomUtil.randomNumbers(4));
- tbBusinessCarService.save(tbBusinessCar);
- CoverBase64ToUrl(image, tbBusinessCar.getId(), carNo, 1);
- return;
- }
- tbBusinessCar.setRealInTime(now).setInChannel(channel).setTimeUpdate(now)
- .setCarCompany(tbCar != null ? tbCar.getCustomerName() : "临时");
- tbBusinessCarService.saveOrUpdate(tbBusinessCar);
- CoverBase64ToUrl(image, tbBusinessCar.getId(), carNo, 1);
- }
- private void CoverBase64ToUrl(String base64image, String carId, String carNo, int inOrOut) {
- String cacheBase64 = IMAGE_CACHE.get(carNo);
- if (StrUtil.isEmpty(base64image)) {
- base64image = cacheBase64;
- }
- if (StrUtil.isEmpty(base64image)) {
- log.error("无出场图片:{}", carNo);
- return;
- }
- taskService.addTask(new CoverBase64ToImageTask("=======" + carId + "", 2000, carId, base64image, inOrOut));
- IMAGE_CACHE.remove(carNo);
- }
- final TimedCache<String, String> IMAGE_CACHE = CacheUtil.newTimedCache(30 * 60 * 1000);
- private ResultJson handlerOut(String carNo, String channel, String image) {
- carNo = carNo.toUpperCase();
- TbBusinessCar tbBusinessCar = tbBusinessCarService.findTheLastRecord(carNo);
- if (tbBusinessCar == null || tbBusinessCar.getRealInTime() == null || tbBusinessCar.getRealOutTime() != null) {
- log.error("请求返回【未查询到入场记录】:{}", carNo);
- return ResultJson.error("未查询到入场记录");
- }
- Date now = new Date();
- Date realInTime = tbBusinessCar.getRealInTime();
- if (now.getTime() / 1000 - realInTime.getTime() / 1000 < partConfig.getMinSeconds()) {
- log.error("请求返回【无效离场记录,返回到设备端为:“未查询到入场记录”让其停止轮询】:{}", carNo);
- return ResultJson.error("无效离场记录");
- }
- if (StrUtil.isNotEmpty(image)) {
- StaticLog.error("缓存离场图片,{}", carNo);
- IMAGE_CACHE.put(carNo, image);
- }
- //判断是否蓝色车牌===免停车费
- if (StrUtil.isNotEmpty(tbBusinessCar.getColor())) {
- List<TbCarNoColor> freeList = tbCarNoColorService.getFreeColor();
- List<String> colorList = freeList.stream().map(f -> f.getCarNoColor().substring(0, 1)).collect(Collectors.toList());
- String color = tbBusinessCar.getColor().substring(0, 1);
- if (colorList.contains(color)) {
- freeOut(tbBusinessCar, now, channel, image);
- return ResultJson.success();
- }
- }
- //是否行政车辆=====
- if (checkFree(carNo, 2, now)) {
- freeOut(tbBusinessCar, now, channel, image);
- return ResultJson.success();
- }
- if (tbBusinessCar.getIsLock() == 1) {
- RedisUtil.setByMINUTES(channel, carNo, 2);
- log.error("请求返回:车辆已锁定:{}", carNo);
- return ResultJson.error("车辆已锁定");
- }
- String businessCarId = tbBusinessCar.getId();
- //String carNoPrefix = StrUtil.sub(carNo, 0, 1);
- String carType = tbBusinessCar.getCarType();
- BigDecimal carMoney = new BigDecimal(0);
- List<TbBusiness> businessList = tbBusinessService.findOtherBusinessByCarId(businessCarId);
- if (businessList.isEmpty()) {//无业务车辆===>计算停车费
- //如果已经支付过,则从支付时间算起,重新计算停车费
- double dif = caulatePrice(tbBusinessCar, now);
- if (dif > 0) {
- RedisUtil.setByMINUTES(channel, carNo, 1);
- log.error("请求返回:请缴停车费:{},{}元", carNo, dif);
- automaticPay.run(null, tbBusinessCar.getCarNo(), 1);
- return ResultJson.error("请缴停车费" + dif + "元");
- } else {
- //无需交停车费,又没有支付的--->设置成免费车辆
- if (tbBusinessCar.getPayTime() == null) {
- tbBusinessCar.setPayType(TbBusinessCar.PayTypeEnum.FEE_TYPE.getType()).setPay(1);
- }
- freeOut(tbBusinessCar, now, channel, image);
- return ResultJson.success();
- }
- } else {
- //有业务的车
- //1、分越重车和空车
- //空车是否收费
- //该车所有的业务都是到达卡口才进行扣费才会进入自动扣费
- int autoPayCount = 0;
- for (TbBusiness business : businessList) {
- TbGoods tbGoods = tbGoodsService.getById(business.getGoodsId());
- if (TbGoods.DeductionTypeEnum.OUT_KK.getCode().equals(tbGoods.getAutoDeductionType())) {
- autoPayCount++;
- }
- }
- if (autoPayCount == businessList.size()) {
- log.info("车辆到达卡口进行扣停车费和业务费:{}", carNo);
- //自动缴费
- automaticPay.run(null, tbBusinessCar.getCarNo(), 3);
- tbDeductionBindService.autoUnbindCar(tbBusinessCar.getCarNo());
- freeOut(tbBusinessCar, now, channel, image);
- return ResultJson.success();
- }
- if (TbItem.ItemTypeEnum.EMPTY_TYPE.getType().equals(carType)) {
- boolean chinaCarPay = businessList.stream().anyMatch(tbBusiness -> {
- TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
- return tbGoods.getChinaCarPay() == 1;
- });
- if (chinaCarPay) {
- double dif = caulatePrice(tbBusinessCar, now);
- if (dif > 0) {
- RedisUtil.setByMINUTES(channel, carNo, 1);
- log.error("中国车停车费:{},{}元", carNo, dif);
- carMoney = new BigDecimal(dif);
- // return ResultJson.error("请缴停车费" + dif + "元");
- } else {
- if (tbBusinessCar.getPayTime() == null) {
- tbBusinessCar.setPayType(TbBusinessCar.PayTypeEnum.FEE_TYPE.getType()).setPay(1);
- }
- }
- }
- } else {//越南车=重车
- boolean vietnamCarPay = businessList.stream().anyMatch(tbBusiness -> {
- TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
- return tbGoods.getVietnamCarPay() == 1;
- });
- if (vietnamCarPay) {
- double dif = caulatePrice(tbBusinessCar, now);
- if (dif > 0) {
- RedisUtil.setByMINUTES(channel, carNo, 1);
- log.error("越南车停车费:{},{}元", carNo, dif);
- carMoney = new BigDecimal(dif);
- // return ResultJson.error("请缴停车费" + dif + "元");
- } else {
- if (tbBusinessCar.getPayTime() == null) {
- tbBusinessCar.setPayType(TbBusinessCar.PayTypeEnum.FEE_TYPE.getType()).setPay(1);
- }
- }
- }
- }
- }
- //============业务费计算是否交完
- BigDecimal businessMoney = new BigDecimal(0);
- for (TbBusiness tbBusiness : businessList) {
- TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
- int vietnamLeave = tbGoods.getVietnamCarLeave();
- int chinaCarLeave = tbGoods.getChinaCarLeave();
- boolean pay = tbBusiness.getPayMoney().doubleValue() >= tbBusiness.getItemPrice().doubleValue();
- //需要交业务费
- if (TbItem.ItemTypeEnum.WEIGHT_TYPE.getType().equals(carType)) {//越南车==重车
- if (TbGoods.LeaveEnum.PART_MONEY.getCode() != vietnamLeave
- && !pay) {
- RedisUtil.setByMINUTES(channel, carNo, 1);
- log.error("越南车==重车:缴纳业务费用:{}", carNo);
- businessMoney = businessMoney.add(tbBusiness.getItemPrice());
- // return ResultJson.error("请缴纳业务费用");
- }
- } else {
- if (TbGoods.LeaveEnum.PART_MONEY.getCode() != chinaCarLeave
- && !pay) {
- RedisUtil.setByMINUTES(channel, carNo, 1);
- businessMoney = businessMoney.add(tbBusiness.getItemPrice());
- log.error("请求返回:请缴纳业务费用:{}", carNo);
- // return ResultJson.error("请缴纳业务费用");
- }
- }
- }
- BigDecimal total = businessMoney.add(carMoney);
- if (total.doubleValue() > 0) {
- log.error("请求返回:请缴费用:{},{}元", carNo, total.doubleValue());
- return ResultJson.error("请缴费用" + total.doubleValue() + "元");
- }
- //离场直接解绑
- tbDeductionBindService.autoUnbindCar(tbBusinessCar.getCarNo());
- freeOut(tbBusinessCar, now, channel, image);
- return ResultJson.success();
- }
- private double caulatePrice(TbBusinessCar tbBusinessCar, Date now) {
- Date inTime = tbBusinessCar.getRealInTime();
- if (tbBusinessCar.getPay() == 1 && tbBusinessCar.getRealOutTime() == null && tbBusinessCar.getPayTime() != null) {
- inTime = tbBusinessCar.getPayTime();
- }
- BigDecimal price = tbBusinessService.calculationPartMoney(inTime, now);
- return price.doubleValue();
- }
- private void freeOut(TbBusinessCar tbBusinessCar, Date now, String outChannel, String base64Image) {
- tbBusinessCar.setRealOutTime(now).setTimeUpdate(now).setOutChannel(outChannel);
- tbBusinessCarService.updateById(tbBusinessCar);
- String carNo = tbBusinessCar.getCarNo();
- CoverBase64ToUrl(base64Image, tbBusinessCar.getId(), carNo, 2);
- RedisUtil.del(outChannel);
- log.error("请求返回【放行】:{}", carNo);
- }
- private boolean checkFree(String carNo, int inOrOut, Date now) {
- TbCar tbCar = tbCarService.findByCardNo(carNo);
- if (tbCar != null) {
- if (inOrOut == 1) {
- tbCar.setLastInTime(now);
- } else {
- tbCar.setLastOutTime(now);
- }
- tbCarService.updateById(tbCar);
- }
- return tbCar != null && !TbCar.CarTypeEnum.BUSINESS_CAR.getType().equals(tbCar.getCarType());
- }
- @Async
- public void handlerInRecord(InRecordBO inRecordBO) {
- List<TbCarNoColor> carNoColorList = tbCarNoColorService.getFreeColor();
- String freeColors = carNoColorList.stream().map(TbCarNoColor::getCarNoColor).collect(Collectors.joining(","));
- String carNo = inRecordBO.getCarNumber().trim().toUpperCase();
- // 入场==>取车牌颜色
- List<TbBusinessCar> cars = tbBusinessCarService.findByCarNo(carNo);
- cars.stream().filter(obj -> StrUtil.isEmpty(obj.getColor()))
- .forEach(tbBusinessCar -> {
- String color = inRecordBO.getCarColor();
- String prefixColor = StrUtil.sub(color, 0, 1);
- if (StrUtil.contains(freeColors, prefixColor)) {
- tbBusinessCar.setPayType(TbBusinessCar.PayTypeEnum.FEE_TYPE.getType());
- }
- TbCar tbCar = tbCarService.findByCardNo(tbBusinessCar.getCarNo());
- if (tbCar != null && !TbCar.CarTypeEnum.BUSINESS_CAR.getType().equals(tbCar.getCarType())) {
- tbBusinessCar.setPayType(TbBusinessCar.PayTypeEnum.FEE_TYPE.getType());
- }
- tbBusinessCar.setColor(color);
- tbBusinessCarService.updateById(tbBusinessCar);
- });
- }
- }
|