发票 积分 支付逻辑修改

This commit is contained in:
hanrenchun 2026-04-08 10:10:07 +08:00
parent e62fdd9e34
commit b408554bdb
25 changed files with 1216 additions and 55 deletions

View File

@ -0,0 +1,174 @@
package com.ruoyi.database.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.Log;
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.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.database.domain.BaseCouponInfo;
import com.ruoyi.database.domain.dto.ReceiveCouponDto;
import com.ruoyi.database.service.BaseCouponInfoService;
import com.ruoyi.database.util.MoneyFormatUtil;
import com.ruoyi.framework.web.service.TokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 优惠卷基础信息表(BaseCouponInfo)Controller
*
* @author hanrenchun
* @since 2026-04-03 18:09:43
*/
@RequestMapping("/BaseCouponInfo")
@Api(tags = "优惠卷基础信息")
@RestController
@RequiredArgsConstructor
public class BaseCouponInfoController extends BaseController {
private final BaseCouponInfoService baseCouponInfoService;
private final TokenService tokenService;
@GetMapping
@ApiOperation("查询优惠卷基础信息表")
public TableDataInfo<BaseCouponInfo> list(BaseCouponInfo baseCouponInfo) {
startPage();
QueryWrapper<BaseCouponInfo> queryWrapper = new QueryWrapper<>(baseCouponInfo);
List<BaseCouponInfo> list = baseCouponInfoService.list(queryWrapper);
long size = baseCouponInfoService.count(queryWrapper);
return getDataTableEnhance(list, size);
}
@PostMapping
@ApiOperation("新增优惠卷基础信息表")
@Log(title = "优惠卷基础信息表", businessType = BusinessType.INSERT)
public AjaxResult insert(@RequestBody BaseCouponInfo baseCouponInfo) {
return toAjax(baseCouponInfoService.save(baseCouponInfo));
}
@PutMapping
@ApiOperation("修改优惠卷基础信息表")
@Log(title = "优惠卷基础信息表", businessType = BusinessType.UPDATE)
public AjaxResult update(@RequestBody BaseCouponInfo baseCouponInfo) {
return toAjax(baseCouponInfoService.updateById(baseCouponInfo));
}
@DeleteMapping
@ApiOperation("删除优惠卷基础信息表")
@Log(title = "优惠卷基础信息表", businessType = BusinessType.DELETE)
public AjaxResult delete(@RequestParam("idList") List<Long> idList) {
return toAjax(baseCouponInfoService.removeByIds(idList));
}
@GetMapping("/byOrderId")
@ApiOperation("根据订单id查询优惠劵领取状态")
public AjaxResult getBaseCouponInfo(@RequestParam String orderId, HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (loginUserByPhone == null) {
return AjaxResult.error("用户未登录");
}
// if (amount.compareTo(new BigDecimal(300)) < 0) {
// BaseCouponInfo couponInfo = new BaseCouponInfo();
// couponInfo.setOrderId(orderId);
// couponInfo.setReceiveState(false);
// return AjaxResult.success(couponInfo);
// }
BaseCouponInfo baseCouponInfo = baseCouponInfoService.lambdaQuery()
.eq(BaseCouponInfo::getOrderId, orderId)
.last("LIMIT 1")
.one();
if (baseCouponInfo == null) {
BaseCouponInfo couponInfo = new BaseCouponInfo();
couponInfo.setOrderId(orderId);
// couponInfo.setOrderAmount(amount);
couponInfo.setReceiveState(true);
couponInfo.setDiscountAmount(new BigDecimal("20.00"));
couponInfo.setDiscountAmountCn(MoneyFormatUtil.formatMoney(couponInfo.getDiscountAmount()));
// couponInfo.setOrderAmountCn(MoneyFormatUtil.formatMoney(amount));
baseCouponInfoService.save(couponInfo);
return AjaxResult.success(couponInfo);
}
baseCouponInfo.setDiscountAmountCn(MoneyFormatUtil.formatMoney(baseCouponInfo.getDiscountAmount()));
// baseCouponInfo.setOrderAmountCn(MoneyFormatUtil.formatMoney(amount));
return AjaxResult.success(baseCouponInfo);
}
@PostMapping("/receive")
@ApiOperation("领取优惠卷")
public AjaxResult receive(@RequestParam String orderId, @RequestParam String plateNo, HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (loginUserByPhone == null) {
return AjaxResult.error("用户未登录");
}
BaseCouponInfo one = baseCouponInfoService.lambdaQuery()
.eq(BaseCouponInfo::getOrderId, orderId)
.one();
if (one == null){
BaseCouponInfo couponInfo = new BaseCouponInfo();
couponInfo.setOrderId(orderId);
// couponInfo.setOrderAmount(amount);
couponInfo.setReceiveState(false);
couponInfo.setPhone(loginUserByPhone.getPhone());
couponInfo.setDiscountAmount(new BigDecimal("20.00"));
couponInfo.setReceiveTime(System.currentTimeMillis() / 1000L);
couponInfo.setPlateNo(plateNo);
couponInfo.setDiscountAmountCn(MoneyFormatUtil.formatMoney(couponInfo.getDiscountAmount()));
// couponInfo.setOrderAmountCn(MoneyFormatUtil.formatMoney(amount));
baseCouponInfoService.save(couponInfo);
return AjaxResult.success(couponInfo);
}
if (one.isReceiveState()){
one.setReceiveState(false);
}else {
return AjaxResult.error("该优惠卷已被领取");
}
one.setPlateNo(plateNo);
one.setPhone(loginUserByPhone.getPhone());
one.setReceiveTime(System.currentTimeMillis() / 1000L);
boolean b = baseCouponInfoService.updateById(one);
if (b){
return AjaxResult.success(one);
}else {
return AjaxResult.error("领取失败,稍后在试");
}
}
public static void main(String[] args) {
BigDecimal num1 = new BigDecimal("123.45");
BigDecimal num2 = new BigDecimal("123.45");
BigDecimal num3 = new BigDecimal("456.78");
// 比较num1和num2
int result1 = num1.compareTo(num2);
System.out.println("num1 和 num2 的比较结果: " + result1); // 输出0因为它们相等
// 比较num1和num3
int result2 = num1.compareTo(num3);
System.out.println("num1 和 num3 的比较结果: " + result2); // 输出负值因为num1小于num3
// 比较num3和num1
int result3 = num3.compareTo(num1);
System.out.println("num3 和 num1 的比较结果: " + result3); // 输出正值因为num3大于num1
}
}

