增加余额支付功能

This commit is contained in:
hupeng committed 2019-09-27 18:56:43 +08:00
1 parent 95383a5757
commit 1d4d2b2573
9 files changed
+245 -6

No files matched your search

+16 -2
View File
@@ -36,6 +36,7 @@
<jwt.version>0.9.0</jwt.version> <jwt.version>0.9.0</jwt.version>
<hutool.version>4.1.1</hutool.version> <hutool.version>4.1.1</hutool.version>
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version> <org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
<version>3.5.0</version>
</properties> </properties>
<dependencies> <dependencies>
@@ -144,8 +145,6 @@
<version>${org.mapstruct.version}</version> <version>${org.mapstruct.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
@@ -156,6 +155,19 @@
<artifactId>p6spy</artifactId> <artifactId>p6spy</artifactId>
<version>3.8.1</version> <version>3.8.1</version>
</dependency> </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> </dependencies>
<build> <build>
@@ -189,4 +201,6 @@
</project> </project>
@@ -30,4 +30,11 @@ public interface StoreGoodsMapper extends BaseMapper<StoreGoods> {
@Select("select g.* from store_goods_collect c left join store_goods g " + @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}") "on c.goods_id=g.goods_id where c.user_id=#{userId}")
List<StoreGoods> collectGoods(Page page, @Param("userId") int 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.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.app.common.persistence.model.StoreMember; import com.ruoyi.app.common.persistence.model.StoreMember;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
@Mapper @Mapper
public interface StoreMemberMapper extends BaseMapper<StoreMember> { 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);
} }
@@ -3,7 +3,9 @@ package com.ruoyi.app.common.persistence.dao;
import com.ruoyi.app.common.persistence.model.StoreSpecGoodsPrice; import com.ruoyi.app.common.persistence.model.StoreSpecGoodsPrice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.app.modular.shop.service.dto.ItemDTO; 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.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -29,4 +31,9 @@ public interface StoreSpecGoodsPriceMapper extends BaseMapper<StoreSpecGoodsPric
"ORDER BY b.id </script>") "ORDER BY b.id </script>")
List<ItemDTO> goodsSpec(List<String> keys); 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);
} }
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serializable; import java.io.Serializable;
/** /**
@@ -58,6 +60,7 @@ public class StorePointsMoneyLog extends Model<StorePointsMoneyLog> {
* 添加时间 * 添加时间
*/ */
@TableField("create_time") @TableField("create_time")
//@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
private Integer createTime; 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.dto.OrderDTO;
import com.ruoyi.app.modular.shop.service.vo.OrderVo; import com.ruoyi.app.modular.shop.service.vo.OrderVo;
import com.ruoyi.app.modular.shop.service.vo.PageVO; import com.ruoyi.app.modular.shop.service.vo.PageVO;
import org.springframework.core.annotation.Order;
import java.util.List; import java.util.List;
@@ -35,4 +36,8 @@ public interface IOrderService extends IService<StoreOrder> {
public Map<String,Integer> countInfo(int userId); 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.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; 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.dao.*;
import com.ruoyi.app.common.persistence.model.*; import com.ruoyi.app.common.persistence.model.*;
import com.ruoyi.app.common.utils.OrderUtil; 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.IOrderService;
import com.ruoyi.app.modular.shop.service.dto.CouponDTO; import com.ruoyi.app.modular.shop.service.dto.CouponDTO;
import com.ruoyi.app.modular.shop.service.dto.GoodsDTO; 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 com.ruoyi.app.modular.shop.service.vo.PageVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -51,6 +54,9 @@ public class OrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder>
private final OrderMapper orderMapper; private final OrderMapper orderMapper;
private final StorePointsMoneyLogMapper storePointsMoneyLogMapper; private final StorePointsMoneyLogMapper storePointsMoneyLogMapper;
private final OrderGoodsMapper orderGoodsMapper; 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); map.put("returnCount",returnCount);
return map; 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);
}
} }
+12 -3
View File
@@ -58,9 +58,9 @@ spring:
#driver-class-name: com.mysql.jdbc.Driver #driver-class-name: com.mysql.jdbc.Driver
driver-class-name: com.p6spy.engine.spy.P6SpyDriver driver-class-name: com.p6spy.engine.spy.P6SpyDriver
#driverClassName: com.mysql.cj.jdbc.Driver #driverClassName: com.mysql.cj.jdbc.Driver
username: root username: supply
password: root password: supply#@147
url: jdbc:p6spy:mysql://localhost:3306/ruoyi?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=UTC 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 #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的配置信息 type: com.alibaba.druid.pool.DruidDataSource #这里是配置druid连接池,以下都是druid的配置信息
druid: druid:
@@ -140,3 +140,12 @@ spring:
logging: logging:
level: level:
com.ruoyi.app.modular: debug com.ruoyi.app.modular: debug
wx:
pay:
appId:
mchId:
mchKey:
subAppId:
subMchId:
keyPath: