package com.ruoyi.account.controller;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.account.api.dto.CouponListDto;
import com.ruoyi.account.api.dto.GrantCouponDto;
import com.ruoyi.account.api.model.TAppCoupon;
import com.ruoyi.account.api.model.TAppUser;
import com.ruoyi.account.api.model.TAppUserCar;
import com.ruoyi.account.api.model.TAppUserTag;
import com.ruoyi.account.api.vo.AppUserWhitelistMatchVO;
import com.ruoyi.account.api.query.ExchangeRecordGoodsQuery;
import com.ruoyi.account.service.TAppUserService;
import com.ruoyi.account.service.TAppUserTagService;
import com.ruoyi.account.service.TAppUserWhitelistService;
import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient;
import com.ruoyi.chargingPile.api.model.TChargingGun;
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.log.enums.OperatorType;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.other.api.vo.CouponListVOVO;
import com.ruoyi.account.api.vo.ExchangeRecordVO;
import com.ruoyi.account.service.TAppCouponService;
import com.ruoyi.account.service.TAppUserCarService;
import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient;
import com.ruoyi.chargingPile.api.vo.SiteInfoVO;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.BasePage;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.other.api.domain.TCoupon;
import com.ruoyi.other.api.dto.ExchangeCodeBindDTO;
import com.ruoyi.other.api.feignClient.OtherClient;
import com.ruoyi.other.api.vo.ExchangeCodeBindResultVO;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
* 前端控制器
*
*
* @author luodangjia
* @since 2024-08-06
*/
@RestController
@RequestMapping("/t-app-coupon")
public class TAppCouponController {
@Autowired
private TAppCouponService tAppCouponService;
@Resource
private OtherClient otherClient;
@Autowired
private TAppUserCarService appUserCarService;
@Resource
private TokenService tokenService;
@Resource
private ChargingPileClient chargingPileClient;
@Resource
private ChargingOrderClient chargingOrderClient;
@Resource
private ChargingGunClient chargingGunClient;
@Autowired
private TAppUserTagService appUserTagService;
@Autowired
private TAppUserService appUserService;
@Resource
private TAppUserWhitelistService whitelistService;
@Autowired
private RedissonClient redissonClient;
/**
* 后台退款 回退优惠券使用状态
* @return
*/
@PostMapping(value = "/refund/{id}")
public R refund(@PathVariable("id") String id) {
TAppCoupon byId = tAppCouponService.getById(id);
byId.setStatus(1);
tAppCouponService.updateById(byId);
return R.ok();
}
/**
* 小程序扫一扫 添加车辆
* @param dto
* @return
*/
@Log(title = "【扫一扫】添加车辆", businessType = BusinessType.INSERT,operatorType = OperatorType.MOBILE)
@ApiOperation(value = "添加车辆", tags = {"小程序-扫一扫"})
@PostMapping(value = "/scan/addCar")
public AjaxResult addCar(@RequestBody TAppUserCar dto) {
Long userId = tokenService.getLoginUserApplet().getUserId();
RLock lock = redissonClient.getLock("CREATE_CAR:" + userId);
try {
boolean tryLock = lock.tryLock(2, 10, TimeUnit.SECONDS);
if(tryLock){
dto.setAppUserId(userId);
TAppUserCar one = appUserCarService.getOne(new LambdaQueryWrapper()
.eq(TAppUserCar::getLicensePlate, dto.getLicensePlate())
.eq(TAppUserCar::getAppUserId, dto.getAppUserId())
.eq(TAppUserCar::getDelFlag, 0));
if(null != one){
return AjaxResult.error("车辆已存在");
}
appUserCarService.save(dto);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
return AjaxResult.success();
}
/**
* 查询用户可用优惠券数量
* @return
*/
@ApiOperation(value = "通过充电枪id和预付金额获取电站详情", tags = {"小程序-扫一扫"})
@PostMapping(value = "/scan/siteInfo")
public AjaxResult siteInfo(Integer id, BigDecimal money) {
if (id == null || money == null) {
return AjaxResult.error("充电枪和预付金额不能为空");
}
R chargingGunResult = chargingGunClient.getChargingGunById(id);
TChargingGun chargingGun = chargingGunResult == null ? null : chargingGunResult.getData();
if (chargingGun == null) {
return AjaxResult.error("充电枪不存在或已停用");
}
R chargingPileResult = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId());
TChargingPile chargingPile = chargingPileResult == null ? null : chargingPileResult.getData();
if (chargingPile == null || chargingPile.getCode() == null) {
return AjaxResult.error("充电桩不存在或已停用");
}
R siteInfoResult = chargingPileClient.getSiteInfoByNumber1(chargingPile.getCode().toString());
SiteInfoVO data = siteInfoResult == null ? null : siteInfoResult.getData();
if (data == null) {
String message = siteInfoResult == null ? null : siteInfoResult.getMsg();
return AjaxResult.error(StringUtils.hasLength(message) ? message : "获取电站计费信息失败");
}
data.setChargingGunId(id);
data.setSiteId(chargingGun.getSiteId());
data.setChargeMode(chargingGun.getChargeMode());
String token = SecurityUtils.getToken(ServletUtils.getRequest());
if(com.ruoyi.common.core.utils.StringUtils.isNotEmpty(token)){
List cars = appUserCarService.list(new QueryWrapper()
.eq("app_user_id",tokenService.getLoginUserApplet().getUserId())
.eq("del_flag", 0)
.orderByDesc("create_time"));
if (!cars.isEmpty()){
data.setLicensePlate(cars.get(0).getLicensePlate());
data.setVin(cars.get(0).getVin());
data.setVehicleBrand(cars.get(0).getVehicleBrand());
data.setId(cars.get(0).getId().toString());
}
AppUserWhitelistMatchVO whitelist = whitelistService.matchWhitelist(tokenService.getLoginUserApplet().getUserId(), chargingGun.getSiteId());
data.setWhitelistMatched(Boolean.TRUE.equals(whitelist.getMatched()));
if (Boolean.TRUE.equals(whitelist.getMatched())) {
// 充电页余额显示:按白名单所属公司账户模式下发账户可用余额(共享=公司余额,分配=白名单余额)
data.setWhitelistBalance(whitelistService.resolveWhitelistAccountBalance(whitelist));
}
// 白名单权益已下线(充电完全按企业优惠结算),不再下发权益类型与名称,仅保留命中标识
data.setWhitelistBenefitType(null);
data.setWhitelistBenefitName(null);
}
Integer data2 = otherClient.getAddCarIntegral().getData();
data.setIntegral(data2);
BigDecimal electrovalence = data.getElectrovalence();
BigDecimal vipElectrovalence = data.getVipElectrovalence();
if (electrovalence == null || electrovalence.compareTo(BigDecimal.ZERO) <= 0) {
return AjaxResult.error("当前时段未配置有效费率");
}
if (vipElectrovalence == null) {
vipElectrovalence = electrovalence;
}
// 计算预付金额能充多少度普通电
BigDecimal divide1 = money.divide(electrovalence, 2, BigDecimal.ROUND_HALF_UP);
// 计算冲会员充电需要多少钱
BigDecimal vipMoney = divide1.multiply(vipElectrovalence).setScale(2,BigDecimal.ROUND_HALF_UP);
// BigDecimal subtract = divide.subtract(divide1);
// 优惠金额
data.setMoney(electrovalence.multiply(divide1).subtract(vipMoney).setScale(2, BigDecimal.ROUND_DOWN));
return AjaxResult.ok(data);
}
/**
* 查询用户可用优惠券数量
* @param dto
* @return
*/
@ApiOperation(value = "选择优惠券分页查询", tags = {"小程序-扫一扫"})
@PostMapping(value = "/scan/couponList")
public AjaxResult> couponList(@RequestBody CouponListDto dto) {
PageInfo res = tAppCouponService.couponList(dto);
return AjaxResult.ok(res);
}
/**
* 选择车辆列表 远程调用
* @return
*/
@ApiOperation(value = "选择车辆列表", tags = {"小程序-扫一扫"})
@PostMapping(value = "/scan/carList")
public R> carList() {
String token = SecurityUtils.getToken(ServletUtils.getRequest());
if(!StringUtils.hasLength(token)){
return R.ok(new ArrayList<>());
}
List appUserId = appUserCarService.list(new QueryWrapper()
.eq("app_user_id",tokenService.getLoginUserApplet().getUserId()).eq("del_flag", 0));
appUserId.forEach(s->s.setId_(s.getId().toString()));
return R.ok(appUserId);
}
/**
* 管理后台远程调用 根据优惠券ids 查询对应的发放数量
* @return 优惠券ids 查询每个优惠券的发放数量
*/
@PostMapping("/getCountByCouponIds/{couponIds}")
public R> getCountByCouponIds(@PathVariable("couponIds")String couponIds) {
// 最终结果 和优惠券id一一对应
List res = new ArrayList<>();
String[] split = couponIds.split(",");
// 查询每个优惠券的发放数量
for (String s : split) {
res.add(tAppCouponService.list(new QueryWrapper()
.eq("coupon_id", s)
.eq("del_flag",0)
).size());
}
return R.ok(res);
}
/**
* 后台远程调用 根据优惠券id 查询使用数量
* @param couponId
* @return
*/
@PostMapping("/getUseCountByCouponId/{couponId}")
public R getUseCountByCouponId(@PathVariable("couponId") Integer couponId){
return R.ok(tAppCouponService.list(new QueryWrapper()
.eq("coupon_id", couponId)
.eq("status",2)).size());
}
/**
* 后台远程调用 根据优惠券id 查询领取记录
* @param couponId
* @return
*/
@PostMapping("/getExchangeRecordByCouponId")
public R> getExchangeRecordByCouponId(@RequestBody ExchangeRecordGoodsQuery couponId){
return R.ok(tAppCouponService.pagelist(couponId));
}
@ApiOperation(value = "优惠卷可用数量", tags = {"小程序-站点管理-站点详情"})
@GetMapping(value = "/couponCount")
public R couponCount() {
Long userId = tokenService.getLoginUserApplet().getUserId();
Long count = tAppCouponService.lambdaQuery().eq(TAppCoupon::getAppUserId, userId).ge(TAppCoupon::getEndTime, LocalDateTime.now()).eq(TAppCoupon::getStatus, 1).count();
if(Objects.isNull(count)){
count = 0L;
}
return R.ok(count);
}
@ApiOperation(value = "兑换码绑定", tags = {"小程序-兑换码"})
@PostMapping(value = "/exchangeCode/bind")
public AjaxResult bindExchangeCode(@RequestBody ExchangeCodeBindDTO dto) {
Long userId = tokenService.getLoginUserApplet().getUserId();
TAppUser user = appUserService.getById(userId);
ExchangeCodeBindResultVO data = otherClient.bindExchangeCode(dto, userId, user == null ? "" : user.getPhone()).getData();
return AjaxResult.ok(data);
}
/**
* 后台远程调用 给用户发放优惠券
*/
@PostMapping("/grantCoupon")
public R grantCoupon(@RequestBody GrantCouponDto dto){
if (dto.getWaysToObtain()==null){
dto.setWaysToObtain(3);
}
List res = new ArrayList<>();
TCoupon coupon = otherClient.getCouponById(dto.getCouponId()).getData();
switch (dto.getType()){
case 1:
// 根据标签ids 查询用户ids
List collect = appUserTagService.list(new QueryWrapper()
.in("user_tag_id", Arrays.asList(dto.getTags().split(","))))
.stream().map(TAppUserTag::getAppUserId).collect(Collectors.toList());
for (Long l : collect) {
TAppCoupon tAppCoupon = new TAppCoupon();
tAppCoupon.setAppUserId(l);
tAppCoupon.setCouponId(dto.getCouponId());
tAppCoupon.setEndTime(dto.getEndTime());
tAppCoupon.setWaysToObtain(dto.getWaysToObtain());
tAppCoupon.setStatus(1);
tAppCoupon.setCouponJson(JSON.toJSONString(coupon));
res.add(tAppCoupon);
}
tAppCouponService.saveBatch(res);
break;
case 2:
// 根据市codes 查询用户ids
List collect1 = new ArrayList<>();
// 根据市codes 查询用户ids
if (StringUtils.hasLength(dto.getProvinceCode())){
List collect2 = appUserService.list(new QueryWrapper()
.in("province_code", Arrays.asList(dto.getProvinceCode().split(","))))
.stream().map(TAppUser::getId).collect(Collectors.toList());
collect1.addAll(collect2);
}
if (StringUtils.hasLength(dto.getCityCode())){
List collect2 = appUserService.list(new QueryWrapper()
.in("city_code", Arrays.asList(dto.getCityCode().split(","))))
.stream().map(TAppUser::getId).collect(Collectors.toList());
collect1.addAll(collect2);
}
for (Long l : collect1) {
TAppCoupon tAppCoupon = new TAppCoupon();
tAppCoupon.setAppUserId(l);
tAppCoupon.setCouponId(dto.getCouponId());
tAppCoupon.setEndTime(dto.getEndTime());
tAppCoupon.setWaysToObtain(dto.getWaysToObtain());
tAppCoupon.setStatus(1);
tAppCoupon.setCouponJson(JSON.toJSONString(coupon));
res.add(tAppCoupon);
}
tAppCouponService.saveBatch(res);
break;
case 3:
for (String s : dto.getUserIds().split(",")) {
TAppCoupon tAppCoupon = new TAppCoupon();
tAppCoupon.setAppUserId(Long.valueOf(s));
tAppCoupon.setCouponId(dto.getCouponId());
tAppCoupon.setEndTime(dto.getEndTime());
tAppCoupon.setWaysToObtain(dto.getWaysToObtain());
tAppCoupon.setStatus(1);
tAppCoupon.setCouponJson(JSON.toJSONString(coupon));
res.add(tAppCoupon);
}
tAppCouponService.saveBatch(res);
break;
}
return R.ok();
}
/**
* 根据id获取优惠券领取记录
* @param id
* @return
*/
@PostMapping("/getAppCouponById")
public R getAppCouponById(@RequestParam("id") Long id){
TAppCoupon appCoupon = tAppCouponService.getById(id);
return R.ok(appCoupon);
}
@PostMapping("/getAppCouponByIds")
public R> getAppCouponByIds(@RequestBody List ids){
if (ids == null || ids.isEmpty()) {
return R.ok(new ArrayList<>());
}
return R.ok(tAppCouponService.listByIds(ids));
}
/**
* 修改用户优惠券
* @param appCoupon
* @return
*/
@PostMapping("/updateAppCoupon")
public R updateAppCoupon(@RequestBody TAppCoupon appCoupon){
tAppCouponService.updateById(appCoupon);
return R.ok();
}
}