增加余额支付功能
This commit is contained in:
1 parent
95383a5757
commit
1d4d2b2573
9 files changed
+246
-7
No files matched your search
+16
-2
@@ -36,6 +36,7 @@
|
||||
<jwt.version>0.9.0</jwt.version>
|
||||
<hutool.version>4.1.1</hutool.version>
|
||||
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
|
||||
<version>3.5.0</version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -144,8 +145,6 @@
|
||||
<version>${org.mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
@@ -156,6 +155,19 @@
|
||||
<artifactId>p6spy</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-pay-spring-boot-starter</artifactId>
|
||||
<version>3.5.4.B</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
|
||||
<version>3.5.5.B</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -189,4 +201,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
@@ -30,4 +30,11 @@ public interface StoreGoodsMapper extends BaseMapper<StoreGoods> {
|
||||
@Select("select g.* from store_goods_collect c left join store_goods g " +
|
||||
"on c.goods_id=g.goods_id where c.user_id=#{userId}")
|
||||
List<StoreGoods> collectGoods(Page page, @Param("userId") int userId);
|
||||
|
||||
|
||||
@Update("update store_goods set sales_sum=sales_sum+#{goodsNum} " +
|
||||
"where goods_id=#{goodsId}")
|
||||
int incSaleNum(@Param("goodsId") int goodsId,
|
||||
@Param("goodsNum") int goodsNum);
|
||||
|
||||
}
|
||||
@@ -3,9 +3,12 @@ package com.ruoyi.app.common.persistence.dao;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.app.common.persistence.model.StoreMember;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface StoreMemberMapper extends BaseMapper<StoreMember> {
|
||||
|
||||
@Update("update store_member set user_money=user_money-#{money} where id=#{userId}")
|
||||
int decUserMony(@Param("userId") int userId,@Param("money") double money);
|
||||
}
|
||||
+7
@@ -3,7 +3,9 @@ package com.ruoyi.app.common.persistence.dao;
|
||||
import com.ruoyi.app.common.persistence.model.StoreSpecGoodsPrice;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.app.modular.shop.service.dto.ItemDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -29,4 +31,9 @@ public interface StoreSpecGoodsPriceMapper extends BaseMapper<StoreSpecGoodsPric
|
||||
"ORDER BY b.id </script>")
|
||||
List<ItemDTO> goodsSpec(List<String> keys);
|
||||
|
||||
@Update("update store_spec_goods_price set store_count=store_count-#{goodsNum} " +
|
||||
"where goods_id=#{goodsId} and `key`=#{specKey}")
|
||||
int decCount(@Param("goodsId") int goodsId,
|
||||
@Param("specKey") String specKey,@Param("goodsNum") int goodsNum);
|
||||
|
||||
}
|
||||
+3
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
@@ -58,6 +60,7 @@ public class StorePointsMoneyLog extends Model<StorePointsMoneyLog> {
|
||||
* 添加时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
//@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
|
||||
private Integer createTime;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.ruoyi.app.modular.shop.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.itmuch.lightsecurity.jwt.UserOperator;
|
||||
import com.ruoyi.app.common.R;
|
||||
import com.ruoyi.app.common.persistence.model.StoreOrder;
|
||||
import com.ruoyi.app.modular.shop.service.dto.OrderDTO;
|
||||
import com.ruoyi.app.modular.shop.service.impl.OrderServiceImpl;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName PayController
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2019/9/26
|
||||
**/
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
@Api(value = "支付模块", tags = "支付模块", description = "支付模块")
|
||||
public class PayController {
|
||||
private final UserOperator userOperator;
|
||||
private final OrderServiceImpl orderService;
|
||||
private final WxPayService wxPayService;
|
||||
|
||||
@PostMapping(value = "/shop/pay-confirm-money")
|
||||
@ApiOperation(value = "支付前检测获取的价格",notes = "支付前检测获取的价格")
|
||||
public R confirmPayMoney(@Validated @RequestBody String jsonStr){
|
||||
JSONObject jsonObject = JSON.parseObject(jsonStr);
|
||||
String orderNo = jsonObject.get("order_no").toString();
|
||||
if(StrUtil.isEmpty(orderNo)){
|
||||
return R.error(4000,"订单号缺失");
|
||||
}
|
||||
int userId = userOperator.getUser().getId();
|
||||
StoreOrder storeOrder = orderService.orderInfo(orderNo,userId);
|
||||
if(ObjectUtil.isNull(storeOrder)){
|
||||
return R.error(4000,"订单不存在");
|
||||
}
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("order_amount",storeOrder.getOrderAmount());
|
||||
|
||||
return R.success(map);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/shop/pay-do-pay")
|
||||
@ApiOperation(value = "开始支付",notes = "开始支付")
|
||||
public R doPay(@Validated @RequestBody String jsonStr,
|
||||
WxPayUnifiedOrderRequest orderRequest){
|
||||
JSONObject jsonObject = JSON.parseObject(jsonStr);
|
||||
String orderNo = jsonObject.get("order_no").toString();
|
||||
//1-余额支付 2-微信支付
|
||||
int payType = 1;
|
||||
|
||||
if(StrUtil.isEmpty(orderNo)){
|
||||
return R.error(4000,"订单号缺失");
|
||||
}
|
||||
if(ObjectUtil.isNotNull(jsonObject.get("pay_type"))){
|
||||
payType = Integer.valueOf(jsonObject.get("pay_type").toString());
|
||||
}
|
||||
|
||||
int userId = userOperator.getUser().getId();
|
||||
StoreOrder storeOrder = orderService.orderInfo(orderNo,userId);
|
||||
if(ObjectUtil.isNull(storeOrder)){
|
||||
return R.error(4000,"订单不存在");
|
||||
}
|
||||
|
||||
|
||||
if(payType == 1){
|
||||
orderService.payYue(storeOrder);
|
||||
return R.success("余额支付成功");
|
||||
}else{
|
||||
//todo 微信支付
|
||||
try {
|
||||
//WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
|
||||
orderRequest.setBody("主题");
|
||||
orderRequest.setOutTradeNo("订单号");
|
||||
orderRequest.setTotalFee(1);//元转成分
|
||||
orderRequest.setOpenid("openId");
|
||||
orderRequest.setSpbillCreateIp("userIp");
|
||||
//orderRequest.setTimeStart("yyyyMMddHHmmss");
|
||||
// orderRequest.setTimeExpire("yyyyMMddHHmmss");
|
||||
|
||||
return R.success(wxPayService.createOrder(orderRequest));
|
||||
} catch (Exception e) {
|
||||
log.error("微信支付失败!订单号:{},原因:{}", orderNo, e.getMessage());
|
||||
e.printStackTrace();
|
||||
return R.error(4000,"支付失败,请稍后重试!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// return R.success("");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.ruoyi.app.common.persistence.model.StorePointsMoneyLog;
|
||||
import com.ruoyi.app.modular.shop.service.dto.OrderDTO;
|
||||
import com.ruoyi.app.modular.shop.service.vo.OrderVo;
|
||||
import com.ruoyi.app.modular.shop.service.vo.PageVO;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
@@ -35,4 +36,8 @@ public interface IOrderService extends IService<StoreOrder> {
|
||||
|
||||
public Map<String,Integer> countInfo(int userId);
|
||||
|
||||
public StoreOrder orderInfo(String orderId,int userId);
|
||||
|
||||
public void payYue(StoreOrder order);
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ package com.ruoyi.app.modular.shop.service.impl;
|
||||
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -16,6 +17,7 @@ import com.itmuch.lightsecurity.exception.LightSecurityException;
|
||||
import com.ruoyi.app.common.persistence.dao.*;
|
||||
import com.ruoyi.app.common.persistence.model.*;
|
||||
import com.ruoyi.app.common.utils.OrderUtil;
|
||||
import com.ruoyi.app.modular.member.service.IMemberService;
|
||||
import com.ruoyi.app.modular.shop.service.IOrderService;
|
||||
import com.ruoyi.app.modular.shop.service.dto.CouponDTO;
|
||||
import com.ruoyi.app.modular.shop.service.dto.GoodsDTO;
|
||||
@@ -29,6 +31,7 @@ import com.ruoyi.app.modular.shop.service.vo.OrderVo;
|
||||
import com.ruoyi.app.modular.shop.service.vo.PageVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -51,6 +54,9 @@ public class OrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder>
|
||||
private final OrderMapper orderMapper;
|
||||
private final StorePointsMoneyLogMapper storePointsMoneyLogMapper;
|
||||
private final OrderGoodsMapper orderGoodsMapper;
|
||||
private final IMemberService memberService;
|
||||
private final StoreMemberMapper storeMemberMapper;
|
||||
private final StoreGoodsMapper storeGoodsMapper;
|
||||
|
||||
|
||||
/**
|
||||
@@ -466,4 +472,73 @@ public class OrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder>
|
||||
map.put("returnCount",returnCount);
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoreOrder orderInfo(String orderId, int userId) {
|
||||
QueryWrapper<StoreOrder> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("deleted",0).eq("user_id",userId).eq("pay_status",0).and(
|
||||
i->i.eq("order_id",orderId).or().eq("order_sn",orderId));
|
||||
StoreOrder storeOrder = baseMapper.selectOne(wrapper);
|
||||
return storeOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额支付
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void payYue(StoreOrder order) {
|
||||
//判断库存
|
||||
QueryWrapper<StoreOrderGoods> wrapperGoods = new QueryWrapper<>();
|
||||
wrapperGoods.eq("order_id",order.getOrderId());
|
||||
List<StoreOrderGoods> orderGoodsList = storeOrderGoodsMapper
|
||||
.selectList(wrapperGoods);
|
||||
for (StoreOrderGoods storeGood : orderGoodsList) {
|
||||
int storeCount = checkStore(storeGood.getGoodsId(),storeGood.getSpecKey());
|
||||
if(storeCount < storeGood.getGoodsNum()){
|
||||
throw new LightSecurityException("库存不足");
|
||||
}
|
||||
|
||||
//更新库存
|
||||
storeSpecGoodsPriceMapper.decCount(storeGood.getGoodsId(),
|
||||
storeGood.getSpecKey(),storeGood.getGoodsNum());
|
||||
//增加商品销量
|
||||
storeGoodsMapper.incSaleNum(storeGood.getGoodsId()
|
||||
,storeGood.getGoodsNum());
|
||||
|
||||
}
|
||||
|
||||
//余额判断
|
||||
StoreMember member = memberService.getById(order.getUserId());
|
||||
if(order.getOrderAmount().doubleValue() > member.getUserMoney().doubleValue()){
|
||||
throw new LightSecurityException("余额不足");
|
||||
}
|
||||
|
||||
//更新订单状态
|
||||
StoreOrder storeOrder = new StoreOrder();
|
||||
storeOrder.setOrderId(order.getOrderId());
|
||||
storeOrder.setPayStatus(1);
|
||||
storeOrder.setPayMethod(2);
|
||||
storeOrder.setUserMoney(order.getOrderAmount());
|
||||
storeOrder.setPayTime(OrderUtil.getSecondTimestampTwo());
|
||||
updateById(storeOrder);
|
||||
|
||||
//减去余额
|
||||
int result = storeMemberMapper.decUserMony(order.getUserId(),
|
||||
order.getOrderAmount().doubleValue());
|
||||
if(result <= 0){
|
||||
throw new LightSecurityException("减余额失败");
|
||||
}
|
||||
|
||||
//增加流水
|
||||
StorePointsMoneyLog storePointsMoneyLog = new StorePointsMoneyLog();
|
||||
storePointsMoneyLog.setUserId(order.getUserId());
|
||||
storePointsMoneyLog.setTitle("购买商品");
|
||||
storePointsMoneyLog.setMoneyNumber(order.getOrderAmount());
|
||||
storePointsMoneyLog.setType(2);
|
||||
storePointsMoneyLog.setCreateTime(OrderUtil.getSecondTimestampTwo());
|
||||
|
||||
storePointsMoneyLogMapper.insert(storePointsMoneyLog);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -58,9 +58,9 @@ spring:
|
||||
#driver-class-name: com.mysql.jdbc.Driver
|
||||
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
|
||||
#driverClassName: com.mysql.cj.jdbc.Driver
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:p6spy:mysql://localhost:3306/ruoyi?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=UTC
|
||||
username: supply
|
||||
password: supply#@147
|
||||
url: jdbc:p6spy:mysql://localhost:3306/supply?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=UTC
|
||||
#url: jdbc:mysql://localhost:3306/ruoyi?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=UTC
|
||||
type: com.alibaba.druid.pool.DruidDataSource #这里是配置druid连接池,以下都是druid的配置信息
|
||||
druid:
|
||||
@@ -139,4 +139,13 @@ spring:
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.ruoyi.app.modular: debug
|
||||
com.ruoyi.app.modular: debug
|
||||
|
||||
wx:
|
||||
pay:
|
||||
appId:
|
||||
mchId:
|
||||
mchKey:
|
||||
subAppId:
|
||||
subMchId:
|
||||
keyPath:
|
||||
Reference in new issue
Block a user