| | |
| | | package cc.mrbird.febs.mall.service.impl; |
| | | |
| | | import cc.mrbird.febs.common.entity.FebsResponse; |
| | | import cc.mrbird.febs.common.enumerates.StateUpDownEnum; |
| | | import cc.mrbird.febs.common.enumerates.*; |
| | | import cc.mrbird.febs.common.exception.FebsException; |
| | | import cc.mrbird.febs.common.utils.LoginUserUtil; |
| | | import cc.mrbird.febs.mall.entity.HappyActivity; |
| | | import cc.mrbird.febs.mall.entity.HappyActivityOption; |
| | | import cc.mrbird.febs.mall.entity.HappyFollow; |
| | | import cc.mrbird.febs.mall.entity.MallMember; |
| | | import cc.mrbird.febs.mall.mapper.HappyActivityMapper; |
| | | import cc.mrbird.febs.mall.mapper.HappyActivityOptionMapper; |
| | | import cc.mrbird.febs.mall.mapper.HappyFollowMapper; |
| | | import cc.mrbird.febs.mall.mapper.MallMemberMapper; |
| | | import cc.mrbird.febs.common.utils.MallUtils; |
| | | import cc.mrbird.febs.common.utils.ShareCodeUtil; |
| | | import cc.mrbird.febs.mall.dto.*; |
| | | import cc.mrbird.febs.mall.entity.*; |
| | | import cc.mrbird.febs.mall.mapper.*; |
| | | import cc.mrbird.febs.mall.service.HappyActivityService; |
| | | import cc.mrbird.febs.mall.vo.api.activity.*; |
| | | import cc.mrbird.febs.mall.vo.api.activity.follow.ApiOperateDoDto; |
| | | import cc.mrbird.febs.mall.vo.api.activity.options.*; |
| | | import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; |
| | | import cc.mrbird.febs.mall.vo.*; |
| | | import cc.mrbird.febs.mall.dto.ApiOperateDoDto; |
| | | import cc.mrbird.febs.pay.model.BrandWCPayRequestData; |
| | | import cc.mrbird.febs.pay.service.IXcxPayService; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | private final HappyFollowMapper happyFollowMapper; |
| | | private final MallMemberMapper mallMemberMapper; |
| | | private final HappyActivityOptionMapper happyActivityOptionMapper; |
| | | private final HappyActivityConnectMapper happyActivityConnectMapper; |
| | | private final HappyActivityOrderMapper happyActivityOrderMapper; |
| | | private final HappyActivityOrderItemMapper happyActivityOrderItemMapper; |
| | | private final IXcxPayService iXcxPayService; |
| | | private final IApiMallMemberWalletService iApiMallMemberWalletService; |
| | | |
| | | @Override |
| | | public FebsResponse activityList(ApiActivityInfoDto dto) { |
| | |
| | | throw new FebsException("选项ID不能为空"); |
| | | } |
| | | this.operateDoVote(memberId, StateUpDownEnum.SOURCE_TYPE_ACTIVITY.getCode(), sourceId, sourceOptionId, type); |
| | | this.addLikeCnt(sourceOptionId); |
| | | } else { |
| | | this.operateDo(memberId, StateUpDownEnum.SOURCE_TYPE_ACTIVITY.getCode(), sourceId, type); |
| | | } |
| | |
| | | Integer sourceType = dto.getSourceType(); |
| | | Integer type = StateUpDownEnum.VOTE.getCode(); |
| | | |
| | | HappyActivity happyActivity = this.baseMapper.selectById(sourceId); |
| | | if(StateUpDownEnum.ACTIVITY_TYPE_VOTE.getCode() != happyActivity.getType()){ |
| | | throw new FebsException("当前活动无法投票"); |
| | | } |
| | | |
| | | HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(sourceOptionId); |
| | | if (happyActivityOption == null) { |
| | | throw new FebsException("投票对象不存在"); |
| | | } |
| | | if (StateUpDownEnum.VOTE_OPTION_STATE_AUDIT_SUCCESS.getCode() != happyActivityOption.getState()) { |
| | | throw new FebsException("请重新选择投票对象"); |
| | | } |
| | | //验证当前登录人员今日是否已经投票 |
| | | List<HappyFollow> happyFollows = happyFollowMapper.selectList( |
| | | new LambdaQueryWrapper<HappyFollow>() |
| | |
| | | .eq(HappyFollow::getType, type) |
| | | .gt(HappyFollow::getCreatedTime, DateUtil.beginOfDay(new Date())) |
| | | ); |
| | | if (CollUtil.isNotEmpty(happyFollows)){ |
| | | if (CollUtil.isNotEmpty(happyFollows) && happyFollows.size() >= happyActivity.getVoteCnt()){ |
| | | throw new FebsException("今日已经投票"); |
| | | } |
| | | |
| | | if (StateUpDownEnum.SOURCE_TYPE_ACTIVITY.getCode() == sourceType) { |
| | | HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(sourceOptionId); |
| | | if (happyActivityOption == null) { |
| | | throw new FebsException("投票对象不存在"); |
| | | } |
| | | if (StateUpDownEnum.VOTE_OPTION_STATE_AUDIT_SUCCESS.getCode() != happyActivityOption.getState()) { |
| | | throw new FebsException("请重新选择投票对象"); |
| | | } |
| | | |
| | | Integer likesCnt = happyActivityOption.getLikesCnt(); |
| | | if (likesCnt == null) { |
| | | likesCnt = 0; |
| | | } |
| | | likesCnt += 1; |
| | | happyActivityOption.setLikesCnt(likesCnt); |
| | | |
| | | boolean updateSuccess = happyActivityOptionMapper.updateById(happyActivityOption) > 0; |
| | | if (!updateSuccess) { |
| | | throw new FebsException("更新票数失败"); |
| | | } |
| | | |
| | | this.operateDoVote(memberId, sourceType, sourceId, sourceOptionId, type); |
| | | } |
| | | this.operateDoVote(memberId, sourceType, sourceId, sourceOptionId, type); |
| | | this.addLikeCnt(sourceOptionId); |
| | | return new FebsResponse().success(); |
| | | } |
| | | |
| | |
| | | |
| | | @Override |
| | | public FebsResponse operateRegister(ApiOperateRegisterActivityDto dto) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse addConnect(ApiOperateRegisterUserDto dto) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | |
| | | HappyActivityConnect happyActivityConnect = new HappyActivityConnect(); |
| | | happyActivityConnect.setMemberId(memberId); |
| | | happyActivityConnect.setName(dto.getName()); |
| | | happyActivityConnect.setPhone(dto.getPhone()); |
| | | happyActivityConnect.setAddress(dto.getAddress()); |
| | | happyActivityConnectMapper.insert(happyActivityConnect); |
| | | return new FebsResponse().success(); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse connectList(ApiConnectListDto dto) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | dto.setMemberId(memberId); |
| | | // 创建分页对象,传入当前页和每页大小 |
| | | Page<ApiConnectListInPageVo> page = new Page<>(dto.getPageNow(), dto.getPageSize()); |
| | | Page<ApiConnectListInPageVo> voteRecordInPage = happyActivityConnectMapper.selectConnectListPage(page, dto); |
| | | return new FebsResponse().success().data(voteRecordInPage); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse connectInfo(Long id) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | HappyActivityConnect happyActivityConnect = happyActivityConnectMapper.selectById(id); |
| | | ApiConnectListInPageVo apiConnectListInPageVo = new ApiConnectListInPageVo(); |
| | | BeanUtil.copyProperties(happyActivityConnect,apiConnectListInPageVo); |
| | | return new FebsResponse().success().data(apiConnectListInPageVo); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse connectDel(Long id) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | happyActivityConnectMapper.deleteById(id); |
| | | return new FebsResponse().success(); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse connectSave(ApiConnectSaveDto dto) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | Long id = dto.getId(); |
| | | HappyActivityConnect happyActivityConnect = happyActivityConnectMapper.selectById(id); |
| | | if (happyActivityConnect == null) { |
| | | throw new FebsException("记录不存在"); |
| | | } |
| | | happyActivityConnect.setName(dto.getName()); |
| | | happyActivityConnect.setPhone(dto.getPhone()); |
| | | happyActivityConnect.setAddress(dto.getAddress()); |
| | | happyActivityConnectMapper.updateById(happyActivityConnect); |
| | | return new FebsResponse().success(); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse createOrder(ApiCreateOrderDto dto) { |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | if(CollUtil.isEmpty(dto.getConnectIds())){ |
| | | throw new FebsException("请选择报名人"); |
| | | } |
| | | |
| | | List<Long> connectIds = dto.getConnectIds(); |
| | | Integer numCnt = dto.getNumCnt(); |
| | | if(numCnt != connectIds.size()){ |
| | | throw new FebsException("报名人数与票的数量不匹配"); |
| | | } |
| | | |
| | | Long activityId = dto.getActivityId(); |
| | | HappyActivity happyActivity = this.baseMapper.selectById(activityId); |
| | | if (ObjectUtil.isEmpty(happyActivity)) { |
| | | throw new FebsException("活动不存在"); |
| | | } |
| | | |
| | | Integer joinCnt = happyActivity.getJoinCnt(); |
| | | if(joinCnt < numCnt){ |
| | | throw new FebsException("报名额度剩下"+joinCnt+",请减少报名人数"); |
| | | } |
| | | //支付总金额 |
| | | BigDecimal amount = happyActivity.getPayAmount().multiply(new BigDecimal(dto.getNumCnt())).setScale(2, RoundingMode.DOWN); |
| | | if(amount.compareTo(BigDecimal.ZERO) < 0){ |
| | | throw new FebsException("支付金额错误"); |
| | | } |
| | | HappyActivityOrder happyActivityOrder = new HappyActivityOrder(); |
| | | happyActivityOrder.setOrderNo(MallUtils.getOrderNum()); |
| | | happyActivityOrder.setMemberId(memberId); |
| | | happyActivityOrder.setActivityId(dto.getActivityId()); |
| | | happyActivityOrder.setPrice(happyActivity.getPayAmount()); |
| | | happyActivityOrder.setNumCnt(dto.getNumCnt()); |
| | | happyActivityOrder.setAmount(amount); |
| | | happyActivityOrder.setPayState(StateUpDownEnum.PAY_STATE_NOT_PAY.getCode()); |
| | | happyActivityOrderMapper.insert(happyActivityOrder); |
| | | |
| | | for(Long connectId : connectIds){ |
| | | HappyActivityConnect happyActivityConnect = happyActivityConnectMapper.selectById(connectId); |
| | | HappyActivityOrderItem happyActivityOrderItem = new HappyActivityOrderItem(); |
| | | happyActivityOrderItem.setMemberId(memberId); |
| | | happyActivityOrderItem.setActivityId(dto.getActivityId()); |
| | | happyActivityOrderItem.setOrderId(happyActivityOrder.getId()); |
| | | happyActivityOrderItem.setConnectId(connectId); |
| | | happyActivityOrderItem.setPrice(happyActivity.getPayAmount()); |
| | | |
| | | happyActivityOrderItem.setName(happyActivityConnect.getName()); |
| | | happyActivityOrderItem.setPhone(happyActivityConnect.getPhone()); |
| | | happyActivityOrderItem.setAddress(happyActivityConnect.getAddress()); |
| | | happyActivityOrderItem.setState(StateUpDownEnum.DOWN.getCode()); |
| | | happyActivityOrderItemMapper.insert(happyActivityOrderItem); |
| | | } |
| | | |
| | | this.substructJoinCnt(activityId, happyActivityOrder.getNumCnt()); |
| | | HashMap<String, Object> stringObjectHashMap = new HashMap<>(); |
| | | stringObjectHashMap.put("orderId",happyActivityOrder.getId()); |
| | | stringObjectHashMap.put("amount",amount); |
| | | |
| | | return new FebsResponse().success().data(stringObjectHashMap); |
| | | } |
| | | |
| | | /** |
| | | * 支付订单函数,根据传入的支付订单数据对象处理不同支付类型的订单支付逻辑。 |
| | | * |
| | | * @param dto 包含支付订单相关信息的数据传输对象,包括订单ID和支付类型等信息。 |
| | | * - orderId: 订单ID,用于查询订单信息。 |
| | | * - payType: 支付类型,决定支付逻辑的分支。 |
| | | * - tradePwd: 交易密码(可选),用于余额或积分支付时验证。 |
| | | * @return FebsResponse 返回支付结果的响应对象,包含支付状态、订单信息等数据。 |
| | | * - orderInfo: 支付结果信息,可能是预支付ID或其他支付相关数据。 |
| | | * - orderNo: 订单编号。 |
| | | * - orderId: 订单ID。 |
| | | * - wxResultStr: 微信支付相关的结果字符串(仅在微信支付时返回)。 |
| | | * @throws FebsException 如果订单不存在、已支付、支付失败或支付类型不支持,则抛出异常。 |
| | | */ |
| | | @Override |
| | | public FebsResponse payOrder(ApiPayOrderDto dto) { |
| | | // 获取当前登录用户的ID |
| | | Long memberId = LoginUserUtil.getLoginUser().getId(); |
| | | Long orderId = dto.getOrderId(); |
| | | Integer payType = dto.getPayType(); |
| | | |
| | | // 查询订单信息,确保订单存在且未支付 |
| | | HappyActivityOrder happyActivityOrder = happyActivityOrderMapper.selectById(orderId); |
| | | if (ObjectUtil.isEmpty(happyActivityOrder)) { |
| | | throw new FebsException("订单不存在"); |
| | | } |
| | | if (happyActivityOrder.getPayState() == StateUpDownEnum.PAY_STATE_PAY_SUCCESS.getCode()) { |
| | | throw new FebsException("订单已支付"); |
| | | } |
| | | |
| | | String payResultStr = ""; |
| | | String wxResultStr = ""; |
| | | |
| | | try { |
| | | // 根据支付类型处理不同的支付逻辑 |
| | | if (StateUpDownEnum.PAY_METHOD_NO_PAY.getCode() == payType) { |
| | | // 处理无需支付的订单逻辑 |
| | | processNoPayOrder(happyActivityOrder, orderId); |
| | | } else if (StateUpDownEnum.PAY_METHOD_WECHAT.getCode() == payType) { |
| | | // 处理微信支付逻辑,生成支付请求数据并更新订单状态 |
| | | BrandWCPayRequestData brandWCPayRequestData = iXcxPayService.startPaymentActivity(happyActivityOrder); |
| | | wxResultStr = JSONUtil.toJsonStr(brandWCPayRequestData); |
| | | payResultStr = brandWCPayRequestData.getPrepay_id(); |
| | | updateOrderState(happyActivityOrder, payType, StateUpDownEnum.PAY_STATE_NOT_PAY.getCode()); |
| | | } else if (StateUpDownEnum.PAY_METHOD_BALANCE.getCode() == payType || |
| | | StateUpDownEnum.PAY_METHOD_INTEGRAL.getCode() == payType) { |
| | | // 处理余额或积分支付逻辑,验证交易密码并完成支付 |
| | | String payMethod = StateUpDownEnum.PAY_METHOD_BALANCE.getCode() == payType ? "balance" : "prizeScore"; |
| | | payResultStr = balancePay(happyActivityOrder, dto.getTradePwd(), payMethod); |
| | | processPaidOrder(happyActivityOrder, orderId, payType); |
| | | } else { |
| | | // 如果支付类型不支持,抛出异常 |
| | | throw new FebsException("不支持的支付类型"); |
| | | } |
| | | } catch (Exception e) { |
| | | // 捕获支付过程中的异常,记录日志并抛出自定义异常 |
| | | log.error("支付失败,订单ID:{},支付类型:{}", orderId, payType, e); |
| | | throw new FebsException("支付失败:" + e.getMessage()); |
| | | } |
| | | |
| | | // todo 支付失败要把对应的人数加回来 |
| | | |
| | | // 构造返回结果,包含支付相关信息 |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("orderInfo", payResultStr); |
| | | map.put("orderNo", happyActivityOrder.getOrderNo()); |
| | | map.put("orderId", happyActivityOrder.getId()); |
| | | map.put("wxResultStr", wxResultStr); |
| | | |
| | | return new FebsResponse().success().data(map).message("支付成功"); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void addLikeCnt(Long sourceOptionId) { |
| | | HappyActivityOption happyActivityOption = happyActivityOptionMapper.selectById(sourceOptionId); |
| | | happyActivityOption.setLikesCnt(happyActivityOption.getLikesCnt() + 1); |
| | | happyActivityOptionMapper.updateById(happyActivityOption); |
| | | } |
| | | |
| | | @Override |
| | | public void substructJoinCnt(Long activityId, Integer numCnt) { |
| | | HappyActivity happyActivity = this.baseMapper.selectById(activityId); |
| | | if(ObjectUtil.isNotEmpty(happyActivity)){ |
| | | happyActivity.setJoinCnt(happyActivity.getJoinCnt() -numCnt); |
| | | this.baseMapper.updateById(happyActivity); |
| | | } |
| | | } |
| | | |
| | | // 处理未支付订单 |
| | | private void processNoPayOrder(HappyActivityOrder order, Long orderId) { |
| | | updateOrderState(order, StateUpDownEnum.PAY_METHOD_NO_PAY.getCode(), StateUpDownEnum.PAY_STATE_PAY_SUCCESS.getCode()); |
| | | generateOrderItemCodes(orderId); |
| | | } |
| | | |
| | | // 处理已支付订单 |
| | | private void processPaidOrder(HappyActivityOrder order, Long orderId, Integer payType) { |
| | | updateOrderState(order, payType, StateUpDownEnum.PAY_STATE_PAY_SUCCESS.getCode()); |
| | | generateOrderItemCodes(orderId); |
| | | } |
| | | |
| | | // 更新订单状态 |
| | | private void updateOrderState(HappyActivityOrder order, Integer payType, Integer payState) { |
| | | order.setPayState(payState); |
| | | order.setPayType(payType); |
| | | if (payState == StateUpDownEnum.PAY_STATE_PAY_SUCCESS.getCode()) { |
| | | order.setPayTime(new Date()); |
| | | } |
| | | happyActivityOrderMapper.updateById(order); |
| | | } |
| | | |
| | | // 批量生成订单项编码 |
| | | private void generateOrderItemCodes(Long orderId) { |
| | | List<HappyActivityOrderItem> items = happyActivityOrderItemMapper.selectList( |
| | | new LambdaQueryWrapper<HappyActivityOrderItem>() |
| | | .eq(HappyActivityOrderItem::getOrderId, orderId) |
| | | ); |
| | | if (CollUtil.isNotEmpty(items)) { |
| | | for (HappyActivityOrderItem item : items) { |
| | | String code = ShareCodeUtil.toSerialCode(item.getOrderId()) + MallUtils.getRandomNum(8); |
| | | item.setCode(code); |
| | | happyActivityOrderItemMapper.updateById(item); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | private String balancePay(HappyActivityOrder happyActivityOrder, String tradePwd, String field) { |
| | | if (StrUtil.isBlank(tradePwd)) { |
| | | throw new FebsException("支付密码错误"); |
| | | } |
| | | |
| | | MallMember mallMember = mallMemberMapper.selectById(happyActivityOrder.getMemberId()); |
| | | if (StrUtil.isBlank(mallMember.getTradePassword())) { |
| | | throw new FebsException("未设置支付密码"); |
| | | } |
| | | |
| | | if (!SecureUtil.md5(tradePwd).equals(mallMember.getTradePassword())) { |
| | | throw new FebsException("支付密码错误"); |
| | | } |
| | | |
| | | int reduce = iApiMallMemberWalletService.reduce(happyActivityOrder.getAmount(), mallMember.getId(), field); |
| | | if (reduce == 2) { |
| | | throw new FebsException("余额不足"); |
| | | } |
| | | return happyActivityOrder.getOrderNo(); |
| | | } |
| | | |
| | | |
| | | public static void main(String[] args) { |
| | | Date date = new Date(); |
| | | //获取今日的凌晨的时间 |