package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.enumerates.OrderStatusEnum; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion; import cc.mrbird.febs.mall.dto.*; import cc.mrbird.febs.mall.entity.*; import cc.mrbird.febs.mall.mapper.*; import cc.mrbird.febs.mall.service.IApiMallAppService; import cc.mrbird.febs.mall.vo.*; import cc.mrbird.febs.pay.service.IXcxCodePayService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.RSA; import cn.hutool.db.sql.Order; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @Slf4j @Service @RequiredArgsConstructor public class ApiMallAppServiceImpl extends ServiceImpl implements IApiMallAppService { private final RedisUtils redisUtils; private final MallMemberMapper mallMemberMapper; private final MallGoodsCategoryMapper mallGoodsCategoryMapper; private final MallGoodsMapper mallGoodsMapper; private final MallOrderInfoMapper mallOrderInfoMapper; private final MallOrderItemMapper mallOrderItemMapper; private final MallMemberWalletMapper mallMemberWalletMapper; private final IXcxCodePayService xcxCodePayService; public static void main(String[] args) { System.out.println(SecureUtil.md5("a123456")); } @Override public FebsResponse appToLogin(LoginDto loginDto) { String md5Pwd = SecureUtil.md5(loginDto.getPassword()); MallMember mallMember = mallMemberMapper.selectInfoByAccountAndPwd(loginDto.getAccount(), md5Pwd); if (mallMember == null) { throw new FebsException("用户不存在或账号密码错误"); } String redisKey = AppContants.SY_APP_LOGIN_PREFIX + mallMember.getId(); String existToken = redisUtils.getString(redisKey); if (StrUtil.isNotBlank(existToken)) { Object o = redisUtils.get(existToken); if (ObjectUtil.isNotEmpty(o)) { redisUtils.del(existToken); } } String token = IdUtil.simpleUUID(); redisUtils.set(token, JSONObject.toJSONString(mallMember)); redisUtils.set(redisKey, token); Map authInfo = new HashMap<>(); authInfo.put("token", token); authInfo.put("rasToken", generateAsaToken(token)); return new FebsResponse().success().data(authInfo); } @Override public FebsResponse appMemberInfo(ApiMallAppMemberInfoDto apiMallAppMemberInfoDto) { // Long memberId = LoginUserUtil.getLoginUser().getId(); List mallMembers = this.baseMapper.selectMemberInfoLikePhone(apiMallAppMemberInfoDto.getPhone()); return new FebsResponse().success().data(mallMembers); } @Override public FebsResponse findAllCategoryList() { List mallGoodsCategoryVos = mallGoodsCategoryMapper.selectAllCategoryListByIsApp(AppContants.IS_APP_CATEGORY); return new FebsResponse().success().data(mallGoodsCategoryVos); } @Override public FebsResponse findMallGoodsListNoPage(ApiMallGoodsQueryDto queryDto) { List mallGoodsListVos = mallGoodsMapper.selectMallGoodsListQueryNoPageIsApp(queryDto); return new FebsResponse().success().data(mallGoodsListVos); } @Override @Transactional public FebsResponse createAppOrder(ApiAddOrderDto addOrderDto) { if(ObjectUtil.isNotEmpty(addOrderDto.getOrderId())){ MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(addOrderDto.getOrderId()); if(ObjectUtil.isNotEmpty(mallOrderInfo)){ mallOrderInfo.setStatus(OrderStatusEnum.CANCEL.getValue()); mallOrderInfoMapper.updateById(mallOrderInfo); } } MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(addOrderDto.getMemberId()); if (ObjectUtil.isEmpty(mallMemberWallet)) { throw new FebsException("用户钱包不存在。"); } if (CollUtil.isEmpty(addOrderDto.getItems())) { throw new FebsException("商品明细不能为空。"); } Integer type = addOrderDto.getType(); String orderNo = MallUtils.getOrderNum(); MallOrderInfo orderInfo = new MallOrderInfo(); orderInfo.setOrderNo(orderNo); orderInfo.setIsApp(AppContants.IS_APP_ORDER); orderInfo.setOrderTime(new Date()); orderInfo.setMemberId(addOrderDto.getMemberId()); orderInfo.setPayResult(2); //会员结算 orderInfo.setStatus(OrderStatusEnum.WAIT_PAY.getValue()); mallOrderInfoMapper.insert(orderInfo); BigDecimal total = BigDecimal.ZERO;//总支付金额 //订单子表记录 for (ApiAddOrderItemDto item : addOrderDto.getItems()) { MallOrderItem orderItem = new MallOrderItem(); MallGoods mallGoods = mallGoodsMapper.selectById(item.getId()); //现价 BigDecimal presentPrice = new BigDecimal(mallGoods.getPresentPrice()); BigDecimal amount = presentPrice.multiply(item.getCnt()); orderItem.setAmount(amount); orderItem.setOrderId(orderInfo.getId()); orderItem.setPrice(presentPrice); orderItem.setAppCnt(item.getCnt()); orderItem.setGoodsId(mallGoods.getId()); orderItem.setGoodsName(mallGoods.getGoodsName()); orderItem.setSkuImage(mallGoods.getThumb()); orderItem.setState(1); total = total.add(amount); mallOrderItemMapper.insert(orderItem); } orderInfo.setAmount(total); orderInfo.setMemberId(mallMemberWallet.getMemberId()); //折扣费用 if(AppContants.INSURE_ORDER_MEMBER.equals(type)){ BigDecimal score = mallMemberWallet.getScore();//积分 BigDecimal balance = mallMemberWallet.getBalance();//余额 //这里将运费定义成折扣总金额 /** * 积分 + 余额 1:1来折扣支付金额 */ BigDecimal totalCarriage = BigDecimal.ZERO;//总折扣金额 BigDecimal memberAmount = score.add(balance);//用户积分加余额总数 if(memberAmount.compareTo(BigDecimal.ZERO) > 0){ //折扣金额 if(total.compareTo(memberAmount) >= 0){ totalCarriage = memberAmount; }else{ totalCarriage = total; } } orderInfo.setCarriage(totalCarriage); } mallOrderInfoMapper.updateById(orderInfo); Map orderInfoMap = new HashMap<>(); orderInfoMap.put("orderId", orderInfo.getId()); orderInfoMap.put("totalAmount", orderInfo.getAmount()); orderInfoMap.put("totalCarriage", orderInfo.getCarriage()); return new FebsResponse().success().data(orderInfoMap); } @Override public FebsResponse registAppOrder(ApiRegistAppOrderDto addOrderDto) { String orderNo = MallUtils.getOrderNum(); MallOrderInfo orderInfo = new MallOrderInfo(); orderInfo.setOrderNo(orderNo); orderInfo.setIsApp(AppContants.IS_APP_ORDER); orderInfo.setOrderTime(new Date()); orderInfo.setStatus(OrderStatusEnum.WAIT_PAY.getValue()); orderInfo.setPayResult(2); if (CollUtil.isEmpty(addOrderDto.getItems())) { throw new FebsException("商品明细不能为空。"); } mallOrderInfoMapper.insert(orderInfo); BigDecimal total = BigDecimal.ZERO;//总支付金额 //订单子表记录 for (ApiAddOrderItemDto item : addOrderDto.getItems()) { MallOrderItem orderItem = new MallOrderItem(); MallGoods mallGoods = mallGoodsMapper.selectById(item.getId()); //现价 BigDecimal presentPrice = new BigDecimal(mallGoods.getPresentPrice()); BigDecimal amount = presentPrice.multiply(item.getCnt()); orderItem.setAmount(amount); orderItem.setOrderId(orderInfo.getId()); orderItem.setPrice(presentPrice); orderItem.setAppCnt(item.getCnt()); orderItem.setGoodsId(mallGoods.getId()); orderItem.setGoodsName(mallGoods.getGoodsName()); orderItem.setSkuImage(mallGoods.getThumb()); orderItem.setState(1); mallOrderItemMapper.insert(orderItem); total = total.add(amount); } orderInfo.setAmount(total); mallOrderInfoMapper.updateById(orderInfo); Integer cnt = 0; List mallOrderInfos = mallOrderInfoMapper.selectOrderInfoByStatusIsApp(OrderStatusEnum.WAIT_PAY.getValue()); if(ObjectUtil.isNotEmpty(mallOrderInfos)){ cnt = mallOrderInfos.size(); } return new FebsResponse().success().data(cnt).message("操作成功"); } @Override public FebsResponse normalInsure(ApiNormalInsureDto addOrderDto) { if(ObjectUtil.isNotEmpty(addOrderDto.getOrderId())){ MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(addOrderDto.getOrderId()); if(ObjectUtil.isNotEmpty(mallOrderInfo)){ mallOrderInfo.setStatus(OrderStatusEnum.CANCEL.getValue()); mallOrderInfoMapper.updateById(mallOrderInfo); } } String orderNo = MallUtils.getOrderNum(); MallOrderInfo orderInfo = new MallOrderInfo(); orderInfo.setOrderNo(orderNo); orderInfo.setIsApp(AppContants.IS_APP_ORDER); orderInfo.setOrderTime(new Date()); orderInfo.setStatus(OrderStatusEnum.WAIT_PAY.getValue()); orderInfo.setPayResult(2); if (CollUtil.isEmpty(addOrderDto.getItems())) { throw new FebsException("商品明细不能为空。"); } mallOrderInfoMapper.insert(orderInfo); BigDecimal total = BigDecimal.ZERO;//总支付金额 //订单子表记录 for (ApiAddOrderItemDto item : addOrderDto.getItems()) { MallOrderItem orderItem = new MallOrderItem(); MallGoods mallGoods = mallGoodsMapper.selectById(item.getId()); //现价 BigDecimal presentPrice = new BigDecimal(mallGoods.getPresentPrice()); BigDecimal amount = presentPrice.multiply(item.getCnt()); orderItem.setAmount(amount); orderItem.setOrderId(orderInfo.getId()); orderItem.setPrice(presentPrice); orderItem.setAppCnt(item.getCnt()); orderItem.setGoodsId(mallGoods.getId()); orderItem.setGoodsName(mallGoods.getGoodsName()); orderItem.setSkuImage(mallGoods.getThumb()); orderItem.setState(1); total = total.add(amount); mallOrderItemMapper.insert(orderItem); } orderInfo.setCarriage(BigDecimal.ZERO);//折扣费用 orderInfo.setAmount(total); mallOrderInfoMapper.updateById(orderInfo); Map orderInfoMap = new HashMap<>(); orderInfoMap.put("orderId", orderInfo.getId()); orderInfoMap.put("totalAmount", orderInfo.getAmount()); orderInfoMap.put("totalCarriage", orderInfo.getCarriage()); return new FebsResponse().success().data(orderInfoMap); } @Override public FebsResponse getOrderList(ApiGetOrderListDto orderListDto) { IPage page = new Page<>(orderListDto.getPageNum(), orderListDto.getPageSize()); orderListDto.setStatus(OrderStatusEnum.WAIT_PAY.getValue()); IPage apiGetOrderListVos = mallOrderInfoMapper.getAppOrderListInPage(page, orderListDto); if (CollUtil.isNotEmpty(apiGetOrderListVos.getRecords())) { apiGetOrderListVos.getRecords().forEach(item -> { item.setItems(mallOrderItemMapper.getAppOrderItemByOrderId(item.getId())); }); } return new FebsResponse().success().data(apiGetOrderListVos); } @Override public FebsResponse getOrder(ApiGetOrderDto apiGetOrderDto) { Long orderId = apiGetOrderDto.getOrderId(); ApiGetOrderListVo apiGetOrderListVo = mallOrderInfoMapper.getAppOrderByOrderId(orderId); if(ObjectUtil.isNotEmpty(apiGetOrderListVo)){ apiGetOrderListVo.setItems(mallOrderItemMapper.getAppOrderItemByOrderId(apiGetOrderListVo.getId())); } // mallOrderInfoMapper.deleteById(orderId); // QueryWrapper mallOrderItemQuery = new QueryWrapper<>(); // mallOrderItemQuery.eq("order_id",orderId); // mallOrderItemMapper.delete(mallOrderItemQuery); return new FebsResponse().success().data(apiGetOrderListVo); } @Override public FebsResponse getOrderCancel(ApiGetOrderDto apiGetOrderDto) { MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(apiGetOrderDto.getOrderId()); mallOrderInfo.setStatus(OrderStatusEnum.CANCEL.getValue()); mallOrderInfoMapper.updateById(mallOrderInfo); return new FebsResponse().success().message("订单已取消"); } @Override @Transactional public FebsResponse wxCodePay(ApiWxCodePayDto wxCodePayDto) { Long orderId = wxCodePayDto.getOrderId(); MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId); if(OrderStatusEnum.FINISH.getValue() == (mallOrderInfo.getStatus())){ throw new FebsException("已支付"); } BigDecimal amount = mallOrderInfo.getAmount(); BigDecimal carriage = mallOrderInfo.getCarriage(); //减少用户积分和余额 if(ObjectUtil.isNotEmpty(mallOrderInfo.getMemberId())){ BigDecimal avaAmount = carriage;//剩余需要折扣的金额 if(avaAmount.compareTo(BigDecimal.ZERO) > 0){ MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(mallOrderInfo.getMemberId()); BigDecimal score = mallMemberWallet.getScore(); BigDecimal balance = mallMemberWallet.getBalance(); BigDecimal memberAmount = score.add(balance); if(avaAmount.compareTo(memberAmount) >= 0){ //清零用户的积分和余额 mallMemberWallet.setBalance(BigDecimal.ZERO); mallMemberWallet.setScore(BigDecimal.ZERO); mallMemberWalletMapper.updateBalanceScoreWithId(mallMemberWallet); }else{ /** * 先扣积分,再扣余额 */ if(avaAmount.compareTo(score) >= 0){ mallMemberWallet.setScore(BigDecimal.ZERO); avaAmount = avaAmount.subtract(score); }else{ mallMemberWallet.setScore(score.subtract(avaAmount)); avaAmount = BigDecimal.ZERO; } //积分不够 if(avaAmount.compareTo(BigDecimal.ZERO) > 0){ mallMemberWallet.setBalance(balance.subtract(avaAmount)); }else{ mallMemberWallet.setBalance(balance); } mallMemberWalletMapper.updateBalanceScoreWithId(mallMemberWallet); } } } String wxPayCode = wxCodePayDto.getWxPayCode(); mallOrderInfo.setTakeCode(wxPayCode); List appOrderItemByOrderId = mallOrderItemMapper.getAppOrderItemByOrderId(orderId); if(CollUtil.isEmpty(appOrderItemByOrderId)){ mallOrderInfo.setName("商品"); }else{ mallOrderInfo.setName(appOrderItemByOrderId.get(0).getGoodsName()); } mallOrderInfo.setStatus(OrderStatusEnum.FINISH.getValue()); mallOrderInfoMapper.updateById(mallOrderInfo); // 发起付款码支付请求 String payResult = "支付成功"; if(amount.subtract(carriage).compareTo(BigDecimal.ZERO) > 0){ /** * auth_code 扫码支付付款码 微信付款码规则:18位纯数字,前缀以10、11、12、13、14、15开头 */ String regex = "^(10|11|12|13|14|15)\\d{16}$"; boolean flag = wxPayCode.matches(regex); if(!flag){ throw new FebsException("请打开微信付款码!"); } payResult = xcxCodePayService.pay(mallOrderInfo); } return new FebsResponse().success().message(payResult); } @Override public FebsResponse cancelOrder(Long id) { MallOrderInfo orderInfo = mallOrderInfoMapper.selectById(id); if (orderInfo == null || AppContants.DEL_FLAG_Y == orderInfo.getDelFlag()) { throw new FebsException("订单不存在"); } if (OrderStatusEnum.WAIT_PAY.getValue() != orderInfo.getStatus()) { throw new FebsException("订单不是待付款, 无法取消"); } orderInfo.setStatus(OrderStatusEnum.CANCEL.getValue()); orderInfo.setCancelType(MallOrderInfo.CANCEL_BY_SELF); mallOrderInfoMapper.updateById(orderInfo); return new FebsResponse().success().message("取消成功"); } public String generateAsaToken(String token) { RSA rsa = new RSA(null, AppContants.PUBLIC_KEY); return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey); } }