diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml index 0911520..a1c5e24 100644 --- a/ruoyi-api/pom.xml +++ b/ruoyi-api/pom.xml @@ -36,6 +36,7 @@ 0.9.0 4.1.1 1.2.0.Final + 3.5.0 @@ -144,8 +145,6 @@ ${org.mapstruct.version} provided - - org.projectlombok lombok @@ -156,6 +155,19 @@ p6spy 3.8.1 + + com.github.binarywang + wx-java-pay-spring-boot-starter + 3.5.4.B + + + com.github.binarywang + wx-java-miniapp-spring-boot-starter + 3.5.5.B + + + + @@ -189,4 +201,6 @@ + + \ No newline at end of file diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreGoodsMapper.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreGoodsMapper.java index bcf946e..dbb5241 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreGoodsMapper.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreGoodsMapper.java @@ -30,4 +30,11 @@ public interface StoreGoodsMapper extends BaseMapper { @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 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); + } diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreMemberMapper.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreMemberMapper.java index a0ed6d2..f3c9f87 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreMemberMapper.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreMemberMapper.java @@ -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 { - + @Update("update store_member set user_money=user_money-#{money} where id=#{userId}") + int decUserMony(@Param("userId") int userId,@Param("money") double money); } diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreSpecGoodsPriceMapper.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreSpecGoodsPriceMapper.java index 392094c..6578b9e 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreSpecGoodsPriceMapper.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/dao/StoreSpecGoodsPriceMapper.java @@ -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") List goodsSpec(List 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); + } diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/model/StorePointsMoneyLog.java b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/model/StorePointsMoneyLog.java index 2993e8c..052f3bf 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/model/StorePointsMoneyLog.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/common/persistence/model/StorePointsMoneyLog.java @@ -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 { * 添加时间 */ @TableField("create_time") + //@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8") private Integer createTime; diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/controller/PayController.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/controller/PayController.java new file mode 100644 index 0000000..3aefd3c --- /dev/null +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/controller/PayController.java @@ -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 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(""); + + } + + +} diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/IOrderService.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/IOrderService.java index a454430..fd9d6ad 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/IOrderService.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/IOrderService.java @@ -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 { public Map countInfo(int userId); + public StoreOrder orderInfo(String orderId,int userId); + + public void payYue(StoreOrder order); + } diff --git a/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/impl/OrderServiceImpl.java b/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/impl/OrderServiceImpl.java index beb1579..4159b23 100644 --- a/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/impl/OrderServiceImpl.java +++ b/ruoyi-api/src/main/java/com/ruoyi/app/modular/shop/service/impl/OrderServiceImpl.java @@ -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 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 map.put("returnCount",returnCount); return map; } + + @Override + public StoreOrder orderInfo(String orderId, int userId) { + QueryWrapper 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 wrapperGoods = new QueryWrapper<>(); + wrapperGoods.eq("order_id",order.getOrderId()); + List 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); + + } } diff --git a/ruoyi-api/src/main/resources/application.yml b/ruoyi-api/src/main/resources/application.yml index 48bdb80..cecd8d9 100644 --- a/ruoyi-api/src/main/resources/application.yml +++ b/ruoyi-api/src/main/resources/application.yml @@ -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 \ No newline at end of file + com.ruoyi.app.modular: debug + +wx: + pay: + appId: + mchId: + mchKey: + subAppId: + subMchId: + keyPath: \ No newline at end of file