b2b2c商城源码_b2b2c商城系统-会员预存款架构及源码分享

业务需求

  • 可以为预存款充值,在支付订单时使用预存款支付功能
  • 当预存款余额>商品订单总金额时,完全抵扣商品订单金额;
  • 当预存款余额

架构

一、 充值

f5075d63039a6a4a1aa4a31b95063da9.png

二、 数据结构

1、会员钱包表(es_member_wallet)

2、 后期可能会将会员积分等关于消费抵扣相关信息放入此表中

724640c66844be718fbb023c5142dfb1.png

3、充值记录表(es_deposite_recharge)

5cccaafb548cef01b1eb74487ce1e38b.png

4.预存款日志表(es_deposite_log)

9f7fd4f724b6c2b34c5ee964749e18f8.png

三、充值模型图

15579c03eb8accd4233e84f2f8ad0ade.png

四、源码

说明:此处仅展示预存款充值相关代码,其他关联业务不做具体展示

预存款充值相关API

package com.enation.app.javashop.buyer.api.payment;import com.enation.app.javashop.core.payment.model.dto.PayParam;import com.enation.app.javashop.core.payment.service.OrderPayManager;import com.enation.app.javashop.core.trade.deposite.model.dos.RechargeDO;import com.enation.app.javashop.core.trade.deposite.service.RechargeManager;import com.enation.app.javashop.core.trade.order.model.enums.TradeTypeEnum;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiImplicitParams;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.validation.constraints.Max;import javax.validation.constraints.Min;import java.util.Map;/** * @description: 预存款充值 * @author: liuyulei * @create: 2019-12-30 19:53 * @version:1.0 * @since:7.1.4 **/@Api(description = "预存款充值相关API")@RestController@RequestMapping("/recharge")@Validatedpublic class RechargePayBuyerController {    @Autowired    private RechargeManager rechargeManager;    @Autowired    private OrderPayManager orderPayManager;    @PostMapping    @ApiOperation(value    = "创建充值订单")    @ApiImplicitParams({            @ApiImplicitParam(name = "price", value = "充值金额", required = true, dataType = "double", paramType = "query")    })    public RechargeDO create(@Max(value = 10000,message = "充值金额输入有误,单次最多允许充值10000元") @Min(value = 1, message = "充值金额有误,单次最少充值金额为1元") Double price) {        return this.rechargeManager.recharge(price);    }    @PostMapping(value = "/{sn}")    @ApiOperation(value    = "支付充值订单")    @ApiImplicitParams({            @ApiImplicitParam(name = "sn", value = "充值订单编号", required = true, dataType = "String", paramType = "path")    })    public Map pay(@PathVariable(name = "sn") String sn,  @Validated PayParam payParam)    {        payParam.setSn(sn);        payParam.setTradeType(TradeTypeEnum.RECHARGE.name());        return orderPayManager.pay(payParam);    }}

充值相关业务