View File

@ -0,0 +1,68 @@
package com.ruoyi.database.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.Log;
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.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.database.domain.BaseInvoiceInfo;
import com.ruoyi.database.domain.dto.BaseInvoiceInfoDto;
import com.ruoyi.database.service.BaseInvoiceInfoService;
import com.ruoyi.framework.web.service.TokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
/**
* 发票信息表(BaseInvoiceInfo)Controller
*
* @author hanrenchun
* @since 2026-04-08 09:26:38
*/
@RequestMapping("/BaseInvoiceInfo")
@Api(tags = "发票信息")
@RestController
@RequiredArgsConstructor
public class BaseInvoiceInfoController extends BaseController {
private final BaseInvoiceInfoService baseInvoiceInfoService;
private final TokenService tokenService;
@GetMapping
@ApiOperation("查询当前已开发票信息")
public TableDataInfo<BaseInvoiceInfo> list(BaseInvoiceInfo baseInvoiceInfo, HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
QueryWrapper<BaseInvoiceInfo> queryWrapper = new QueryWrapper<>(baseInvoiceInfo);
queryWrapper.eq("user_phone",loginUserByPhone.getPhone());
PageUtils.startPage();
List<BaseInvoiceInfo> list = baseInvoiceInfoService.list(queryWrapper);
long size = baseInvoiceInfoService.count(queryWrapper);
return getDataTableEnhance(list, size);
}
@PostMapping
@ApiOperation("新增发票开票任务")
public AjaxResult insert(@RequestBody BaseInvoiceInfoDto baseInvoiceInfo, HttpServletRequest request) {
BaseInvoiceInfo invoiceInfo = new BaseInvoiceInfo();
BeanUtils.copyProperties(baseInvoiceInfo,invoiceInfo);
invoiceInfo.setInvoiceTypeCode(0);
invoiceInfo.setPriceTaxMark(1);
return toAjax(baseInvoiceInfoService.save(invoiceInfo));
}
}

View File

@ -72,8 +72,11 @@ public class ParkingBillInfoController extends BaseController {
ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO(); ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO();
BeanUtils.copyProperties(b, parkingBillInfoVO); BeanUtils.copyProperties(b, parkingBillInfoVO);
parkingBillInfoVO.setTotalCostYuan(b.getTotalCostYuan().toString() + ""); parkingBillInfoVO.setTotalCostYuan(b.getTotalCostYuan().toString() + "");
parkingBillInfoVO.setTotalCost(b.getTotalCostYuan());
parkingBillInfoVO.setPayMoneyYuan(b.getPayMoneyYuan().toString() + ""); parkingBillInfoVO.setPayMoneyYuan(b.getPayMoneyYuan().toString() + "");
parkingBillInfoVO.setPayMoney(b.getPayMoneyYuan());
parkingBillInfoVO.setDeductMoneyYuan(b.getDeductMoneyYuan().toString() + ""); parkingBillInfoVO.setDeductMoneyYuan(b.getDeductMoneyYuan().toString() + "");
parkingBillInfoVO.setDeductMoney(b.getDeductMoneyYuan());
parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(b.getParkPeriodTime())); parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(b.getParkPeriodTime()));
parkingBillInfoVOS.add(parkingBillInfoVO); parkingBillInfoVOS.add(parkingBillInfoVO);
}); });

View File

@ -12,25 +12,25 @@ import org.springframework.web.bind.annotation.RestController;
* @Author lijingtong * @Author lijingtong
* @Date 2026-01-19 * @Date 2026-01-19
*/ */
@RestController //@RestController
@RequestMapping("/ParkingScore") //@RequestMapping("/ParkingScore")
@Api(tags = "积分") //@Api(tags = "积分")
@RequiredArgsConstructor //@RequiredArgsConstructor
public class ParkingScoreController { public class ParkingScoreController {
private final ParkingPointsService service; // private final ParkingPointsService service;
@RequestMapping("/queryScore") // @RequestMapping("/queryScore")
@ApiOperation("查询积分") // @ApiOperation("查询积分")
public String queryScore(String phone) throws Exception { // public String queryScore(String phone) throws Exception {
return service.queryScore(phone); // return service.queryScore(phone);
} // }
//
//
@RequestMapping("/payScore") // @RequestMapping("/payScore")
@ApiOperation("积分支付") // @ApiOperation("积分支付")
public String payScore(String phone, int money) throws Exception { // public String payScore(String phone, int money) throws Exception {
return service.payScore(phone, money); // return service.payScore(phone, money);
} // }

View File

@ -17,6 +17,8 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -25,6 +27,9 @@ import java.util.Map;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.ruoyi.database.service.ParkingPointsService.parseResponseToMap;
import static com.ruoyi.database.service.ParkingPointsService.queryScore;
@Api(tags = "小程序接口") @Api(tags = "小程序接口")
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@ -38,7 +43,7 @@ public class SmallProgramController extends BaseController {
private final ParkingBillPaymentInfoService parkingBillPaymentInfoService; private final ParkingBillPaymentInfoService parkingBillPaymentInfoService;
private final CustomerPlateNoInfoService customerPlateNoInfoService; private final CustomerPlateNoInfoService customerPlateNoInfoService;
private final TokenService tokenService; private final TokenService tokenService;
private final ParkingPointsService parkingPointsService;
@GetMapping("/getOrder") @GetMapping("/getOrder")
@ -46,31 +51,33 @@ public class SmallProgramController extends BaseController {
@Transactional @Transactional
public AjaxResult getOrder(String plateNo) { public AjaxResult getOrder(String plateNo) {
String trim = plateNo.trim(); String trim = plateNo.trim();
ParkingBillInfo one = parkingBillInfoService.saveOrUpdateParkingBillInfo(trim); // ParkingBillInfo one = parkingBillInfoService.saveOrUpdateParkingBillInfo(trim);
// ParkingBillInfo one = parkingBillInfoService.lambdaQuery() ParkingBillInfo one = parkingBillInfoService.lambdaQuery()
// .eq(ParkingBillInfo::getPlateNo, plateNo) .eq(ParkingBillInfo::getPlateNo, plateNo)
// .orderByDesc(ParkingBillInfo::getCreateTime) .orderByDesc(ParkingBillInfo::getCreateTime)
// .last("limit 1") .last("limit 1")
// .one(); .one();
if (one == null) { if (one == null) {
return AjaxResult.error("未查询到停车记录"); return AjaxResult.error("未查询到停车记录");
}else { } else {
ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO(); ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO();
BeanUtils.copyProperties(one, parkingBillInfoVO); BeanUtils.copyProperties(one, parkingBillInfoVO);
parkingBillInfoVO.setTotalCostYuan(one.getTotalCostYuan().toString() + ""); parkingBillInfoVO.setTotalCostYuan(one.getTotalCostYuan().toString() + "");
parkingBillInfoVO.setTotalCost(one.getTotalCostYuan());
parkingBillInfoVO.setPayMoneyYuan(one.getPayMoneyYuan().toString() + ""); parkingBillInfoVO.setPayMoneyYuan(one.getPayMoneyYuan().toString() + "");
parkingBillInfoVO.setPayMoney(one.getPayMoneyYuan());
parkingBillInfoVO.setDeductMoneyYuan(one.getDeductMoneyYuan().toString() + ""); parkingBillInfoVO.setDeductMoneyYuan(one.getDeductMoneyYuan().toString() + "");
parkingBillInfoVO.setDeductMoney(one.getDeductMoneyYuan());
parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(one.getParkPeriodTime())); parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(one.getParkPeriodTime()));
return AjaxResult.success(parkingBillInfoVO); return AjaxResult.success(parkingBillInfoVO);
} }
} }
@GetMapping("/getHistoryPlateNo") @GetMapping("/getHistoryPlateNo")
@ApiOperation("历史缴费车牌列表") @ApiOperation("历史缴费车牌列表")
public AjaxResult getHistoryOrder(HttpServletRequest request){ public AjaxResult getHistoryOrder(HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request); LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (loginUserByPhone == null) { if (loginUserByPhone == null) {
return AjaxResult.error("用户未登录"); return AjaxResult.error("用户未登录");
@ -79,6 +86,8 @@ public class SmallProgramController extends BaseController {
List<ParkingBillPaymentInfo> list = parkingBillPaymentInfoService.lambdaQuery() List<ParkingBillPaymentInfo> list = parkingBillPaymentInfoService.lambdaQuery()
.eq(ParkingBillPaymentInfo::getPhone, phone) .eq(ParkingBillPaymentInfo::getPhone, phone)
.eq(ParkingBillPaymentInfo::getPayStatus, 1) .eq(ParkingBillPaymentInfo::getPayStatus, 1)
.orderByDesc(ParkingBillPaymentInfo::getCreateTime)
.last("LIMIT 100")
.list(); .list();
Map<String, List<ParkingBillPaymentInfo>> groupedByPlateNo = list.stream() Map<String, List<ParkingBillPaymentInfo>> groupedByPlateNo = list.stream()
.collect(Collectors.groupingBy( .collect(Collectors.groupingBy(
@ -91,17 +100,16 @@ public class SmallProgramController extends BaseController {
ParkingBillPaymentInfo parkingBillPaymentInfo = list1.get(0); ParkingBillPaymentInfo parkingBillPaymentInfo = list1.get(0);
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("plateNo", plateNo); map.put("plateNo", plateNo);
map.put("plateColor",parkingBillPaymentInfo.getPlateColorCn()); map.put("plateColor", parkingBillPaymentInfo.getPlateColorCn());
maps.add(map); maps.add(map);
} }
return AjaxResult.success(maps); return AjaxResult.success(maps);
} }
@GetMapping("/getHistoryNoPayOrder") @GetMapping("/getHistoryNoPayOrder")
@ApiOperation("查询历史未缴费订单") @ApiOperation("查询历史未缴费订单")
public AjaxResult getHistoryNoPayOrder(HttpServletRequest request){ public AjaxResult getHistoryNoPayOrder(HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request); LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (loginUserByPhone == null) { if (loginUserByPhone == null) {
return AjaxResult.error("用户未登录"); return AjaxResult.error("用户未登录");
@ -110,7 +118,7 @@ public class SmallProgramController extends BaseController {
.eq(CustomerPlateNoInfo::getPhone, loginUserByPhone.getPhone()) .eq(CustomerPlateNoInfo::getPhone, loginUserByPhone.getPhone())
.list(); .list();
List<String> collect = list.stream().map(CustomerPlateNoInfo::getPlateNo).collect(Collectors.toList()); List<String> collect = list.stream().map(CustomerPlateNoInfo::getPlateNo).collect(Collectors.toList());
if (collect.isEmpty()){ if (collect.isEmpty()) {
return AjaxResult.success(collect); return AjaxResult.success(collect);
} }
List<ParkingBillInfo> list1 = parkingBillInfoService.lambdaQuery() List<ParkingBillInfo> list1 = parkingBillInfoService.lambdaQuery()
@ -122,8 +130,11 @@ public class SmallProgramController extends BaseController {
ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO(); ParkingBillInfoVO parkingBillInfoVO = new ParkingBillInfoVO();
BeanUtils.copyProperties(b, parkingBillInfoVO); BeanUtils.copyProperties(b, parkingBillInfoVO);
parkingBillInfoVO.setTotalCostYuan(b.getTotalCostYuan().toString() + ""); parkingBillInfoVO.setTotalCostYuan(b.getTotalCostYuan().toString() + "");
parkingBillInfoVO.setTotalCost(b.getTotalCostYuan());
parkingBillInfoVO.setPayMoneyYuan(b.getPayMoneyYuan().toString() + ""); parkingBillInfoVO.setPayMoneyYuan(b.getPayMoneyYuan().toString() + "");
parkingBillInfoVO.setPayMoney(b.getPayMoneyYuan());
parkingBillInfoVO.setDeductMoneyYuan(b.getDeductMoneyYuan().toString() + ""); parkingBillInfoVO.setDeductMoneyYuan(b.getDeductMoneyYuan().toString() + "");
parkingBillInfoVO.setDeductMoney(b.getDeductMoneyYuan());
parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(b.getParkPeriodTime())); parkingBillInfoVO.setParkPeriodTime(minutesToDHMS(b.getParkPeriodTime()));
parkingBillInfoVOS.add(parkingBillInfoVO); parkingBillInfoVOS.add(parkingBillInfoVO);
}); });
@ -131,11 +142,9 @@ public class SmallProgramController extends BaseController {
} }
@GetMapping("/getBindTheVehicle") @GetMapping("/getBindTheVehicle")
@ApiOperation("查询已绑定车辆") @ApiOperation("查询已绑定车辆")
public AjaxResult getBindTheVehicle(HttpServletRequest request){ public AjaxResult getBindTheVehicle(HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request); LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (loginUserByPhone == null) { if (loginUserByPhone == null) {
return AjaxResult.error("用户未登录"); return AjaxResult.error("用户未登录");
@ -147,15 +156,14 @@ public class SmallProgramController extends BaseController {
} }
@PostMapping("/bindTheVehicle") @PostMapping("/bindTheVehicle")
@ApiOperation("绑定车辆") @ApiOperation("绑定车辆")
public AjaxResult bindTheVehicle(@RequestBody BindTheVehicle bindTheVehicle,HttpServletRequest request){ public AjaxResult bindTheVehicle(@RequestBody BindTheVehicle bindTheVehicle, HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request); LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
String plateNo = bindTheVehicle.getPlateNo(); String plateNo = bindTheVehicle.getPlateNo();
if (plateNo == null || "".equals(plateNo)) { if (plateNo == null || "".equals(plateNo)) {
return AjaxResult.error("绑定的车牌不能为空"); return AjaxResult.error("绑定的车牌不能为空");
}else{ } else {
boolean valid = LicensePlateValidator.isValid(plateNo); boolean valid = LicensePlateValidator.isValid(plateNo);
if (!valid) { if (!valid) {
return AjaxResult.error("绑定的车牌格式不正确"); return AjaxResult.error("绑定的车牌格式不正确");
@ -175,11 +183,43 @@ public class SmallProgramController extends BaseController {
} }
@GetMapping("/getPoints")
@ApiOperation("获取当前积分")
public AjaxResult getPoints(HttpServletRequest request) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (loginUserByPhone == null) {
return AjaxResult.error("用户未登录");
}
try {
String phone = loginUserByPhone.getPhone();
String queryResult = ParkingPointsService.queryScore(phone);
System.out.println("查询积分结果:" + queryResult);
Map<String, Object> stringObjectMap = parseResponseToMap(queryResult);
System.out.println(stringObjectMap);
Object score = stringObjectMap.get("score");
BaseCustomerInfo one = baseCustomerInfoService.lambdaQuery()
.eq(BaseCustomerInfo::getPhone, phone)
.last("LIMIT 1")
.one();
one.setIntegral(score.toString());
boolean b = baseCustomerInfoService.updateById(one);
if (b) {
return AjaxResult.success(stringObjectMap);
}else {
return AjaxResult.error("积分功能维护中");
}
} catch (Exception e) {
return AjaxResult.error("积分功能维护中");
}
}
@PostMapping("/payFees") @PostMapping("/payFees")
@ApiOperation("缴费") @ApiOperation("缴费")
@Transactional @Transactional
public AjaxResult payFees(@RequestBody PayFees payFees,HttpServletRequest request){ public AjaxResult payFees(@RequestBody PayFees payFees, HttpServletRequest request) throws Exception {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request); LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
ParkingBillInfo one = parkingBillInfoService.getById(payFees.getId()); ParkingBillInfo one = parkingBillInfoService.getById(payFees.getId());
@ -198,6 +238,37 @@ public class SmallProgramController extends BaseController {
if (one1 == null) { if (one1 == null) {
return AjaxResult.error("用户信息出错"); return AjaxResult.error("用户信息出错");
} }
Integer points = payFees.getPoints();
if (points != null && points >= 300) {
try {
String phone = loginUserByPhone.getPhone();
String queryResult = ParkingPointsService.queryScore(phone);
System.out.println("查询积分结果:" + queryResult);
Map<String, Object> stringObjectMap = parseResponseToMap(queryResult);
System.out.println(stringObjectMap);
Object score = stringObjectMap.get("score");
one1.setIntegral(score.toString());
boolean b = baseCustomerInfoService.updateById(one1);
if (b) {
// String integral = one1.getIntegral();
int i = calculateDeductPoints(points);
BigDecimal bigDecimal = pointsToAmount(i);
one.setDeductMoney(Integer.valueOf(bigDecimal.multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN).toString()));
one.setDeductMoneyYuan(bigDecimal);
one.setPayMoney(Integer.valueOf(one.getPayMoneyYuan().subtract(bigDecimal).multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN).toString()));
one.setPayMoneyYuan(one.getPayMoneyYuan().subtract(bigDecimal));
}else {
return AjaxResult.error("积分功能维护中");
}
} catch (Exception e) {
return AjaxResult.error("积分功能维护中");
}
// points
}
String openId = null; String openId = null;
String userId = null; String userId = null;
PayType payType = PayType.getByCode(payFees.getPayType()); PayType payType = PayType.getByCode(payFees.getPayType());
@ -226,7 +297,7 @@ public class SmallProgramController extends BaseController {
boolean b = parkingBillPaymentInfoService.saveOrUpdate(parkingBillPaymentInfo); boolean b = parkingBillPaymentInfoService.saveOrUpdate(parkingBillPaymentInfo);
if (b) { if (b) {
return AjaxResult.success(order); return AjaxResult.success(order);
}else { } else {
return AjaxResult.error("创建订单出错"); return AjaxResult.error("创建订单出错");
} }
@ -234,9 +305,30 @@ public class SmallProgramController extends BaseController {
} }
/**
* 计算可扣除积分只取300的整数倍不足不扣
*/
private int calculateDeductPoints(Integer userAvailablePoints) {
if (userAvailablePoints == null || userAvailablePoints < 300) {
return 0;
}
// 只保留 300 的整数倍例如 800 600
return (userAvailablePoints / 300) * 300;
}
/**
* 积分转抵扣金额 300积分 = 1元
*/
private BigDecimal pointsToAmount(int deductPoints) {
if (deductPoints <= 0) return BigDecimal.ZERO;
return new BigDecimal(deductPoints).divide(new BigDecimal(300), 2, RoundingMode.DOWN);
}
/** /**
* 创建支付宝 微信 订单 * 创建支付宝 微信 订单
*
* @param payFees * @param payFees
* @param orderId * @param orderId
* @param openId * @param openId
@ -249,18 +341,22 @@ public class SmallProgramController extends BaseController {
String openId, String openId,
ParkingBillInfo parkingBillInfo, ParkingBillInfo parkingBillInfo,
String clientIp, String clientIp,
String userId) { String userId) throws Exception {
PayType payType = PayType.getByCode(payFees.getPayType()); PayType payType = PayType.getByCode(payFees.getPayType());
switch (payType) { switch (payType) {
case WECHAT: case WECHAT:
return wechatMiniProgramPayService.createJsapiOrder( return wechatMiniProgramPayService.createJsapiOrder(
openId,orderId,parkingBillInfo.getPayMoney(), openId, orderId, parkingBillInfo.getPayMoney(),
"常客隆智慧停车缴费",clientIp); "常客隆智慧停车缴费", clientIp);
case ALIPAY: case ALIPAY:
return alipayService.createOrder(orderId, return alipayService.createOrder(orderId,
parkingBillInfo.getPayMoneyYuan().toString(), parkingBillInfo.getPayMoneyYuan().toString(),
"常客隆智慧停车缴费",openId,userId); "常客隆智慧停车缴费", openId, userId);
// case POINTS:
// String payScore = parkingPointsService.payScore("", 1);
//
// return ;
default: default:
throw new IllegalArgumentException("不支持的登录方式: " + payType); throw new IllegalArgumentException("不支持的登录方式: " + payType);
@ -268,8 +364,6 @@ public class SmallProgramController extends BaseController {
} }
public static String generate(String phone) { public static String generate(String phone) {
// 1. 参数校验 // 1. 参数校验
if (phone == null || phone.length() < 4) { if (phone == null || phone.length() < 4) {

View File

@ -0,0 +1,113 @@
package com.ruoyi.database.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 优惠卷基础信息表(BaseCouponInfo)
*
* @author hanrenchun
* @since 2026-04-03 18:09:42
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "base_coupon_info")
@ApiModel(value = "BaseCouponInfo", description = "优惠卷基础信息表")
public class BaseCouponInfo extends BaseEntity {
/**
* 主键
*/
@ApiModelProperty("主键")
@Excel(name = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 订单id
*/
@ApiModelProperty("订单id")
@Excel(name = "订单id")
private String orderId;
/**
* 手机号
*/
@ApiModelProperty("手机号")
@Excel(name = "手机号")
private String phone;
/**
* 用户id
*/
@ApiModelProperty("用户id")
@Excel(name = "用户id")
private Long userId;
@ApiModelProperty("领取状态")
@Excel(name = "领取状态")
private boolean receiveState;
@ApiModelProperty("优惠金额")
@Excel(name = "优惠金额")
private BigDecimal discountAmount;
@TableField(exist = false)
private String discountAmountCn;
@ApiModelProperty("订单金额")
@Excel(name = "订单金额")
private BigDecimal orderAmount;
@TableField(exist = false)
private String orderAmountCn;
@ApiModelProperty("使用时间")
@Excel(name = "使用时间")
private Long useTime;
@TableField(exist = false)
private String useTimeCn;
@ApiModelProperty("使用状态")
@Excel(name = "使用状态")
private Integer useState;
@TableField(exist = false)
private String useStateCn;
@ApiModelProperty("领取时间")
@Excel(name = "领取时间")
private Long receiveTime;
@TableField(exist = false)
private String receiveTimeCn;
@ApiModelProperty("车牌号")
private String plateNo;
}

View File

@ -110,7 +110,7 @@ public class BaseCustomerInfo {
*/ */
@ApiModelProperty("积分") @ApiModelProperty("积分")
@Excel(name = "积分") @Excel(name = "积分")
private Long integral; private String integral;
/** /**
* 会员等级 * 会员等级

View File

@ -0,0 +1,162 @@
package com.ruoyi.database.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 发票信息表(BaseInvoiceInfo)
*
* @author hanrenchun
* @since 2026-04-08 09:34:39
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "base_invoice_info")
@ApiModel(value = "BaseInvoiceInfo", description = "发票信息表")
public class BaseInvoiceInfo extends BaseEntity {
/**
* 主键
*/
@ApiModelProperty("主键")
@Excel(name = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 记录唯一标识
*/
@ApiModelProperty("记录唯一标识")
@Excel(name = "记录唯一标识")
private String inUnid;
/**
* 发票下载地址
*/
@ApiModelProperty("发票下载地址")
@Excel(name = "发票下载地址")
private String pdfUrl;
/**
* 开票时间
*/
@ApiModelProperty("开票时间")
@Excel(name = "开票时间")
private Long invoiceTime;
/**
* 发票号码
*/
@ApiModelProperty("发票号码")
@Excel(name = "发票号码")
private String invoiceNo;
/**
* 开票请求流水号
*/
@ApiModelProperty("开票请求流水号")
@Excel(name = "开票请求流水号")
private String serialNo;
/**
* 开票状态
*/
@ApiModelProperty("开票状态")
@Excel(name = "开票状态")
private Integer isPushState;
@TableField(exist = false)
private String isPushStateCn;
/**
* 购方名称抬头
*/
@ApiModelProperty("购方名称,抬头")
@Excel(name = "购方名称,抬头")
private String buyerName;
/**
* 购方纳税识别号
*/
@ApiModelProperty("购方纳税识别号")
@Excel(name = "购方纳税识别号")
private String buyerTaxNo;
/**
* 购方地址
*/
@ApiModelProperty("购方地址")
@Excel(name = "购方地址")
private String buyerAddress;
/**
* 购方电话
*/
@ApiModelProperty("购方电话")
@Excel(name = "购方电话")
private String buyerTelephone;
/**
* 购方开户行
*/
@ApiModelProperty("购方开户行")
@Excel(name = "购方开户行")
private String buyerBankName;
/**
* 购方银行账号
*/
@ApiModelProperty("购方银行账号")
@Excel(name = "购方银行账号")
private String buyerBankNumber;
/**
* 发票种类:0-数电普票1-数电专票
*/
@ApiModelProperty("发票种类:0-数电普票1-数电专票")
@Excel(name = "发票种类:0-数电普票1-数电专票")
private Integer invoiceTypeCode;
/**
* 单价含税标志:0-不含税,1-含税
*/
@ApiModelProperty("单价含税标志:0-不含税,1-含税")
@Excel(name = "单价含税标志:0-不含税,1-含税")
private Integer priceTaxMark;
/**
* 开票总金额(含税)2位小数
*/
@ApiModelProperty("开票总金额(含税)2位小数")
@Excel(name = "开票总金额(含税)2位小数")
private BigDecimal totalAmount;
/**
* 备注
*/
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@ApiModelProperty("用户手机号")
@Excel(name = "用户手机号")
private String userPhone;
}

View File

@ -15,4 +15,8 @@ public class PayFees {
@ApiModelProperty("支付方式: wechat 或 alipay") @ApiModelProperty("支付方式: wechat 或 alipay")
@NotBlank(message = "支付方式不能为空") @NotBlank(message = "支付方式不能为空")
private String payType; private String payType;
@ApiModelProperty("支付积分额度")
private Integer points;
} }

View File

@ -0,0 +1,69 @@
package com.ruoyi.database.domain.dto;
import com.ruoyi.common.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "BaseInvoiceInfoDto")
public class BaseInvoiceInfoDto {
/**
* 记录唯一标识
*/
@ApiModelProperty("记录唯一标识")
@Excel(name = "记录唯一标识")
private String inUnid;
/**
* 购方名称抬头
*/
@ApiModelProperty("购方名称,抬头")
@Excel(name = "购方名称,抬头")
private String buyerName;
/**
* 购方纳税识别号
*/
@ApiModelProperty("购方纳税识别号")
@Excel(name = "购方纳税识别号")
private String buyerTaxNo;
/**
* 购方地址
*/
@ApiModelProperty("购方地址")
@Excel(name = "购方地址")
private String buyerAddress;
/**
* 购方电话
*/
@ApiModelProperty("购方电话")
@Excel(name = "购方电话")
private String buyerTelephone;
/**
* 购方开户行
*/
@ApiModelProperty("购方开户行")
@Excel(name = "购方开户行")
private String buyerBankName;
/**
* 购方银行账号
*/
@ApiModelProperty("购方银行账号")
@Excel(name = "购方银行账号")
private String buyerBankNumber;
/**
* 备注
*/
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
}

View File

@ -0,0 +1,77 @@
package com.ruoyi.database.domain.dto;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class InvoiceRequest {
/**
* 购方名称抬头
*/
private String buyerName;
/**
* 购方纳税识别号
*/
private String buyerTaxNo;
/**
* 购方地址
*/
private String buyerAddress;
/**
* 购方电话
*/
private String buyerTelephone;
/**
* 购方开户行
*/
private String buyerBankName;
/**
* 购方银行账号
*/
private String buyerBankNumber;
/**
* 发票种类:0-数电普票1-数电专票
*/
private Integer invoiceTypeCode;
/**
* 单价含税标志:0-不含税,1-含税
*/
private Integer priceTaxMark;
/**
* 开票总金额(含税)2位小数
*/
private BigDecimal totalAmount;
/**
* 备注
*/
private String remark;
/**
* 开票订单列表
*/
private List<InvoiceDetail> detailList;
@Data
public static class InvoiceDetail {
/**
* 开票订单号唯一
*/
private String billNo;
/**
* 订单开票金额(含税)2位小数
*/
private BigDecimal amount;
}
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.database.domain.dto;
import lombok.Data;
@Data
public class InvoiceRequestData {
private String appid;
private String data;
private Long timestamp;
private String sign;
}

View File

@ -0,0 +1,13 @@
package com.ruoyi.database.domain.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ReceiveCouponDto {
private String orderId;
private BigDecimal amount;
}

View File

@ -78,12 +78,18 @@ public class ParkingBillInfoVO {
private String totalCostYuan; private String totalCostYuan;
private BigDecimal totalCost;
private String deductMoneyYuan; private String deductMoneyYuan;
private BigDecimal deductMoney;
private String payMoneyYuan; private String payMoneyYuan;
private BigDecimal payMoney;
private String inUnid; private String inUnid;

View File

@ -6,7 +6,8 @@ import lombok.Getter;
@Getter @Getter
public enum PayType { public enum PayType {
WECHAT("wechat", "微信支付"), WECHAT("wechat", "微信支付"),
ALIPAY("alipay", "支付宝支付"); ALIPAY("alipay", "支付宝支付"),
POINTS("points", "积分支付");
private final String code; private final String code;
private final String description; private final String description;

View File

@ -0,0 +1,20 @@
package com.ruoyi.database.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.database.domain.BaseCouponInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
/**
* 优惠卷基础信息表(BaseCouponInfo) Mapper 接口
*
* @author hanrenchun
* @since 2026-04-03 18:09:42
*/
@Mapper
public interface BaseCouponInfoMapper extends BaseMapper<BaseCouponInfo> {
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.database.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.database.domain.BaseInvoiceInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
/**
* 发票信息表(BaseInvoiceInfo) Mapper 接口
*
* @author hanrenchun
* @since 2026-04-08 09:26:38
*/
@Mapper
public interface BaseInvoiceInfoMapper extends BaseMapper<BaseInvoiceInfo> {
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.database.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.database.domain.BaseCouponInfo;
import java.util.Date;
import java.util.List;
/**
* 优惠卷基础信息表(BaseCouponInfo)Service
*
* @author hanrenchun
* @since 2026-04-03 18:09:43
*/
public interface BaseCouponInfoService extends IService<BaseCouponInfo> {
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.database.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.database.domain.BaseInvoiceInfo;
import java.util.Date;
import java.util.List;
/**
* 发票信息表(BaseInvoiceInfo)Service
*
* @author hanrenchun
* @since 2026-04-08 09:26:38
*/
public interface BaseInvoiceInfoService extends IService<BaseInvoiceInfo> {
}

View File

@ -9,6 +9,9 @@ import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
@Service @Service
public class ParkingPointsService { public class ParkingPointsService {
@ -17,12 +20,13 @@ public class ParkingPointsService {
private static final String TOKEN = "VAR21UEUjhHmeMqiAvA7VYvQLPn5rO2z"; private static final String TOKEN = "VAR21UEUjhHmeMqiAvA7VYvQLPn5rO2z";
private static final String QUERY_SCORE_URL = "https://yxphp.ckldzsw.com/index/score/search"; private static final String QUERY_SCORE_URL = "https://yxphp.ckldzsw.com/index/score/search";
private static final String PAY_SCORE_URL = "https://yxphp.ckldzsw.com/index/score/reduce"; private static final String PAY_SCORE_URL = "https://yxphp.ckldzsw.com/index/score/reduce";
private static final ObjectMapper objectMapper = new ObjectMapper();
/** /**
* 生成签名 * 生成签名
* 签名规则md5(phone + timestamp + TOKEN) * 签名规则md5(phone + timestamp + TOKEN)
*/ */
public String generateSign(String phone, String timestamp) throws NoSuchAlgorithmException { public static String generateSign(String phone, String timestamp) throws NoSuchAlgorithmException {
String data = phone + timestamp + TOKEN; String data = phone + timestamp + TOKEN;
MessageDigest md = MessageDigest.getInstance("MD5"); MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data.getBytes()); md.update(data.getBytes());
@ -37,7 +41,7 @@ public class ParkingPointsService {
/** /**
* 查询积分 * 查询积分
*/ */
public String queryScore(String phone) throws Exception { public static String queryScore(String phone) throws Exception {
// 生成时间戳Unix时间戳秒级 // 生成时间戳Unix时间戳秒级
String timestamp = String.valueOf(System.currentTimeMillis() / 1000); String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
// 生成签名 // 生成签名
@ -72,7 +76,7 @@ public class ParkingPointsService {
/** /**
* 停车积分支付 * 停车积分支付
*/ */
public String payScore(String phone, int money) throws Exception { public static String payScore(String phone, int money) throws Exception {
// 生成时间戳Unix时间戳秒级 // 生成时间戳Unix时间戳秒级
String timestamp = String.valueOf(System.currentTimeMillis() / 1000); String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
// 生成签名 // 生成签名
@ -104,22 +108,62 @@ public class ParkingPointsService {
return response.toString(); return response.toString();
} }
/*public static void main(String[] args) { public static void main(String[] args) {
try { try {
// 示例查询积分 // 示例查询积分
String phone = "15599026928"; // String phone = "15599026928";
String phone = "13151593507";
String queryResult = queryScore(phone); String queryResult = queryScore(phone);
System.out.println("查询积分结果:" + queryResult); System.out.println("查询积分结果:" + queryResult);
Map<String, Object> stringObjectMap = parseResponseToMap(queryResult);
System.out.println(stringObjectMap);
// 示例停车积分支付支付1积分 // 示例停车积分支付支付1积分
String payResult = payScore(phone, 1); String payResult = payScore(phone, 0);
System.out.println("停车积分支付结果:" + payResult); System.out.println("停车积分支付结果:" + payResult);
Map<String, Object> stringObjectMap1 = parseResponseToMap(payResult);
System.out.println(stringObjectMap1);
String queryResult1 = queryScore(phone); String queryResult1 = queryScore(phone);
System.out.println("查询积分结果1" + queryResult1); System.out.println("查询积分结果1" + queryResult1);
Map<String, Object> stringObjectMap2 = parseResponseToMap(queryResult1);
System.out.println(stringObjectMap2);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
}*/ }
public static Map<String, Object> parseResponseToMap(Object response) {
try {
// 如果response本身就是Map类型
if (response instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) response;
return map;
}
// 如果response有toMap或asMap方法假设
try {
java.lang.reflect.Method method = response.getClass()
.getMethod("toMap");
if (Map.class.isAssignableFrom(method.getReturnType())) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) method.invoke(response);
return map;
}
} catch (NoSuchMethodException e) {
// 方法不存在继续尝试其他方式
}
// 尝试JSON解析
String jsonString = response.toString();
return objectMapper.readValue(jsonString,
new TypeReference<Map<String, Object>>() {});
} catch (Exception e) {
throw new RuntimeException("Failed to parse response to Map", e);
}
}
} }

View File

@ -0,0 +1,25 @@
package com.ruoyi.database.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.database.domain.BaseCouponInfo;
import com.ruoyi.database.mapper.BaseCouponInfoMapper;
import com.ruoyi.database.service.BaseCouponInfoService;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* 优惠卷基础信息表(BaseCouponInfo)ServiceImpl
*
* @author hanrenchun
* @since 2026-04-03 18:09:43
*/
@Service
public class BaseCouponInfoServiceImpl extends ServiceImpl<BaseCouponInfoMapper, BaseCouponInfo> implements BaseCouponInfoService {
}

View File

@ -0,0 +1,23 @@
package com.ruoyi.database.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.database.domain.BaseInvoiceInfo;
import com.ruoyi.database.mapper.BaseInvoiceInfoMapper;
import com.ruoyi.database.service.BaseInvoiceInfoService;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* 发票信息表(BaseInvoiceInfo)ServiceImpl
*
* @author hanrenchun
* @since 2026-04-08 09:26:38
*/
@Service
public class BaseInvoiceInfoServiceImpl extends ServiceImpl<BaseInvoiceInfoMapper, BaseInvoiceInfo> implements BaseInvoiceInfoService {
}

View File

@ -0,0 +1,75 @@
package com.ruoyi.database.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
public class EncryptUtils {
//AES秘钥与偏移量
private static final String AESKEY = "1234567891234567";
private static final String INITVECTOR = "1234567891234567";
//MD5签名Token
private static final String MD5TOKEN = "123456789";
//AES加密 "UTF-8"
public static String encrypt(String value,String charset) {
try {
IvParameterSpec iv = new IvParameterSpec(INITVECTOR.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(AESKEY.getBytes(charset), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.encodeBase64String(encrypted);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//AES解密 "UTF-8"
public static String decrypt(String encrypted,String charset) {
try {
IvParameterSpec iv = new IvParameterSpec(INITVECTOR.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(AESKEY.getBytes(charset), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original,charset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//MD5签名
public static String getMd5(String plainText) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
// 32位加密
return buf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,97 @@
package com.ruoyi.database.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.database.domain.dto.InvoiceRequest;
import com.ruoyi.database.domain.dto.InvoiceRequestData;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
/**
* 发票对接
*/
public class InvoiceUtil {
private static final String API_URL = "http://58.210.14.10:9300/ckl/einvoice/api/issue";
public static void main(String[] args) throws JsonProcessingException {
String appid = "0c091ef6-a30b-4022-9cb3-e105429c397c";
ObjectMapper objectMapper = new ObjectMapper();
InvoiceRequest invoiceRequest = new InvoiceRequest();
invoiceRequest.setBuyerName("个人");
invoiceRequest.setBuyerTaxNo("91110108MA00XXXXXX");
invoiceRequest.setPriceTaxMark(1);
invoiceRequest.setTotalAmount(new BigDecimal(100.00));
InvoiceRequest.InvoiceDetail invoiceDetail = new InvoiceRequest.InvoiceDetail();
ArrayList<InvoiceRequest.InvoiceDetail> invoiceDetails = new ArrayList<>();
invoiceDetail.setAmount(new BigDecimal(100.00));
invoiceDetail.setBillNo("3012512122CZWSUFLKU8I");
invoiceDetails.add(invoiceDetail);
invoiceRequest.setDetailList(invoiceDetails);
String compactJsonStr = objectMapper.writeValueAsString(invoiceRequest);
System.out.println( "JSON字符串:" + compactJsonStr);
String encrypt = EncryptUtils.encrypt(compactJsonStr, "UTF-8");
System.out.println( "加密字符串:" + encrypt);
long timestamp = System.currentTimeMillis() / 1000L;
String aaa ="appid=" + appid + "&data=" + encrypt + "&timestamp=" + timestamp + "&token=123456789";
System.out.println("拼接字符串:" + aaa);
String md5 = EncryptUtils.getMd5(aaa);
System.out.println("md5字符串:" + md5);
InvoiceRequestData invoiceRequestData = new InvoiceRequestData();
invoiceRequestData.setData(encrypt);
invoiceRequestData.setAppid(appid);
invoiceRequestData.setSign(md5);
invoiceRequestData.setTimestamp(timestamp);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 2. 创建 POST 请求
HttpPost httpPost = new HttpPost(API_URL);
// 3. 设置请求头
httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
// 转为 JSON 字符串
String jsonBody = objectMapper.writeValueAsString(invoiceRequestData);
StringEntity entity = new StringEntity(jsonBody, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 5. 执行请求
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
// 6. 处理响应
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity responseEntity = response.getEntity();
String responseBody = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
if (statusCode >= 200 && statusCode < 300) {
System.out.println("接口调用成功!");
System.out.println("响应状态码:" + statusCode);
System.out.println("响应体:" + responseBody);
} else {
System.out.println("接口调用失败,状态码:" + statusCode);
System.out.println("错误响应体:" + responseBody);
}
}
} catch (Exception e) {
System.err.println("接口调用异常:" + e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.database.util;
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class MoneyFormatUtil {
private static final DecimalFormat NORMAL_FORMAT = new DecimalFormat("#.##");
/**
* 格式化金额为中文显示
*/
public static String formatMoney(BigDecimal amount) {
if (amount == null) {
return "0元";
}
// 去掉末尾多余的0
String num = NORMAL_FORMAT.format(amount);
return num + "";
}
}