| | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.api.feignClient.AppUserCarClient; |
| | | import com.ruoyi.account.api.feignClient.AppUserClient; |
| | | import com.ruoyi.account.api.feignClient.AppUserVipDetailClient; |
| | | import com.ruoyi.account.api.model.TAppUser; |
| | | import com.ruoyi.account.api.model.TAppUserCar; |
| | | import com.ruoyi.account.api.model.TAppUserVipDetail; |
| | | import com.ruoyi.account.api.vo.GetAppUserVipDetail; |
| | | import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient; |
| | | import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient; |
| | | import com.ruoyi.chargingPile.api.feignClient.SiteClient; |
| | | import com.ruoyi.chargingPile.api.model.Site; |
| | | import com.ruoyi.chargingPile.api.model.TChargingGun; |
| | | import com.ruoyi.chargingPile.api.model.TChargingPile; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.core.web.page.BasePage; |
| | | import com.ruoyi.common.redis.service.RedisService; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.common.security.utils.SecurityUtils; |
| | | import com.ruoyi.order.api.model.TChargingOrder; |
| | | import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy; |
| | | import com.ruoyi.order.dto.GetMyChargingOrderList; |
| | | import com.ruoyi.order.dto.GetNoInvoicedOrder; |
| | | import com.ruoyi.order.dto.MyChargingOrderInfo; |
| | | import com.ruoyi.order.dto.MyChargingOrderList; |
| | | import com.ruoyi.order.dto.*; |
| | | import com.ruoyi.order.mapper.TChargingOrderMapper; |
| | | import com.ruoyi.order.service.TChargingOrderAccountingStrategyService; |
| | | import com.ruoyi.order.service.TChargingOrderService; |
| | | import com.ruoyi.payment.api.feignClient.WxPaymentClient; |
| | | import com.ruoyi.payment.api.vo.NotifyV3PayDecodeRespBody; |
| | | import com.ruoyi.payment.api.vo.PaymentOrder; |
| | | import io.seata.spring.annotation.GlobalTransactional; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | |
| | | import java.time.ZoneOffset; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @Resource |
| | | private TokenService tokenService; |
| | | |
| | | @Resource |
| | | private WxPaymentClient wxPaymentClient; |
| | | |
| | | @Resource |
| | | private ChargingPileClient chargingPileClient; |
| | | |
| | | @Resource |
| | | private AppUserClient appUserClient; |
| | | |
| | | @Resource |
| | | private AppUserVipDetailClient appUserVipDetailClient; |
| | | |
| | | @Resource |
| | | private RedisService redisService; |
| | | |
| | | |
| | | |
| | | |
| | |
| | | myChargingOrderList.setTitle(site.getName()); |
| | | myChargingOrderList.setChargingDegree(tChargingOrder.getChargingCapacity()); |
| | | String name = chargingGunClient.getAllName(tChargingOrder.getChargingGunId()).getData(); |
| | | myChargingOrderList.setChargingGunId(tChargingOrder.getChargingGunId()); |
| | | myChargingOrderList.setName(name); |
| | | myChargingOrderList.setEndMode(tChargingOrder.getEndMode()); |
| | | BigDecimal payMoney = tChargingOrder.getStatus() < 4 ? tChargingOrder.getRechargeAmount() : tChargingOrder.getPaymentAmount(); |
| | |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 充电支付 |
| | | * @param addChargingOrder |
| | | * @return |
| | | */ |
| | | @Override |
| | | @GlobalTransactional(rollbackFor = Exception.class) |
| | | public AjaxResult paymentChargingOrder(AddChargingOrder addChargingOrder) { |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | TAppUser appUser = appUserClient.getUserById(userId).getData(); |
| | | //查询待支付状态的订单,没有支付则删除订单 |
| | | List<TChargingOrder> list = this.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId) |
| | | .eq(TChargingOrder::getRechargePaymentStatus, 1).eq(TChargingOrder::getDelFlag, 0)); |
| | | for (TChargingOrder tChargingOrder : list) { |
| | | Integer rechargePaymentType = tChargingOrder.getRechargePaymentType(); |
| | | if(1 == rechargePaymentType){ |
| | | NotifyV3PayDecodeRespBody data = wxPaymentClient.queryOrderInfo(tChargingOrder.getCode()).getData(); |
| | | if(null != data){ |
| | | String trade_state = data.getTrade_state(); |
| | | //支付失败,删除无效的订单 |
| | | if(trade_state.equals("REFUND") || trade_state.equals("NOTPAY") || trade_state.equals("REVOKED") || trade_state.equals("PAYERROR")){ |
| | | this.removeById(tChargingOrder.getId()); |
| | | } |
| | | } |
| | | } |
| | | if(2 == rechargePaymentType){ |
| | | |
| | | } |
| | | } |
| | | |
| | | //检查当前枪是否是正在使用中 |
| | | TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, addChargingOrder.getId()) |
| | | .in(TChargingOrder::getStatus, Arrays.asList(1, 2, 3)).eq(TChargingOrder::getDelFlag, 0)); |
| | | if(null != one){ |
| | | return AjaxResult.error("充电枪正在充电桩中,启动失败"); |
| | | } |
| | | //查询当前充电枪是否有正在支付的订单 |
| | | one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, addChargingOrder.getId()) |
| | | .eq(TChargingOrder::getAppUserCarId, userId).eq(TChargingOrder::getRechargePaymentStatus, 1).eq(TChargingOrder::getDelFlag, 0)); |
| | | if(null != one){ |
| | | //查询三方支付数据,支付中直接结束三方订单 |
| | | if(1 == one.getRechargePaymentType()){ |
| | | NotifyV3PayDecodeRespBody data = wxPaymentClient.queryOrderInfo(one.getCode()).getData(); |
| | | if(null != data){ |
| | | String trade_state = data.getTrade_state(); |
| | | //支付失败,删除无效的订单 |
| | | if(trade_state.equals("REFUND") || trade_state.equals("NOTPAY") || trade_state.equals("REVOKED") || trade_state.equals("PAYERROR")){ |
| | | this.removeById(one.getId()); |
| | | }else{ |
| | | //结束第三方支付,删除订单 |
| | | wxPaymentClient.close(one.getCode()); |
| | | this.removeById(one.getId()); |
| | | } |
| | | } |
| | | } |
| | | if(2 == one.getRechargePaymentType()){ |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | //构建新的待支付订单 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | TChargingOrder chargingOrder = new TChargingOrder(); |
| | | String code = "CD" + Math.random() * 1000 + sdf.format(new Date()); |
| | | chargingOrder.setCode(code); |
| | | chargingOrder.setOrderType(1); |
| | | chargingOrder.setOrderClassification(1); |
| | | chargingOrder.setAppUserId(userId); |
| | | chargingOrder.setAppUserCarId(addChargingOrder.getAppUserCarId()); |
| | | TChargingGun tChargingGun = chargingGunClient.getChargingGunById(addChargingOrder.getId()).getData(); |
| | | chargingOrder.setSiteId(tChargingGun.getSiteId()); |
| | | chargingOrder.setChargingPileId(tChargingGun.getChargingPileId()); |
| | | chargingOrder.setChargingGunId(addChargingOrder.getId()); |
| | | chargingOrder.setRechargePaymentType(addChargingOrder.getPaymentType()); |
| | | chargingOrder.setRechargePaymentStatus(1); |
| | | chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount()); |
| | | chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId()); |
| | | if(null != appUser.getVipId()){ |
| | | GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail(); |
| | | getAppUserVipDetail.setAppUserId(appUser.getId()); |
| | | getAppUserVipDetail.setVipId(appUser.getVipId()); |
| | | TAppUserVipDetail vipDetail = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData(); |
| | | if(null != vipDetail){ |
| | | Integer chargeNum = vipDetail.getChargeNum(); |
| | | if(0 > chargeNum){ |
| | | chargingOrder.setVipDiscount(vipDetail.getDiscount()); |
| | | BigDecimal discountAmount = addChargingOrder.getPaymentAmount().multiply((new BigDecimal(10) |
| | | .subtract(vipDetail.getDiscount())).divide(new BigDecimal(10))).setScale(4, BigDecimal.ROUND_HALF_EVEN); |
| | | chargingOrder.setVipDiscountAmount(discountAmount); |
| | | } |
| | | } |
| | | |
| | | } |
| | | this.save(chargingOrder); |
| | | //会员优惠折扣将其计入增加充电时长(增加总充电金额) |
| | | //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额) |
| | | if(1 == addChargingOrder.getPaymentType()){ |
| | | PaymentOrder paymentOrder = new PaymentOrder(); |
| | | paymentOrder.setCode(chargingOrder.getCode()); |
| | | paymentOrder.setAmount(addChargingOrder.getPaymentAmount()); |
| | | paymentOrder.setOpenId(appUser.getWxOpenid()); |
| | | paymentOrder.setDescription("充电充值"); |
| | | paymentOrder.setNotifyUrl("/order/t-charging-order/chargingOrderWXCallback"); |
| | | Map<String, Object> data = wxPaymentClient.orderPay(paymentOrder).getData(); |
| | | return AjaxResult.success(data); |
| | | } |
| | | if(2 == addChargingOrder.getPaymentType()){ |
| | | |
| | | } |
| | | throw new RuntimeException("无效的支付方式"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 支付成功后的回调处理逻辑 |
| | | * @param paymentType 支付方式:1=微信,2=支付宝 |
| | | * @param out_trade_no 业务流水号 |
| | | * @param transaction_id 三方支付流水号 |
| | | * @param attach 附加数据 |
| | | * @return |
| | | */ |
| | | @Override |
| | | public AjaxResult chargingOrderCallback(Integer paymentType, String out_trade_no, String transaction_id, String attach) { |
| | | TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, out_trade_no)); |
| | | if(chargingOrder.getRechargePaymentStatus() == 2){ |
| | | return AjaxResult.success(); |
| | | } |
| | | chargingOrder.setRechargePaymentStatus(2); |
| | | chargingOrder.setRechargeSerialNumber(transaction_id); |
| | | this.updateById(chargingOrder); |
| | | //添加安全检测数据到缓存中,每步安全检测完成后需要更新缓存数据 |
| | | PreChargeCheck preChargeCheck = new PreChargeCheck(); |
| | | preChargeCheck.setElectronicLockLock(false); |
| | | preChargeCheck.setInsulationTesting(false); |
| | | preChargeCheck.setSecureConnectionDetection(false); |
| | | String key = "AQJC_" + chargingOrder.getChargingGunId(); |
| | | redisService.setCacheObject(key, preChargeCheck); |
| | | //开始检测充电桩状,将检查状态写入缓存。检测完成后开始开启充电 |
| | | //充电结束后需要计算退款剩余金额 |
| | | // todo 需要完善 |
| | | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取充电中的详情 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @Override |
| | | public ChargingDetails getChargingDetails(Integer id) { |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId).eq(TChargingOrder::getChargingGunId, id) |
| | | .in(TChargingOrder::getStatus, Arrays.asList(1, 2, 3)).eq(TChargingOrder::getRechargePaymentStatus, 2).eq(TChargingOrder::getDelFlag, 0)); |
| | | if(null == one){ |
| | | return null; |
| | | } |
| | | // todo 需要完善充电实时数据 |
| | | ChargingDetails chargingDetails = new ChargingDetails(); |
| | | chargingDetails.setId(one.getId().toString()); |
| | | TChargingGun chargingGun = chargingGunClient.getChargingGunById(id).getData(); |
| | | TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData(); |
| | | Site site = siteClient.getSiteByIds(Arrays.asList(chargingPile.getSiteId())).getData().get(0); |
| | | chargingDetails.setName(site.getName() + "-" + chargingPile.getName()); |
| | | chargingDetails.setCode(one.getCode()); |
| | | chargingDetails.setStatus(one.getStatus()); |
| | | return chargingDetails; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 停止充电操作 |
| | | * @param id 订单id |
| | | * @return |
| | | */ |
| | | @Override |
| | | public AjaxResult stopCharging(String id) { |
| | | TChargingOrder chargingOrder = this.getById(id); |
| | | Integer status = chargingOrder.getStatus(); |
| | | if(status == 4 || status == 5){ |
| | | return AjaxResult.error("不能重复操作"); |
| | | } |
| | | chargingOrder.setStatus(4); |
| | | chargingOrder.setEndMode(1); |
| | | this.updateById(chargingOrder); |
| | | //调用硬件停止充电,停止成功后开始计算费用退款 |
| | | // todo 待完善 |
| | | return AjaxResult.success(); |
| | | } |
| | | } |