package com.enation.app.javashop.core.trade.deposite.service.impl;import com.enation.app.javashop.core.client.member.DepositeClient;import com.enation.app.javashop.core.member.model.dto.DepositeParamDTO;import com.enation.app.javashop.core.payment.model.dos.PaymentBillDO;import com.enation.app.javashop.core.payment.service.PaymentBillManager;import com.enation.app.javashop.core.statistics.util.DateUtil;import com.enation.app.javashop.core.trade.TradeErrorCode;import com.enation.app.javashop.core.trade.deposite.model.dos.RechargeDO;import com.enation.app.javashop.core.trade.deposite.service.RechargeManager;import com.enation.app.javashop.core.trade.order.model.enums.PayStatusEnum;import com.enation.app.javashop.core.trade.order.model.enums.TradeTypeEnum;import com.enation.app.javashop.framework.context.UserContext;import com.enation.app.javashop.framework.exception.ServiceException;import com.enation.app.javashop.framework.security.model.Buyer;import com.enation.app.javashop.framework.util.CurrencyUtil;import com.enation.app.javashop.framework.util.SqlSplicingUtil;import com.enation.app.javashop.framework.util.StringUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.enation.app.javashop.framework.database.DaoSupport;import com.enation.app.javashop.framework.database.Page;import java.util.ArrayList;import java.util.Date;import java.util.List;/** * 充值记录业务类 * @author liuyulei * @version v1.0 * @since v7.1.5 * 2019-12-30 16:38:45 */@Servicepublic class RechargeManagerImpl implements RechargeManager {   @Autowired   @Qualifier("tradeDaoSupport")   private    DaoSupport daoSupport;   @Autowired   private PaymentBillManager paymentBillManager;   @Autowired   private DepositeClient depositeClient;   @Override   @Transactional(value = "tradeTransactionManager",propagation = Propagation.REQUIRED,rollbackFor=Exception.class)   public RechargeDO recharge(Double money) {      Buyer buyer =  UserContext.getBuyer();      //本金额支付次数      int times = 0;      //账单编号格式: 年月日+ memberID掩码 + 价格掩码 +支付次数      //掩码均为5位数,不足前面补零      String snPrefix = createSn(buyer.getUid(), "D", money);      String sn = snPrefix + times;      RechargeDO rechargeDO = this.getModel(sn);      if(rechargeDO == null ){         //整合充值订单数据         rechargeDO = new RechargeDO(sn,buyer.getUid(),buyer.getUsername(),money);         //添加充值订单         createBill(rechargeDO);      }else{         //如果是已付款         if(!PayStatusEnum.PAY_NO.name().equals(rechargeDO.getPayStatus())){            // 获取到已支付次数            times = Integer.parseInt(sn.substring(19, sn.length()));            //循环生成sn            while (true) {               times++;               sn = snPrefix + times;               RechargeDO rechargeTemp = this.getModel(sn);               // 找到一个没有使用过的 就可以break了               if (rechargeTemp == null) {                  break;               }            }            //充值订单已经被支付,则表示当天再次支付            rechargeDO.setRechargeSn(sn);            rechargeDO.setPayStatus(PayStatusEnum.PAY_NO.name());            createBill(rechargeDO);         }         //如果没有被支付则不用创建充值订单,再次为此订单支付即可      }      return rechargeDO;   }   @Override   @Transactional(value = "tradeTransactionManager",propagation = Propagation.REQUIRED,rollbackFor=Exception.class)   public void paySuccess(String sn, Double price) {      RechargeDO rechargeDO = this.getModel(sn);      if(!rechargeDO.getRechargeMoney().equals(price)){         throw new ServiceException(TradeErrorCode.E454.code(), "付款金额和应付金额不一致");      }      this.daoSupport.execute("update es_deposite_recharge set pay_status = ? where recharge_sn = ? ",PayStatusEnum.PAY_YES.name(),sn);      //增加会员预存款 余额      depositeClient.increase(price,rechargeDO.getMemberId(),"会员充值,充值单号:" + rechargeDO.getRechargeSn());   }   @Override   @Transactional(value = "tradeTransactionManager",propagation = Propagation.REQUIRED,rollbackFor=Exception.class)   public void updatePaymentMethod(String subSn, String pluginId, String methodName) {      String sql = "update es_deposite_recharge set payment_plugin_id = ?,recharge_way = ?, pay_time = ?  where recharge_sn = ? ";      this.daoSupport.execute(sql,pluginId,methodName, DateUtil.getDateline(),subSn);   }   @Override   public Page list(DepositeParamDTO paramDTO){      StringBuffer sql = new StringBuffer("select * from es_deposite_recharge ");      List whereSql = new ArrayList<>();      List term = new ArrayList<>();      //根据会员名称查询      if(!StringUtil.isEmpty(paramDTO.getMemberName())){         whereSql.add(" member_name = ? ");         term.add(paramDTO.getMemberName());      }      //根据会员id查询      if(paramDTO.getMemberId() != null ){         whereSql.add(" member_id = ? ");         term.add(paramDTO.getMemberId());      }      //根据充值编号查询      if(!StringUtil.isEmpty(paramDTO.getSn()) ){         whereSql.add(" recharge_sn = ? ");         term.add(paramDTO.getSn());      }      //根据充值编号查询      if(!StringUtil.isEmpty(paramDTO.getSn()) ){         whereSql.add(" recharge_sn = ? ");         term.add(paramDTO.getSn());      }      //根据充值时间查询      if(paramDTO.getStartTime() != null){         whereSql.add(" recharge_time >= ? ");         term.add(paramDTO.getStartTime());      }      //根据充值时间查询      if(paramDTO.getStartTime() != null){         whereSql.add(" recharge_time <= ? ");         term.add(paramDTO.getEndTime());      }      whereSql.add(" pay_status = ? ");      term.add(PayStatusEnum.PAY_YES.name());      //拼接sql      sql.append(SqlSplicingUtil.sqlSplicing(whereSql));      sql.append("order by recharge_time desc");      Page  webPage = this.daoSupport.queryForPage(sql.toString(),paramDTO.getPageNo(), paramDTO.getPageSize() , RechargeDO.class,term.toArray() );            return webPage;   }   @Override   public Double getPrice(String sn) {      return this.daoSupport.queryForDouble("select recharge_money from es_deposite_recharge where recharge_sn = ? ",sn);   }      @Override   public RechargeDO getModel(String sn)  {      return this.daoSupport.queryForObject("select * from es_deposite_recharge where recharge_sn = ?  ",RechargeDO.class,sn);   }   private String mask(String str) {      String mask = "000000";      mask = mask + str;      mask = mask.substring(mask.length() - 5);      return mask;   }   private String createSn(Integer memberId,String prefix,Double price) {      String memberMask = mask("" + memberId);      String priceMask = mask("" + CurrencyUtil.mul(price,100).intValue());      String snPrefix = prefix + DateUtil.toString(new Date(), "yyyyMMdd") + memberMask + priceMask;      return snPrefix;   }   private void createBill(RechargeDO rechargeDO) {      daoSupport.insert(rechargeDO);      //创建充值 支付 账单数据      PaymentBillDO paymentBillDO = new PaymentBillDO();      paymentBillDO.setSubSn(rechargeDO.getRechargeSn());      paymentBillDO.setTradePrice(rechargeDO.getRechargeMoney());      paymentBillDO.setServiceType(TradeTypeEnum.RECHARGE.name());      paymentBillManager.add(paymentBillDO);   }}

消费

一、消费时序图

ecdee8a3df726f115e3ef48e8bec9666.png

二、消费数据结构

1.交易表(es_trade)

新增预存款抵扣金额字段,记录订单使用的预存款金额

5a4e41a928fedc674a7ef841d43af95b.png

2.订单表(es_order)

新增预存款抵扣金额字段,记录订单使用的预存款金额

feb3802e20caae220b66f939c143a831.png

3.源码

说明:此处仅展示预存款消费相关代码,其他关联业务不做具体展示

预存款支付相关API

@ApiOperation(value = "使用预存款支付")@ApiImplicitParams({        @ApiImplicitParam(name = "sn", value = "要支付的交易sn", required = true, dataType = "String", paramType = "query"),        @ApiImplicitParam(name = "trade_type", value = "交易类型", required = true, dataType = "String", paramType = "query", allowableValues = "TRADE,ORDER"),        @ApiImplicitParam(name = "password", value = "支付密码", required = true, dataType = "String", paramType = "query")})@GetMapping(value = "/{trade_type}/{sn}")public BalancePayVO payTrade(@PathVariable(name = "sn") String sn, @PathVariable(name = "trade_type") String tradeType,                             @NotEmpty(message = "密码不能为空") String password) {    Buyer buyer = UserContext.getBuyer();    return balanceManager.balancePay(sn,buyer.getUid(),tradeType.toUpperCase(),password);}@GetMapping(value = "/cashier")@ApiOperation(value    = "获取预存款相关,收银台使用")public MemberDepositeVO getDepositeVO()    {   Buyer buyer = UserContext.getBuyer();   return depositeManager.getDepositeVO(buyer.getUid());}————————————————版权声明:本文为CSDN博主「kingapex1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/kingapex1/article/details/105943918

预存款支付相关业务

package com.enation.app.javashop.core.trade.order.service.impl;import com.enation.app.javashop.core.client.member.DepositeClient;import com.enation.app.javashop.core.member.model.dos.MemberWalletDO;import com.enation.app.javashop.core.payment.service.PaymentServicePlugin;import com.enation.app.javashop.core.trade.order.model.vo.BalancePayVO;import com.enation.app.javashop.core.trade.order.service.BalanceManager;import com.enation.app.javashop.core.trade.order.service.TradeQueryManager;import com.enation.app.javashop.framework.util.CurrencyUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;/** * @description: 预存款抵扣业务类 * @author: liuyulei * @create: 2020-01-01 11:55 * @version:1.0 * @since:7.1.4 **/@Servicepublic class BalanceManagerImpl implements BalanceManager {    @Autowired    private TradeQueryManager tradeQueryManager;    @Autowired    private DepositeClient depositeClient;    @Autowired    private List paymentServicePlugin;    @Override    public BalancePayVO balancePay(String sn,Integer memberId, String tradeType, String password) {        //检测订单、交易是否属于当前登录会员        this.tradeQueryManager.checkIsOwner(sn,memberId);        //检测支付密码是否正确        this.depositeClient.checkPwd(memberId,password);        PaymentServicePlugin plugin = this.findServicePlugin(tradeType);        //获取订单待支付金额        Double needPay = plugin.getPrice(sn);        //获取会员预存款信息        MemberWalletDO walletDO = this.depositeClient.getModel(memberId);        //判断预存款余额与订单待支付金额        Double diffPrice = CurrencyUtil.sub(needPay,walletDO.getPreDeposite());        Double balance = 0D;        if(diffPrice >= 0 ){            //此时预存款不足,无法完全抵扣所有订单支付基恩            balance = walletDO.getPreDeposite();            needPay = diffPrice;        }else{            //此时订单支付金额为0            balance = needPay;            needPay = 0D;        }        BalancePayVO payVO = new BalancePayVO();        payVO.setSn(sn);        payVO.setBalance(balance);        payVO.setNeedPay(needPay);        //预存款支付,修改订单待支付金额        plugin.balancePay(payVO,memberId);        return payVO;    }    /**     * 在支付子业务插件中  找到对应业务插件     * @param tradeType     * @return     */    private PaymentServicePlugin findServicePlugin(String tradeType) {        for (PaymentServicePlugin plugin:paymentServicePlugin){            if (tradeType.equals(plugin.getServiceType())) {                return plugin;            }        }        return null;    }}

更多源码分享,请关注“易族智汇”公众号查看更多文章!!

易族智汇(javashop)原创文章

56a89efb6ec9c61b7f676b68759dfdc5.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值