package com.wind.web.controller.third; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.wind.mybatis.pojo.*; import com.wind.web.common.QueryParameter; import com.wind.web.common.QueryParameterMethod; import com.wind.web.common.QueryParameterType; import com.wind.web.controller.wx.WxPayAPI; import com.wind.web.service.*; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.apachecommons.CommonsLog; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; import java.util.*; import static com.wind.common.Constant.EMPTY_STRING; @CommonsLog @RestController @RequestMapping("/third/park") public class ParkThirdAPI { @Autowired ParkMemberService parkMemberService; @Autowired ParkService parkService; @Autowired CarFeeService carFeeService; @Autowired FeeService feeService; @Autowired protected WxPayAPI wxPayAPI; @Autowired private PaymentService paymentService; @PostMapping("/pay_callback/{type}/{id}/{rid}/{uid}") public ResponseEntity<?> parseOrderNotifyResult(@ApiParam("支付类型") @PathVariable("type") Integer type, @ApiParam("主键") @PathVariable("id") long id, @ApiParam("外键") @PathVariable("rid") long rid, @ApiParam("用户id") @PathVariable("uid") long uid, @RequestBody String xmlData) throws WxPayException { WxPayOrderNotifyResult result = wxPayAPI.parseOrderNotifyResult(xmlData); if (result.getReturnCode().equals("SUCCESS")) { if (type == 1) { Payment payment = paymentService.selectByID(id).get(); payment.setBankType(result.getBankType()); payment.setOutTradeNo(result.getOutTradeNo()); payment.setTransactionNo(result.getTransactionId()); payment.setComment(result.getReturnCode()); paymentService.modifyById(payment); CarFee carFee = carFeeService.selectByID(rid).get(); carFee.setPaymentAmount(new BigDecimal(payment.getTotalFee()).divide(new BigDecimal(100))); carFee.setPaymentTime(new Date()); carFee.setPaymentMode("微信支付"); carFee.setPaymentId(id); carFee.setUserId(uid); carFeeService.modifyById(carFee); } else { // todo: 会员充值 } return ResponseEntity.status(HttpStatus.OK).body("SUCCESS"); } else { return ResponseEntity.status(HttpStatus.OK).body("FAIL"); } } @ApiOperation(value = "车辆待入场申请") @GetMapping(value = "/car_in_pre", produces = "text/plain;charset=UTF-8") public ResponseEntity<?> carInPre( @RequestParam("parkId") Long parkId, @RequestParam("car") String carNumber) { int code = -1; long rec = 0; String message; try { Date now = new Date(); Optional<Park> optionalPark = parkService.selectByID(parkId); if (optionalPark.isPresent()) { CarFee fee = new CarFee(); fee.setCarNumber(carNumber); fee.setInTime(new Date()); fee.setParkId(parkId); List<ParkMember> memberList = parkMemberService.selectTop(1, new QueryParameter("parkId", QueryParameterMethod.EQUAL, parkId.toString(), QueryParameterType.LONG), new QueryParameter("carNumber", QueryParameterMethod.EQUAL, carNumber, QueryParameterType.STRING)); if (memberList.size() > 0) { ParkMember member = memberList.get(0); if (member.getEndDate().after(now)) { Integer days = (int) ((member.getEndDate().getTime() - now.getTime()) / (1000 * 3600 * 24)); if (days > 30) { code = 1; message = "会员车辆"; } else { code = 2; message = days.toString(); } } else if (optionalPark.get().getIsMemberOnly()) { message = "非会员车辆"; code = 4; } else { message = "按次收费车辆"; code = 3; } } else if (optionalPark.get().getIsMemberOnly()) { code = 4; message = "非会员车辆"; } else { code = 3; message = "按次收费车辆"; } fee.setCode(code); fee.setInComment(message); carFeeService.add(fee); rec = fee.getId(); } else { code = -9; message = "无法识别小区"; } } catch (Exception e) { message = e.getMessage(); log.error(message); e.printStackTrace(); } return ResponseEntity.status(HttpStatus.OK).body(String.format("{\"code\":%d, \"msg\":\"%s\",\"recId\":%d }", code, message, rec)); } @ApiOperation(value = "车辆已入场通知") @GetMapping(value = "/car_in_post", produces = "text/plain;charset=UTF-8") public ResponseEntity<?> carInPost( @RequestParam("parkId") Long parkId, @RequestParam("recId") Long recId, @RequestParam("gate") String gate, @RequestParam("car") String car, @RequestParam("imgUrl") String imgUrl, @RequestParam("optType") Integer optType, @RequestParam(name = "optUser", required = false) String optUser ) { int code = -1; String message = EMPTY_STRING; try { List<CarFee> feeList = carFeeService.selectTop(1, new QueryParameter("id", QueryParameterMethod.EQUAL, recId.toString(), QueryParameterType.LONG), new QueryParameter("parkId", QueryParameterMethod.EQUAL, parkId.toString(), QueryParameterType.LONG), new QueryParameter("carNumber", QueryParameterMethod.EQUAL, car, QueryParameterType.STRING)); if (feeList.size() > 0) { CarFee fee = feeList.get(0); fee.setInTime(new Date()); fee.setInOperationType(optType); fee.setInOperator(optUser); fee.setInImageUrl(imgUrl); fee.setInGate(gate); carFeeService.modifyById(fee); code = 0; } else { message = "记录不存在"; } } catch (Exception e) { message = e.getMessage(); log.error(message); e.printStackTrace(); } return ResponseEntity.status(HttpStatus.OK).body(String.format("{\"code\":%d, \"msg\":\"%s\"}", code, message)); } @ApiOperation(value = "车辆待出场申请") @GetMapping(value = "/car_out_pre", produces = "text/plain;charset=UTF-8") public ResponseEntity<?> carOutPre( @RequestParam("parkId") Long parkId, @RequestParam("car") String carNumber) { int code = -1; String message; Date now = new Date(); try { Park park = parkService.selectByID(parkId).get(); Fee parkFee = feeService.selectByID(park.getFeeId()).get(); List<CarFee> feeList = carFeeService.selectTop(1, new QueryParameter("parkId", QueryParameterMethod.EQUAL, parkId.toString(), QueryParameterType.LONG), new QueryParameter("carNumber", QueryParameterMethod.EQUAL, carNumber, QueryParameterType.STRING)); if (feeList.size() > 0) { CarFee carFee = feeList.get(0); long recId = carFee.getId(); long inUTC = carFee.getInTime().getTime() / 1000; long outUTC = (new Date()).getTime() / 1000; if (carFee.getOutTime() != null) { code = -3; message = "无入场记录"; return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"msg\":\"%s\" }", code, message)); } else { if (carFee.getCode() == 1 || carFee.getCode() == 2) { code = 1; carFee.setPaymentMode("会员"); carFee.setOutComment("会员车辆"); carFeeService.modifyById(carFee); return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"recId\":%d }", code, recId)); } else if (carFee.getCode() == 3 || carFee.getCode() == 4) { BigDecimal money = calculateMoney(parkFee, carFee.getInTime(), new Date()); if (money.compareTo(BigDecimal.ZERO) == 0) { code = 1; carFee.setOutComment("免费期内出场"); carFeeService.modifyById(carFee); return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"recId\":%d }", code, recId)); } else if (carFee.getPaymentTime() == null) { code = 4; carFee.setOutComment("未提前移动支付"); carFeeService.modifyById(carFee); return ResponseEntity.status(HttpStatus.OK).body( String.format("{\"code\":%d,\"recId\":%d\n" + "\"inTime\":%d,\n" + "\"fee1\":{\"sTime\":%d,\n" + "\"eTime\":%d,\n" + "\"inCash\":%d}\n" + "}", code, recId, inUTC, inUTC, outUTC, money.multiply(new BigDecimal(100)).intValue())); } else if ((now.getTime() - carFee.getPaymentTime().getTime()) / (1000 * 60) < parkFee.getOutFreeMinutes()) { code = 1; carFee.setOutComment("已移动支付"); carFeeService.modifyById(carFee); return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"recId\":%d }", code, recId)); } else { // 已经提前移动支付,超时出场 BigDecimal payedMoney = carFee.getPaymentAmount(); if (money.compareTo(payedMoney) == 0) { code = 1; carFee.setOutComment("已移动支付,超时出场,无需补缴"); carFeeService.modifyById(carFee); return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"recId\":%d }", code, recId)); } else { code = 4; carFee.setOutComment("已移动支付,超时出场,需补缴"); carFeeService.modifyById(carFee); return ResponseEntity.status(HttpStatus.OK).body( String.format("{\"code\":%d,\"recId\":%d\n" + "\"inTime\":%d,\n" + "\"fee1\":{\"sTime\":%d,\n" + "\"eTime\":%d,\n" + "\"inCash\":%d}\n" + "}", code, recId, inUTC, carFee.getPaymentTime().getTime() / 1000, outUTC, (money.subtract(payedMoney)).multiply(new BigDecimal(100)).intValue())); } } } else { message = "code不正确"; } } } else { code = -3; message = "无入场记录"; return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"msg\":\"%s\" }", code, message)); } } catch (Exception e) { code = -1; message = e.getMessage(); log.error(message); e.printStackTrace(); } return ResponseEntity.status(HttpStatus.OK).body(String.format("{ \"code\":%d ,\"msg\":\"%s\" }", code, message)); } @ApiOperation(value = "车辆已出场通知") @GetMapping(value = "/car_out_post", produces = "text/plain;charset=UTF-8") public ResponseEntity<?> carOutPost( @RequestParam("parkId") Long parkId, @RequestParam("recId") Long recId, @RequestParam("gate") String gate, @RequestParam("car") String carNumber, @RequestParam("imgUrl") String imgUrl, @RequestParam("optType") Integer optType, @RequestParam("inCash") Long inCash, @RequestParam(name = "feeType", required = false) Integer feeType, @RequestParam(name = "sTime", required = false) Long sTime, @RequestParam(name = "eTime", required = false) Long eTime, @RequestParam(name = "optUser", required = false) String optUser ) { int code = -1; String message = EMPTY_STRING; try { List<CarFee> feeList = carFeeService.selectTop(1, new QueryParameter("id", QueryParameterMethod.EQUAL, recId.toString(), QueryParameterType.LONG), new QueryParameter("parkId", QueryParameterMethod.EQUAL, parkId.toString(), QueryParameterType.LONG), new QueryParameter("carNumber", QueryParameterMethod.EQUAL, carNumber, QueryParameterType.STRING)); if (feeList.size() > 0) { CarFee fee = feeList.get(0); fee.setOutTime(new Date()); fee.setOutOperationType(optType); fee.setOutOperator(optUser); fee.setOutImageUrl(imgUrl); fee.setOutGate(gate); if (inCash > 0) { if (fee.getPaymentTime() == null) { fee.setPaymentAmount(new BigDecimal(inCash).divide(new BigDecimal(100))); fee.setPaymentTime(new Date()); fee.setCash(fee.getPaymentAmount()); fee.setPaymentMode("现金"); } else { fee.setCash(new BigDecimal(inCash).divide(new BigDecimal(100))); fee.setComment("超时补缴"); } } carFeeService.modifyById(fee); code = 0; } else { message = "记录不存在"; } } catch (Exception e) { message = e.getMessage(); log.error(message); e.printStackTrace(); } return ResponseEntity.status(HttpStatus.OK).body(String.format("{\"code\":%d, \"msg\":\"%s\"}", code, message)); } @ApiOperation(value = "子库入场申请") @GetMapping("/car_in_sub") public ResponseEntity<?> carInSub( @RequestParam("parkId") Long parkId, @RequestParam("car") String carNumber, @RequestParam("subId") Long subId) { return ResponseEntity.status(HttpStatus.OK).body("{ \"code\":1 ,\"msg\":\"欢迎入场\" }"); } static public BigDecimal calculateMoney(Fee fee, Date startTime, Date endTime) { BigDecimal money = BigDecimal.ZERO; if (fee.getIsFree()) { // zero } else if ((endTime.getTime() - startTime.getTime()) / (1000 * 60) < fee.getInFreeMinutes()) { // zero } else { ArrayList<String> parameters = new ArrayList<>(Arrays.asList(fee.getParameters().split(","))); int hours = (int) ((endTime.getTime() - startTime.getTime()) / (1000 * 3600) + 1); money = getPricing(fee, parameters, hours); if (parameters.contains("limit_per_day")) { int days = hours / 24; int residualHours = hours - days * 24; BigDecimal residualMoney = getPricing(fee, parameters, residualHours); if (fee.getLimitPerDay().compareTo(residualMoney) == -1) { residualMoney = fee.getLimitPerDay(); } BigDecimal daysMoney = new BigDecimal(days).multiply(fee.getLimitPerDay()); money = daysMoney.add(residualMoney); } if (parameters.contains("limit_per_time") && fee.getLimitPerTime().compareTo(money) == -1) { money = fee.getLimitPerTime(); } } return money; } static private BigDecimal getPricing(Fee fee, ArrayList<String> parameters, int hours) { BigDecimal money = BigDecimal.ZERO; if (parameters.contains("per_hour")) { money = new BigDecimal(hours).multiply(fee.getPerHour()); } else if (parameters.contains("per_time")) { money = fee.getPerTime(); } else if (parameters.contains("differential_pricing")) { ArrayList<String> prices = new ArrayList<>(Arrays.asList(fee.getDifferentialPricing().split(","))); if (prices.size() != 24) { log.error(String.format("分区计费错误,规则必须等于24小时:%d", fee.getId())); } else { hours = hours > 24 ? 24 : hours; int value = Integer.parseInt(prices.get(hours - 1)); money = BigDecimal.valueOf(value); } } return money; } }