300 lines
12 KiB
Java
300 lines
12 KiB
Java
package com.ruoyi.database.controller;
|
||
|
||
import com.ruoyi.common.core.controller.BaseController;
|
||
import com.ruoyi.common.core.domain.AjaxResult;
|
||
import com.ruoyi.common.core.domain.model.LoginUserByPhone;
|
||
import com.ruoyi.common.utils.bean.BeanUtils;
|
||
import com.ruoyi.database.domain.*;
|
||
import com.ruoyi.database.domain.vo.ParkingBillInfoVO;
|
||
import com.ruoyi.database.enums.PayType;
|
||
import com.ruoyi.database.service.*;
|
||
import com.ruoyi.database.util.LicensePlateValidator;
|
||
import com.ruoyi.framework.web.service.TokenService;
|
||
import io.swagger.annotations.Api;
|
||
import io.swagger.annotations.ApiOperation;
|
||
import lombok.RequiredArgsConstructor;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
import org.springframework.web.bind.annotation.*;
|
||
|
||
import javax.servlet.http.HttpServletRequest;
|
||
import java.time.Instant;
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.concurrent.ThreadLocalRandom;
|
||
import java.util.stream.Collectors;
|
||
|
||
@Api(tags = "小程序接口")
|
||
@RestController
|
||
@RequiredArgsConstructor
|
||
@RequestMapping("/SmallProgram")
|
||
public class SmallProgramController extends BaseController {
|
||
|
||
private final ParkingBillInfoService parkingBillInfoService;
|
||
private final AlipayService alipayService;
|
||
private final BaseCustomerInfoService baseCustomerInfoService;
|
||
private final WechatMiniProgramPayService wechatMiniProgramPayService;
|
||
private final ParkingBillPaymentInfoService parkingBillPaymentInfoService;
|
||
private final CustomerPlateNoInfoService customerPlateNoInfoService;
|
||
private final TokenService tokenService;
|
||
|
||
|
||
|
||
@GetMapping("/getOrder")
|
||
@ApiOperation("根据车牌号查询缴费订单")
|
||
@Transactional
|
||
public AjaxResult getOrder(String plateNo) {
|
||
String trim = plateNo.trim();
|
||
ParkingBillInfo one = parkingBillInfoService.saveOrUpdateParkingBillInfo(trim);
|
||
// ParkingBillInfo one = parkingBillInfoService.lambdaQuery()
|
||
// .eq(ParkingBillInfo::getPlateNo, plateNo)
|
||
// .orderByDesc(ParkingBillInfo::getCreateTime)
|
||
// .last("limit 1")
|
||
// .one();
|
||
|
||
if (one == null) {
|
||
return AjaxResult.error("未查询到停车记录");
|
||
}else {
|
||
ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO();
|
||
BeanUtils.copyProperties(one, parkingBillInfoVO);
|
||
parkingBillInfoVO.setTotalCostYuan(one.getTotalCostYuan().toString() + "元");
|
||
parkingBillInfoVO.setPayMoneyYuan(one.getPayMoneyYuan().toString() + "元");
|
||
parkingBillInfoVO.setDeductMoneyYuan(one.getDeductMoneyYuan().toString() + "元");
|
||
parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(one.getParkPeriodTime()));
|
||
return AjaxResult.success(parkingBillInfoVO);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
@GetMapping("/getHistoryPlateNo")
|
||
@ApiOperation("历史缴费车牌列表")
|
||
public AjaxResult getHistoryOrder(HttpServletRequest request){
|
||
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
|
||
if (loginUserByPhone == null) {
|
||
return AjaxResult.error("用户未登录");
|
||
}
|
||
String phone = loginUserByPhone.getPhone();
|
||
List<ParkingBillPaymentInfo> list = parkingBillPaymentInfoService.lambdaQuery()
|
||
.eq(ParkingBillPaymentInfo::getPhone, phone)
|
||
.eq(ParkingBillPaymentInfo::getPayStatus, 1)
|
||
.list();
|
||
Map<String, List<ParkingBillPaymentInfo>> groupedByPlateNo = list.stream()
|
||
.collect(Collectors.groupingBy(
|
||
ParkingBillPaymentInfo::getPlateNo, // 按车牌分组
|
||
Collectors.toList() // 收集为List
|
||
));
|
||
ArrayList<Map<String, String>> maps = new ArrayList<>();
|
||
for (String plateNo : groupedByPlateNo.keySet()) {
|
||
List<ParkingBillPaymentInfo> list1 = groupedByPlateNo.get(plateNo);
|
||
ParkingBillPaymentInfo parkingBillPaymentInfo = list1.get(0);
|
||
Map<String, String> map = new HashMap<>();
|
||
map.put("plateNo", plateNo);
|
||
map.put("plateColor",parkingBillPaymentInfo.getPlateColorCn());
|
||
maps.add(map);
|
||
}
|
||
return AjaxResult.success(maps);
|
||
}
|
||
|
||
|
||
|
||
@GetMapping("/getHistoryNoPayOrder")
|
||
@ApiOperation("查询历史未缴费订单")
|
||
public AjaxResult getHistoryNoPayOrder(HttpServletRequest request){
|
||
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
|
||
if (loginUserByPhone == null) {
|
||
return AjaxResult.error("用户未登录");
|
||
}
|
||
List<CustomerPlateNoInfo> list = customerPlateNoInfoService.lambdaQuery()
|
||
.eq(CustomerPlateNoInfo::getPhone, loginUserByPhone.getPhone())
|
||
.list();
|
||
List<String> collect = list.stream().map(CustomerPlateNoInfo::getPlateNo).collect(Collectors.toList());
|
||
if (collect.isEmpty()){
|
||
return AjaxResult.success(collect);
|
||
}
|
||
List<ParkingBillInfo> list1 = parkingBillInfoService.lambdaQuery()
|
||
.in(ParkingBillInfo::getPlateNo, collect)
|
||
.eq(ParkingBillInfo::getIsPay, 0)
|
||
.list();
|
||
List<ParkingBillInfoVO> parkingBillInfoVOS = new ArrayList<>();
|
||
list1.forEach(b -> {
|
||
ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO();
|
||
BeanUtils.copyProperties(b, parkingBillInfoVO);
|
||
parkingBillInfoVO.setTotalCostYuan(b.getTotalCostYuan().toString() + "元");
|
||
parkingBillInfoVO.setPayMoneyYuan(b.getPayMoneyYuan().toString() + "元");
|
||
parkingBillInfoVO.setDeductMoneyYuan(b.getDeductMoneyYuan().toString() + "元");
|
||
parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(b.getParkPeriodTime()));
|
||
parkingBillInfoVOS.add(parkingBillInfoVO);
|
||
});
|
||
return AjaxResult.success(parkingBillInfoVOS);
|
||
}
|
||
|
||
|
||
|
||
|
||
@GetMapping("/getBindTheVehicle")
|
||
@ApiOperation("查询已绑定车辆")
|
||
public AjaxResult getBindTheVehicle(HttpServletRequest request){
|
||
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
|
||
if (loginUserByPhone == null) {
|
||
return AjaxResult.error("用户未登录");
|
||
}
|
||
List<CustomerPlateNoInfo> list = customerPlateNoInfoService.lambdaQuery()
|
||
.eq(CustomerPlateNoInfo::getPhone, loginUserByPhone.getPhone())
|
||
.list();
|
||
return AjaxResult.success(list);
|
||
}
|
||
|
||
|
||
|
||
@PostMapping("/bindTheVehicle")
|
||
@ApiOperation("绑定车辆")
|
||
public AjaxResult bindTheVehicle(@RequestBody BindTheVehicle bindTheVehicle,HttpServletRequest request){
|
||
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
|
||
String plateNo = bindTheVehicle.getPlateNo();
|
||
if (plateNo == null || "".equals(plateNo)) {
|
||
return AjaxResult.error("绑定的车牌不能为空");
|
||
}else{
|
||
boolean valid = LicensePlateValidator.isValid(plateNo);
|
||
if (!valid) {
|
||
return AjaxResult.error("绑定的车牌格式不正确");
|
||
}
|
||
}
|
||
List<CustomerPlateNoInfo> list = customerPlateNoInfoService.lambdaQuery()
|
||
.eq(CustomerPlateNoInfo::getPlateNo, plateNo)
|
||
.list();
|
||
if (list != null && list.size() > 0) {
|
||
return AjaxResult.error("车牌已被绑定");
|
||
}
|
||
CustomerPlateNoInfo customerPlateNoInfo = new CustomerPlateNoInfo();
|
||
customerPlateNoInfo.setPlateNo(plateNo);
|
||
customerPlateNoInfo.setPlateType(bindTheVehicle.getPlateType());
|
||
customerPlateNoInfo.setPhone(loginUserByPhone.getPhone());
|
||
return toAjax(customerPlateNoInfoService.saveOrUpdate(customerPlateNoInfo));
|
||
}
|
||
|
||
|
||
|
||
@PostMapping("/payFees")
|
||
@ApiOperation("缴费")
|
||
@Transactional
|
||
public AjaxResult payFees(@RequestBody PayFees payFees,HttpServletRequest request){
|
||
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
|
||
|
||
ParkingBillInfo one = parkingBillInfoService.getById(payFees.getId());
|
||
if (one == null) {
|
||
return AjaxResult.error("停车记录查询失败");
|
||
}
|
||
ParkingBillInfo parkingBillInfo = parkingBillInfoService.saveOrUpdateParkingBillInfo(one.getPlateNo());
|
||
if (parkingBillInfo != null) {
|
||
one = parkingBillInfo;
|
||
}
|
||
String generate = generate(loginUserByPhone.getPhone());
|
||
BaseCustomerInfo one1 = baseCustomerInfoService.lambdaQuery()
|
||
.eq(BaseCustomerInfo::getPhone, loginUserByPhone.getPhone())
|
||
.last("limit 1")
|
||
.one();
|
||
if (one1 == null) {
|
||
return AjaxResult.error("用户信息出错");
|
||
}
|
||
String openId = null;
|
||
String userId = null;
|
||
PayType payType = PayType.getByCode(payFees.getPayType());
|
||
switch (payType) {
|
||
case WECHAT:
|
||
openId = one1.getOpenId();
|
||
break;
|
||
case ALIPAY:
|
||
openId = one1.getAlipayOpenId();
|
||
userId = one1.getAlipayUserId();
|
||
break;
|
||
}
|
||
String clientIp = wechatMiniProgramPayService.getClientIpAddress(request);
|
||
Map<String, Object> order = createOrder(payFees, generate, openId, one, clientIp, userId);
|
||
|
||
ParkingBillPaymentInfo parkingBillPaymentInfo = new ParkingBillPaymentInfo();
|
||
parkingBillPaymentInfo.setBillCode(one.getBillCode());
|
||
parkingBillPaymentInfo.setPlateNo(one.getPlateNo());
|
||
parkingBillPaymentInfo.setPlateColor(one.getPlateColor());
|
||
parkingBillPaymentInfo.setOpenId(openId);
|
||
parkingBillPaymentInfo.setPayType(payFees.getPayType());
|
||
parkingBillPaymentInfo.setPhone(loginUserByPhone.getPhone());
|
||
parkingBillPaymentInfo.setPayStatus(0);
|
||
parkingBillPaymentInfo.setOrderId(generate);
|
||
parkingBillPaymentInfo.setInUnid(one.getInUnid());
|
||
boolean b = parkingBillPaymentInfoService.saveOrUpdate(parkingBillPaymentInfo);
|
||
if (b) {
|
||
return AjaxResult.success(order);
|
||
}else {
|
||
return AjaxResult.error("创建订单出错");
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 创建支付宝 微信 订单
|
||
* @param payFees
|
||
* @param orderId
|
||
* @param openId
|
||
* @param parkingBillInfo
|
||
* @param clientIp
|
||
* @return
|
||
*/
|
||
private Map<String, Object> createOrder(PayFees payFees,
|
||
String orderId,
|
||
String openId,
|
||
ParkingBillInfo parkingBillInfo,
|
||
String clientIp,
|
||
String userId) {
|
||
PayType payType = PayType.getByCode(payFees.getPayType());
|
||
|
||
switch (payType) {
|
||
case WECHAT:
|
||
return wechatMiniProgramPayService.createJsapiOrder(
|
||
openId,orderId,parkingBillInfo.getPayMoney(),
|
||
"常客隆智慧停车缴费",clientIp);
|
||
case ALIPAY:
|
||
return alipayService.createOrder(orderId,
|
||
parkingBillInfo.getPayMoneyYuan().toString(),
|
||
"常客隆智慧停车缴费",openId,userId);
|
||
|
||
default:
|
||
throw new IllegalArgumentException("不支持的登录方式: " + payType);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
public static String generate(String phone) {
|
||
// 1. 参数校验
|
||
if (phone == null || phone.length() < 4) {
|
||
throw new IllegalArgumentException("Invalid phone number");
|
||
}
|
||
// 2. 获取手机尾号(后4位更常见)
|
||
String phoneSuffix = phone.substring(phone.length() - 4);
|
||
// 3. 使用更精确的时间戳
|
||
String timePart = Instant.now().toEpochMilli() + ""; // 毫秒时间戳
|
||
// 4. 增加更多随机性
|
||
int random = ThreadLocalRandom.current().nextInt(1000, 9999);
|
||
return phoneSuffix + timePart.substring(timePart.length() - 10) + random;
|
||
}
|
||
|
||
|
||
public static String minutesToDHMS(int minutes) {
|
||
int days = minutes / 1440; // 1440 = 24 * 60
|
||
int hours = (minutes % 1440) / 60;
|
||
int mins = minutes % 60;
|
||
int secs = 0;
|
||
|
||
return days + "天" +
|
||
String.format("%02d", hours) + "小时" +
|
||
String.format("%02d", mins) + "分钟" +
|
||
String.format("%02d", secs) + "秒";
|
||
}
|
||
}
|