fix: 修复bug

This commit is contained in:
huchuansai
2025-10-04 23:59:17 +08:00
parent e9ab50ea0a
commit 4ee24aabea
12 changed files with 293 additions and 331 deletions

View File

@@ -6,9 +6,11 @@ import com.starry.admin.modules.order.module.dto.*;
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
import com.starry.admin.modules.order.module.vo.*;
import com.starry.admin.modules.weichat.entity.order.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.stereotype.Service;
/**
@@ -23,8 +25,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 查询当前租户店员总数
*
* @param tenantId
* 租户ID
* @param tenantId 租户ID
* @return 店员总数
*/
List<PlayOrderInfoEntity> getTotalOrderInfo(String tenantId);
@@ -32,14 +33,10 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 新增充值单
*
* @param orderNo
* 订单编号
* @param orderMoney
* 订单金额
* @param finalAmount
* 订单最终金额(支付金额)
* @param purchaserBy
* 下单人ID
* @param orderNo 订单编号
* @param orderMoney 订单金额
* @param finalAmount 订单最终金额(支付金额)
* @param purchaserBy 下单人ID
*/
void createRechargeOrder(String orderNo, BigDecimal orderMoney, BigDecimal finalAmount, String purchaserBy);
@@ -55,96 +52,63 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 新增订单信息 - 旧版本方法已废弃建议使用OrderCreationRequest
*
* @deprecated 请使用 {@link #createOrderInfo(OrderCreationRequest)} 替代
* @param orderId
* 订单ID
* @param orderNo
* 订单编号
* @param orderState
* 订单状态【0:已下单(待接单);1:已接单(待开始);2:已开始(服务中);3;已完成:4:已取消
* @param orderType
* 订单类型【-1:退款订单;0:充值订单1:提现订单2:普通订单】
* @param placeType
* 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param rewardType
* 0:余额;1:礼物)
* @param firstOrder
* 是否是首单【0不是1是】
* @param commodityId
* 商品ID
* @param commodityType
* 商品类型[0:礼物1服务]
* @param commodityPrice
* 商品属性-商品单价
* @param serviceDuration
* 商品属性-服务时长
* @param commodityName
* 商品名称
* @param commodityNumber
* 商品数量
* @param orderMoney
* 订单金额
* @param finalAmount
* 订单最终金额(支付金额)
* @param discountAmount
* 优惠金额
* @param purchaserBy
* 下单人
* @param acceptBy
* 接单人
* @param weiChatCode
* 订单微信号码
* @param couponIds
* 优惠券ID列表
* @param remark
* 订单备注
* @param clerkSex
* 随机单要求-店员性别0:未知;1:男;2:女)
* @param clerkLevelId
* 随机单要求-店员等级ID
* @param excludeHistory
* 随机单要求-是否排除下单过的成员0:不排除;1:排除)
* @param orderId 订单ID
* @param orderNo 订单编号
* @param orderState 订单状态【0:已下单(待接单);1:已接单(待开始);2:已开始(服务中);3;已完成:4:已取消】
* @param orderType 订单类型【-1:退款订单;0:充值订单1:提现订单2:普通订单】
* @param placeType 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param rewardType 0:余额;1:礼物)
* @param firstOrder 是否是首单【0不是1
* @param commodityId 商品ID
* @param commodityType 商品类型[0:礼物1服务]
* @param commodityPrice 商品属性-商品单价
* @param serviceDuration 商品属性-服务时长
* @param commodityName 商品名称
* @param commodityNumber 商品数量
* @param orderMoney 订单金额
* @param finalAmount 订单最终金额(支付金额)
* @param discountAmount 优惠金额
* @param purchaserBy 下单人
* @param acceptBy 接单人
* @param weiChatCode 订单微信号码
* @param couponIds 优惠券ID列表
* @param remark 订单备注
* @param clerkSex 随机单要求-店员性别0:未知;1:男;2:女)
* @param clerkLevelId 随机单要求-店员等级ID
* @param excludeHistory 随机单要求-是否排除下单过的成员0:不排除;1:排除)
* @author admin
* @since 2024/6/3 10:53
* @deprecated 请使用 {@link #createOrderInfo(OrderCreationRequest)} 替代
**/
@Deprecated
void createOrderInfo(String orderId, String orderNo, String orderState, String orderType, String placeType,
String rewardType, String firstOrder, String commodityId, String commodityType, BigDecimal commodityPrice,
String serviceDuration, String commodityName, String commodityNumber, BigDecimal orderMoney,
BigDecimal finalAmount, BigDecimal discountAmount, String purchaserBy, String acceptBy, String weiChatCode,
List<String> couponIds, String remark, String clerkSex, String clerkLevelId, String excludeHistory);
String rewardType, String firstOrder, String commodityId, String commodityType, BigDecimal commodityPrice,
String serviceDuration, String commodityName, String commodityNumber, BigDecimal orderMoney,
BigDecimal finalAmount, BigDecimal discountAmount, String purchaserBy, String acceptBy, String weiChatCode,
List<String> couponIds, String remark, String clerkSex, String clerkLevelId, String excludeHistory);
/**
* 据店员等级和订单金额,获取店员预计收入
*
* @param clerkId
* 店员ID
* @param croupIds
* 优惠券ID列表
* @param placeType
* 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param firstOrder
* 是否是首单【0不是1是】
* @param finalAmount
* 订单支付金额
* @param clerkId 店员ID
* @param croupIds 优惠券ID列表
* @param placeType 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param firstOrder 是否是首单【0不是1是】
* @param finalAmount 订单支付金额
* @return com.starry.admin.modules.order.module.vo.ClerkEstimatedRevenueVo
* @author admin
* @since 2024/7/18 16:39
**/
ClerkEstimatedRevenueVo getClerkEstimatedRevenue(String clerkId, List<String> croupIds, String placeType,
String firstOrder, BigDecimal finalAmount);
String firstOrder, BigDecimal finalAmount);
/**
* 根据店员等级和订单金额,获取店员预计收入
*
* @param clerkId
* 店员ID
* @param placeType
* 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param firstOrder
* 是否是首单【0不是1是】
* @param finalAmount
* 订单支付金额
* @param clerkId 店员ID
* @param placeType 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param firstOrder 是否是首单【0不是1是】
* @param finalAmount 订单支付金额
* @return math.BigDecimal 店员预计收入
* @author admin
* @since 2024/6/3 11:12
@@ -154,12 +118,9 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 根据店员等级,获取店员提成比例
*
* @param clerkId
* 店员ID
* @param placeType
* 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param firstOrder
* 是否是首单【0不是1是】
* @param clerkId 店员ID
* @param placeType 下单类型(-1:其他类型;0:指定单;1:随机单;2:打赏单)
* @param firstOrder 是否是首单【0不是1是】
* @return math.BigDecimal 店员预计收入
* @author admin
* @since 2024/6/3 11:12
@@ -169,10 +130,8 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 根据订单结算状态查询订单
*
* @param clerkId
* 店员ID
* @param orderSettlementState
* 订单结算状态(0:未结算;1:已结算)
* @param clerkId 店员ID
* @param orderSettlementState 订单结算状态(0:未结算;1:已结算)
* @return List<PlayOrderInfoEntity>
*/
List<PlayOrderInfoEntity> queryBySettlementOrder(String clerkId, String orderSettlementState);
@@ -180,10 +139,8 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 查询指定店员在指定时间前完成,并且未结算工资的订单
*
* @param clerkId
* 店员ID
* @param endTime
* 结束时间
* @param clerkId 店员ID
* @param endTime 结束时间
* @return List<PlayOrderInfoEntity>
*/
List<PlayOrderInfoEntity> listByEndTime(String clerkId, LocalDateTime endTime);
@@ -191,14 +148,10 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 查询指定店员在一定时间内的订单
*
* @param clerkId
* 店员ID
* @param startTime
* 开始时间
* @param endTime
* 结束时间
* @param orderStatus
* 店员状态列表
* @param clerkId 店员ID
* @param startTime 开始时间
* @param endTime 结束时间
* @param orderStatus 店员状态列表
* @return List<PlayOrderInfoEntity>
*/
List<PlayOrderInfoEntity> listByTime(String clerkId, String startTime, String endTime, List<String> orderStatus);
@@ -206,8 +159,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 分页查询打赏订单
*
* @param vo
* 打赏订单查询对象
* @param vo 打赏订单查询对象
* @return 打赏订单
*/
IPage<PlayOrderRewardReturnVo> selectRewardOrderInfoByPage(PlayOrderRewardQueryVo vo);
@@ -215,8 +167,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 根据订单ID查询订单信息
*
* @param orderId
* 订单ID
* @param orderId 订单ID
* @return 订单信息
*/
PlayOrderDetailsReturnVo selectById(String orderId);
@@ -224,8 +175,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 查询订单
*
* @param id
* 订单主键
* @param id 订单主键
* @return 订单
*/
PlayOrderInfoEntity selectOrderInfoById(String id);
@@ -233,8 +183,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 查询订单列表
*
* @param orderInfoEntity
* 订单
* @param orderInfoEntity 订单
* @return 订单集合
*/
IPage<PlayOrderInfoReturnVo> selectOrderInfoPage(PlayOrderInfoQueryVo orderInfoEntity);
@@ -242,10 +191,8 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 店员查询本人订单详情
*
* @param clerkId
* 店员ID
* @param id
* 订单ID
* @param clerkId 店员ID
* @param id 订单ID
* @return 订单详情
*/
@@ -254,8 +201,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 店员分页查询订单本人列表
*
* @param vo
* 订单列表查询对象
* @param vo 订单列表查询对象
* @return 订单集合
*/
IPage<PlayClerkOrderListReturnVo> clerkSelectOrderInfoByPage(PlayClerkOrderInfoQueryVo vo);
@@ -263,12 +209,9 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 店员查询自己一段时间内的订单
*
* @param clerkId
* 店员ID
* @param startTime
* 开始时间
* @param endTime
* 结束时间
* @param clerkId 店员ID
* @param startTime 开始时间
* @param endTime 结束时间
* @return 订单列表
*/
List<PlayOrderInfoEntity> clerkSelectOrderInfoList(String clerkId, String startTime, String endTime);
@@ -276,10 +219,8 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 顾客查询订单详情
*
* @param customId
* 顾客ID
* @param orderId
* 订单ID
* @param customId 顾客ID
* @param orderId 订单ID
* @return 订单详情
*/
PlayCustomOrderDetailsReturnVo customSelectOrderDetails(String customId, String orderId);
@@ -287,8 +228,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 顾客分页查询订单列表
*
* @param vo
* 订单列表查询对象
* @param vo 订单列表查询对象
* @return 订单集合
*/
IPage<PlayCustomOrderListReturnVo> customSelectOrderInfoByPage(PlayCustomOrderInfoQueryVo vo);
@@ -296,8 +236,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 顾客查询本人订单列表
*
* @param customId
* 顾客ID
* @param customId 顾客ID
* @return 订单集合
*/
List<PlayOrderInfoEntity> customSelectOrderInfoByList(String customId);
@@ -305,53 +244,39 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 修改订单状态为接单 只有管理员或者店员本人才能操作
*
* @param operatorByType
* 操作人类型0:顾客;1:店员;2:管理员)
* @param operatorBy
* 操作人ID
* @param acceptBy
* 接单人ID
* @param orderId
* 订单Id
* @param operatorByType 操作人类型0:顾客;1:店员;2:管理员)
* @param operatorBy 操作人ID
* @param acceptBy 接单人ID
* @param orderId 订单Id
**/
void updateStateTo1(String operatorByType, String operatorBy, String acceptBy, String orderId);
/**
* 修改订单状态为开始订单或者完成订单 只有管理员或者店员本人才能操作
*
* @param operatorByType
* 操作人类型0:顾客;1:店员;2:管理员)
* @param operatorBy
* 操作人ID
* @param orderState
* 订单状态
* @param orderId
* 订单Id
* @param operatorByType 操作人类型0:顾客;1:店员;2:管理员)
* @param operatorBy 操作人ID
* @param orderState 订单状态
* @param orderId 订单Id
**/
void updateStateTo23(String operatorByType, String operatorBy, String orderState, String orderId);
/**
* 修改订单状态为取消订单 管理员、店员、顾客均可操作
*
* @param operatorByType
* 操作人类型0:顾客;1:店员;2:管理员)
* @param operatorBy
* 操作人ID
* @param orderId
* 订单Id
* @param refundReason
* 订单取消原因
* @param images
* 证据图片列表
* @param operatorByType 操作人类型0:顾客;1:店员;2:管理员)
* @param operatorBy 操作人ID
* @param orderId 订单Id
* @param refundReason 订单取消原因
* @param images 证据图片列表
**/
void updateStateTo4(String operatorByType, String operatorBy, String orderId, String refundReason,
List<String> images);
List<String> images);
/**
* 修改订单
*
* @param orderInfoEntity
* 订单
* @param orderInfoEntity 订单
* @return 结果
*/
boolean update(PlayOrderInfoEntity orderInfoEntity);
@@ -359,8 +284,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 批量删除订单
*
* @param ids
* 需要删除的订单主键集合
* @param ids 需要删除的订单主键集合
* @return 结果
*/
int deleteOrderInfoByIds(String[] ids);
@@ -368,8 +292,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 根据订单编号查询订单信息
*
* @param orderNo
* 订单编号
* @param orderNo 订单编号
* @return 订单信息
*/
PlayOrderInfoEntity queryByOrderNo(String orderNo);
@@ -377,8 +300,7 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 删除订单信息
*
* @param id
* 订单主键
* @param id 订单主键
* @return 结果
*/
int deleteOrderInfoById(String id);
@@ -393,10 +315,8 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 查询未接单的订单
*
* @param vo
* 查询对象
* @param clerkId
* 店员ID
* @param vo 查询对象
* @param clerkId 店员ID
* @return 订单列表
*/
IPage<PlayOrderInfoEntity> selectRandomOrderByPage(PlayOrderInfoRandomQueryVo vo, String clerkId);
@@ -404,10 +324,11 @@ public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {
/**
* 分页获取打赏动态
*
* @param vo
* 查询对象
* @param vo 查询对象
* @return 打赏动态列表
*/
IPage<PlayRewardInfoReturnVo> selectRewardByPage(PlayRewardOrderQueryVo vo);
Boolean checkFirstOrderFlag(String customId, String clerkId);
}

View File

@@ -6,6 +6,7 @@ import static com.starry.admin.modules.order.module.constant.OrderConstant.ORDER
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
@@ -38,6 +39,7 @@ import com.starry.admin.utils.SecurityUtils;
import com.starry.common.utils.ConvertUtil;
import com.starry.common.utils.IdUtils;
import com.starry.common.utils.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
@@ -48,6 +50,7 @@ import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -68,8 +71,6 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
@Resource
private IPlayClerkUserInfoService playClerkUserInfoService;
@Resource
private IPlayCustomUserInfoService playCustomUserInfoService;
@Resource
private IPlayCustomUserInfoService userInfoService;
@Resource
private IPlayOrderRefundInfoService playOrderRefundInfoService;
@@ -180,6 +181,10 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
if (request.isRewardOrder()) {
setRewardOrderCompleted(entity);
}
// 处理首单逻辑
if (StrUtil.isNotBlank(request.getAcceptBy()) && StrUtil.isNotBlank(request.getPurchaserBy())) {
entity.setFirstOrder(this.checkFirstOrderFlag(request.getPurchaserBy(), request.getAcceptBy()) ? "1" : "0");
}
// 保存订单
userInfoService.saveOrderInfo(entity);
@@ -187,7 +192,7 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
// 修改优惠券状态
playCouponDetailsService.updateCouponUseStateByIds(
request.getPaymentInfo().getCouponIds(), "2");
request.getPaymentInfo().getCouponIds(), "2");
}
/**
@@ -195,7 +200,7 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
*/
private void validateOrderCreationRequest(OrderCreationRequest request) {
if (request.getPlaceType() == OrderConstant.PlaceType.RANDOM
&& !request.isValidForRandomOrder()) {
&& !request.isValidForRandomOrder()) {
throw new CustomException("随机单必须提供店员要求信息");
}
}
@@ -238,7 +243,7 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
entity.setDiscountAmount(paymentInfo.getDiscountAmount());
entity.setCouponIds(paymentInfo.getCouponIds());
entity.setUseCoupon(
paymentInfo.getCouponIds() != null && !paymentInfo.getCouponIds().isEmpty() ? "1" : "0");
paymentInfo.getCouponIds() != null && !paymentInfo.getCouponIds().isEmpty() ? "1" : "0");
// 用户信息
entity.setPurchaserBy(request.getPurchaserBy());
@@ -266,11 +271,11 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
private void setAcceptByInfo(PlayOrderInfoEntity entity, OrderCreationRequest request) {
entity.setAcceptBy(request.getAcceptBy());
ClerkEstimatedRevenueVo estimatedRevenueVo = getClerkEstimatedRevenue(
request.getAcceptBy(),
request.getPaymentInfo().getCouponIds(),
request.getPlaceType().getCode(),
request.getFirstOrderString(),
request.getPaymentInfo().getFinalAmount());
request.getAcceptBy(),
request.getPaymentInfo().getCouponIds(),
request.getPlaceType().getCode(),
request.getFirstOrderString(),
request.getPaymentInfo().getFinalAmount());
entity.setEstimatedRevenue(estimatedRevenueVo.getRevenueAmount());
entity.setEstimatedRevenueRatio(estimatedRevenueVo.getRevenueRatio());
}
@@ -587,9 +592,9 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getOrderStatus, "0");
// lambdaQueryWrapper.eq(PlayOrderInfoEntity::getLevelId, entity.getLevelId());
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getSex, entity.getSex());
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getExcludeHistory, "0")
.or(wrapper1 -> wrapper1.ne(PlayOrderInfoEntity::getAcceptBy, clerkId)
.and(wrapper2 -> wrapper2.eq(PlayOrderInfoEntity::getExcludeHistory, 1)));
// lambdaQueryWrapper.eq(PlayOrderInfoEntity::getExcludeHistory, "0")
// .or(wrapper1 -> wrapper1.ne(PlayOrderInfoEntity::getAcceptBy, clerkId)
// .and(wrapper2 -> wrapper2.eq(PlayOrderInfoEntity::getExcludeHistory, 1)));
return this.baseMapper.selectPage(new Page<>(vo.getPageNum(), vo.getPageSize()), lambdaQueryWrapper);
}
@@ -613,6 +618,13 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
PlayRewardInfoReturnVo.class, lambdaQueryWrapper);
}
@Override
public Boolean checkFirstOrderFlag(String customId, String clerkId) {
// 检查是否是首单
LambdaQueryWrapper<PlayOrderInfoEntity> wrapper = Wrappers.lambdaQuery(PlayOrderInfoEntity.class).eq(PlayOrderInfoEntity::getPurchaserBy, customId).eq(PlayOrderInfoEntity::getAcceptBy, clerkId).eq(PlayOrderInfoEntity::getOrderStatus, "3");
return this.baseMapper.selectCount(wrapper) > 0;
}
/**
* 查询订单
*

View File

@@ -44,6 +44,7 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
@@ -51,6 +52,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -115,7 +117,7 @@ public class WxClerkController {
* 店员获取个人业绩信息
*/
@ApiOperation(value = "查询店员业绩", notes = "店员获取个人业绩信息")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功") })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
@ClerkUserLogin
@PostMapping("/user/queryPerformanceInfo")
public R queryPerformanceInfo(
@@ -134,7 +136,7 @@ public class WxClerkController {
* 店员获取个人等级信息
*/
@ApiOperation(value = "查询店员等级", notes = "店员获取个人等级信息")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功", response = PlayClerkLevelInfoReturnVo.class) })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = PlayClerkLevelInfoReturnVo.class)})
@ClerkUserLogin
@GetMapping("/user/queryLevelInfo")
public R queryLevelInfo() {
@@ -159,8 +161,8 @@ public class WxClerkController {
* 店员获取个人信息
*/
@ApiOperation(value = "查询店员信息", notes = "店员获取个人详细信息")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功", response = PlayClerkUserInfoResultVo.class),
@ApiResponse(code = 500, message = "用户不存在") })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = PlayClerkUserInfoResultVo.class),
@ApiResponse(code = 500, message = "用户不存在")})
@ClerkUserLogin
@GetMapping("/user/queryById")
public R queryById() {
@@ -173,7 +175,7 @@ public class WxClerkController {
}
@ApiOperation(value = "发送验证码", notes = "店员绑定手机号发送验证码")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功", response = String.class) })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功", response = String.class)})
@ClerkUserLogin
@PostMapping("/user/sendCode")
public R sendCode(
@@ -187,7 +189,7 @@ public class WxClerkController {
}
@ApiOperation(value = "绑定手机号", notes = "店员绑定手机号")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "验证码错误") })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "验证码错误")})
@ClerkUserLogin
@PostMapping("/user/bindCode")
public R bindCode(
@@ -211,17 +213,19 @@ public class WxClerkController {
}
@ApiOperation(value = "店员申请", notes = "用户申请成为店员")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "系统错误,用户不存在"),
@ApiResponse(code = 500, message = "当前用户已经是店员"), @ApiResponse(code = 500, message = "已有申请未审核") })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "系统错误,用户不存在"),
@ApiResponse(code = 500, message = "当前用户已经是店员"), @ApiResponse(code = 500, message = "已有申请未审核")})
@ClerkUserLogin
@PostMapping("/user/add")
@Transactional(rollbackFor = Exception.class)
public R userAdd(@ApiParam(value = "店员申请信息", required = true) @Validated @RequestBody PlayClerkUserByWxAddVo vo) {
String clerkId = ThreadLocalRequestDetail.getClerkUserInfo().getId();
PlayClerkUserInfoEntity userInfo = playClerkUserInfoService.selectById(clerkId);
if (userInfo == null) {
throw new CustomException("系统错误,用户不存在");
}
wxCustomMpService.checkSubscribeThrowsExp(userInfo.getOpenid(), userInfo.getTenantId());
if ("1".equals(userInfo.getClerkState())) {
throw new CustomException("当前用户已经是店员");
}
@@ -241,7 +245,7 @@ public class WxClerkController {
}
@ApiOperation(value = "更新头像", notes = "店员更新头像")
@ApiResponses({ @ApiResponse(code = 200, message = "操作成功") })
@ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
@ClerkUserLogin
@PostMapping("/user/updateAvatar")
public R updateAvatar(@ApiParam(value = "头像信息", required = true) @Validated @RequestBody PlayClerkUserAvatarVo vo) {
@@ -340,8 +344,7 @@ public class WxClerkController {
/**
* 分页获取店员列表
*
* @param vo
* PlayClerkUserInfoQueryVo
* @param vo PlayClerkUserInfoQueryVo
* @return 店员列表
*/
@PostMapping("/user/queryByPage")
@@ -369,8 +372,7 @@ public class WxClerkController {
/**
* 获取店员礼物信息
*
* @param id
* 店员ID
* @param id 店员ID
* @return 店员礼物
*/
@@ -405,8 +407,7 @@ public class WxClerkController {
/**
* 获取店员价格
*
* @param id
* 店员ID
* @param id 店员ID
* @return 店员价格
*/
@GetMapping("/user/queryPriceById")
@@ -417,8 +418,7 @@ public class WxClerkController {
/**
* 店员分页查询本人订单列表
*
* @param vo
* 订单列表分页查询对象
* @param vo 订单列表分页查询对象
* @return com.starry.common.result.R
* @author admin
* @since 2024/5/8 15:57
@@ -434,8 +434,7 @@ public class WxClerkController {
/**
* 店员查询本人订单详情
*
* @param id
* 订单ID
* @param id 订单ID
* @return com.starry.common.result.R
* @author admin
* @since 2024/5/8 15:57
@@ -448,7 +447,7 @@ public class WxClerkController {
if (StringUtils.isNotEmpty(vo.getAcceptBy()) && !vo.getAcceptBy().equals(ThreadLocalRequestDetail.getClerkUserInfo().getId())) {
vo.setWeiChatCode("");
}
if(vo.getOrderStatus().equals("4")){
if (vo.getOrderStatus().equals("4")) {
vo.setWeiChatCode("");
}
return R.ok(vo);
@@ -457,8 +456,7 @@ public class WxClerkController {
/**
* 店员-接单
*
* @param id
* 订单ID
* @param id 订单ID
* @return com.starry.common.result.R
* @author admin
* @since 2024/5/8 15:57
@@ -466,16 +464,27 @@ public class WxClerkController {
@ClerkUserLogin
@GetMapping("/order/accept")
public R acceptOrder(@RequestParam("id") String id) {
playOrderInfoService.updateStateTo1("1", ThreadLocalRequestDetail.getClerkUserInfo().getId(),
ThreadLocalRequestDetail.getClerkUserInfo().getId(), id);
PlayClerkUserInfoEntity clerkUserInfo = ThreadLocalRequestDetail.getClerkUserInfo();
wxCustomMpService.checkSubscribeThrowsExp(clerkUserInfo.getOpenid(), clerkUserInfo.getTenantId());
playOrderInfoService.updateStateTo1("1", clerkUserInfo.getId(),
clerkUserInfo.getId(), id);
return R.ok("成功");
}
@GetMapping("/checkSubscribe")
@ClerkUserLogin
public R checkSubscribe() {
String openid = ThreadLocalRequestDetail.getClerkUserInfo().getOpenid();
String tenantId = SecurityUtils.getTenantId();
wxCustomMpService.checkSubscribe(openid, tenantId);
return R.ok(true);
}
/**
* 店员-开始订单
*
* @param id
* 订单ID
* @param id 订单ID
* @return com.starry.common.result.R
* @author admin
* @since 2024/5/8 15:57
@@ -490,8 +499,7 @@ public class WxClerkController {
/**
* 店员-取消订单
*
* @param vo
* 取消订单传参
* @param vo 取消订单传参
* @return com.starry.common.result.R
* @author admin
* @since 2024/5/8 15:57
@@ -507,8 +515,7 @@ public class WxClerkController {
/**
* 分页获取店员评价(订单评价)
*
* @param vo
* 店员评价查询对象
* @param vo 店员评价查询对象
* @return 店员评价
*/
@PostMapping("/user/queryEvaluateByPage")

View File

@@ -18,6 +18,7 @@ import com.starry.admin.modules.weichat.entity.WxUserQueryAddressVo;
import com.starry.admin.modules.weichat.service.WxCustomMpService;
import com.starry.admin.modules.weichat.service.WxOauthService;
import com.starry.admin.modules.weichat.service.WxTokenService;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.redis.RedisCache;
import com.starry.common.result.R;
import io.swagger.annotations.Api;
@@ -26,8 +27,10 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.util.Date;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -193,6 +196,15 @@ public class WxOauthController {
return R.ok(url);
}
@GetMapping("/checkSubscribe")
@CustomUserLogin
public R checkSubscribe() {
String openid = ThreadLocalRequestDetail.getCustomUserInfo().getOpenid();
String tenantId = SecurityUtils.getTenantId();
wxCustomMpService.checkSubscribe(openid, tenantId);
return R.ok(true);
}
@ApiOperation(value = "顾客登录回调", notes = "微信顾客授权登录回调处理")
@ApiImplicitParam(name = "code", value = "授权码", required = true, dataType = "String", paramType = "query")
@GetMapping("/customLoginCallback")

View File

@@ -33,6 +33,7 @@ import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
@@ -42,6 +43,7 @@ import java.util.Map;
import java.util.Objects;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
@@ -82,8 +84,7 @@ public class WxPlayController {
@ApiResponses({@ApiResponse(code = 200, message = "成功")})
@RequestMapping("/jsCallback")
public String wxPayNotify(HttpServletRequest request) {
try (InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream()) {
try (InputStream inStream = request.getInputStream(); ByteArrayOutputStream outSteam = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) != -1) {
@@ -123,15 +124,13 @@ public class WxPlayController {
orderInfoEntity.setPayState("1");
orderInfoService.updateById(orderInfoEntity);
// 修改账户余额
customUserInfoService.customAccountBalanceRecharge(orderInfoEntity.getOrderMoney(),
orderInfoEntity.getPurchaserBy(), orderInfoEntity.getId());
customUserInfoService.customAccountBalanceRecharge(orderInfoEntity.getOrderMoney(), orderInfoEntity.getPurchaserBy(), orderInfoEntity.getId());
log.info("*********支付处理完成");
// 推送通知
mpService.sendBalanceMessage(orderInfoEntity);
// 请求分账
WxPayService wxPayService = mpService.getWxPay();
this.profitSharing(wxPayService, orderMap, orderInfoEntity,
tenantService.selectSysTenantByTenantId(orderInfoEntity.getTenantId()));
this.profitSharing(wxPayService, orderMap, orderInfoEntity, tenantService.selectSysTenantByTenantId(orderInfoEntity.getTenantId()));
} catch (Exception e) {
log.error("订单回调业务处理异常,xmlData={}", xmlData);
}
@@ -155,15 +154,13 @@ public class WxPlayController {
if (StringUtils.isEmpty(money)) {
throw new CustomException("请求参数错误,money不能为空");
}
BigDecimal paymentAmount = customUserInfoService.getCustomPaymentAmount(new BigDecimal(money),
ThreadLocalRequestDetail.getCustomUserInfo().getId());
BigDecimal paymentAmount = customUserInfoService.getCustomPaymentAmount(new BigDecimal(money), ThreadLocalRequestDetail.getCustomUserInfo().getId());
return R.ok(paymentAmount);
}
@ApiOperation(value = "创建充值订单", notes = "创建微信支付充值订单")
@ApiImplicitParam(name = "money", value = "充值金额", required = true, dataType = "String", paramType = "query")
@ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "请求参数错误,money不能为空"),
@ApiResponse(code = 500, message = "充值金额不能小于10元"), @ApiResponse(code = 500, message = "系统错误,租户ID获取失败")})
@ApiResponses({@ApiResponse(code = 200, message = "操作成功"), @ApiResponse(code = 500, message = "请求参数错误,money不能为空"), @ApiResponse(code = 500, message = "充值金额不能小于10元"), @ApiResponse(code = 500, message = "系统错误,租户ID获取失败")})
@CustomUserLogin
@GetMapping("/custom/createOrder")
public R createOrder(@RequestParam("money") String money) {
@@ -178,17 +175,16 @@ public class WxPlayController {
throw new CustomException("系统错误,租户ID获取失败");
}
// 用户信息
PlayCustomUserInfoEntity customUserInfo = customUserInfoService
.selectById(ThreadLocalRequestDetail.getCustomUserInfo().getId());
PlayCustomUserInfoEntity customUserInfo = customUserInfoService.selectById(ThreadLocalRequestDetail.getCustomUserInfo().getId());
// 租户信息
SysTenantEntity tenant = tenantService.selectSysTenantByTenantId(tenantId);
mpService.checkSubscribeThrowsExp(customUserInfo.getOpenid(), tenant.getTenantId());
Boolean profitSharing = tenant.getProfitsharingRate() > 0;
// 订单总金额,单位为分
long totalFee = getTotalFee(money);
// 创建订单信息
String orderNo = playOrderInfoService.getOrderNo();
orderInfoService.createRechargeOrder(orderNo, new BigDecimal(totalFee * 1.0 / 100),
new BigDecimal(totalFee * 1.0 / 100), customUserInfo.getId());
orderInfoService.createRechargeOrder(orderNo, new BigDecimal(totalFee * 1.0 / 100), new BigDecimal(totalFee * 1.0 / 100), customUserInfo.getId());
WxPayService wxPayService = mpService.getWxPay();
WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
@@ -229,10 +225,7 @@ public class WxPlayController {
String paySign = SignUtils.createSign(paySignInfo, "MD5", wxPayService.getConfig().getMchKey(), signInfo);
// 组合支付参数
JSONObject jsonObject = new JSONObject().fluentPut("appId", wxPayService.getConfig().getAppId())
.fluentPut("timeStamp", timeStamp).fluentPut("nonceStr", nonceStr)
.fluentPut("package", "prepay_id=" + prepayId).fluentPut("signType", "MD5")
.fluentPut("paySign", paySign);
JSONObject jsonObject = new JSONObject().fluentPut("appId", wxPayService.getConfig().getAppId()).fluentPut("timeStamp", timeStamp).fluentPut("nonceStr", nonceStr).fluentPut("package", "prepay_id=" + prepayId).fluentPut("signType", "MD5").fluentPut("paySign", paySign);
return R.ok(jsonObject);
}
@@ -243,9 +236,7 @@ public class WxPlayController {
String nonceStr = "dalfhh241lnandnsklajax";
request.setNonceStr(nonceStr);
request.setSignType("HMAC-SHA256");
request.setReceiver(new JSONObject().fluentPut("type", "MERCHANT_ID").fluentPut("account", "1681470208")
.fluentPut("name", "合肥经济技术开发区陪陪信息技术服务部(个体工商户)").fluentPut("relation_type", "SERVICE_PROVIDER")
.toString());
request.setReceiver(new JSONObject().fluentPut("type", "MERCHANT_ID").fluentPut("account", "1681470208").fluentPut("name", "合肥经济技术开发区陪陪信息技术服务部(个体工商户)").fluentPut("relation_type", "SERVICE_PROVIDER").toString());
try {
ProfitSharingReceiverResult result = wxPayService.getProfitSharingService().addReceiver(request);
log.info("请求添加分账结果:" + JSONObject.toJSONString(result));
@@ -256,8 +247,7 @@ public class WxPlayController {
}
/**
* @param money
* 金额,单位-元
* @param money 金额,单位-元
* @return 金额, 单位-分
*/
public long getTotalFee(String money) {
@@ -289,16 +279,14 @@ public class WxPlayController {
return map;
}
private void profitSharing(WxPayService wxPayService, Map<String, String> orderMap,
PlayOrderInfoEntity orderInfoEntity, SysTenantEntity tenant) throws WxPayException {
private void profitSharing(WxPayService wxPayService, Map<String, String> orderMap, PlayOrderInfoEntity orderInfoEntity, SysTenantEntity tenant) throws WxPayException {
Boolean profitSharing = tenant.getProfitsharingRate() > 0;
if (!profitSharing) {
return;
}
log.info("开始进行分账。。。。。。。。。。。。。。。");
long totalFee = getTotalFee(orderInfoEntity.getOrderMoney().toString());
int amount = new BigDecimal(totalFee).multiply(BigDecimal.valueOf((double) tenant.getProfitsharingRate() / 100))
.intValue();
int amount = new BigDecimal(totalFee).multiply(BigDecimal.valueOf((double) tenant.getProfitsharingRate() / 100)).intValue();
if (amount == 0) {
return;
}
@@ -307,17 +295,12 @@ public class WxPlayController {
request.setTransactionId(orderMap.get("transaction_id"));
request.setOutOrderNo("ps" + orderMap.get("out_trade_no"));
request.setReceivers(new JSONArray().fluentAdd(
new JSONObject().fluentPut("type", "MERCHANT_ID").fluentPut("name", "合肥经济技术开发区陪陪信息技术服务部(个体工商户)")
.fluentPut("account", "1681470208").fluentPut("amount", amount))
.toString());
request.setReceivers(new JSONArray().fluentAdd(new JSONObject().fluentPut("type", "MERCHANT_ID").fluentPut("name", "合肥经济技术开发区陪陪信息技术服务部(个体工商户)").fluentPut("account", "1681470208").fluentPut("amount", amount)).toString());
ProfitSharingResult result = wxPayService.getProfitSharingService().profitSharing(request);
log.info("分账结果:" + JSONObject.toJSONString(result));
// 保存分账金额
BigDecimal profitSharingAmount = new BigDecimal(amount).divide(new BigDecimal(100));
orderInfoService.update(null,
Wrappers.lambdaUpdate(PlayOrderInfoEntity.class).eq(PlayOrderInfoEntity::getId, orderInfoEntity.getId())
.set(PlayOrderInfoEntity::getProfitSharingAmount, profitSharingAmount));
orderInfoService.update(null, Wrappers.lambdaUpdate(PlayOrderInfoEntity.class).eq(PlayOrderInfoEntity::getId, orderInfoEntity.getId()).set(PlayOrderInfoEntity::getProfitSharingAmount, profitSharingAmount));
}
}

View File

@@ -2,12 +2,14 @@ package com.starry.admin.modules.weichat.service;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.common.exception.ServiceException;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserReviewInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
@@ -20,14 +22,17 @@ import com.starry.admin.modules.personnel.service.IPlayPersonnelAdminInfoService
import com.starry.admin.modules.system.module.entity.SysTenantEntity;
import com.starry.admin.modules.system.service.impl.SysTenantServiceImpl;
import com.starry.admin.utils.SecurityUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.config.impl.WxMpMapConfigImpl;
@@ -76,6 +81,7 @@ public class WxCustomMpService {
wxMpService.addConfigStorage(entity.getAppId(), config);
return wxMpService.switchoverTo(entity.getAppId());
}
public WxMpService proxyWxMpService(String tenantId) {
if (StrUtil.isBlankIfStr(tenantId)) {
throw new CustomException("系统错误,租户ID不能为空");
@@ -329,23 +335,46 @@ public class WxCustomMpService {
if (order.getPlaceType().equals("1") || order.getPlaceType().equals("2")) {
SysTenantEntity tenant = tenantService.selectSysTenantByTenantId(order.getTenantId());
PlayCustomUserInfoEntity customUserInfo = customUserInfoService.selectById(order.getPurchaserBy());
WxMpTemplateMessage templateMessage = getWxMpTemplateMessage(tenant.getDingdanwanchengtongzhiTemplateId(),
customUserInfo.getOpenid(),
"https://" + tenant.getTenantKey() + ".julyharbor.com/user/#/orderDetail/" + order.getId());
List<WxMpTemplateData> data = new ArrayList<>();
data.add(new WxMpTemplateData("time18", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")));
data.add(new WxMpTemplateData("character_string8", order.getOrderNo()));
data.add(new WxMpTemplateData("thing13", order.getCommodityName()));
templateMessage.setData(data);
try {
proxyWxMpService(tenant.getTenantId()).getTemplateMsgService().sendTemplateMsg(templateMessage);
} catch (WxErrorException e) {
log.error("订单完成发送消息异常", e);
}
PlayClerkUserInfoEntity clerkUserInfo = clerkUserInfoService.selectById(order.getAcceptBy());
this.sendUserOrderFinishMessage(order, customUserInfo, tenant);
this.sendClerkOrderFinishMessage(order, clerkUserInfo, tenant);
}
}
private void sendClerkOrderFinishMessage(PlayOrderInfoEntity order, PlayClerkUserInfoEntity clerkUserInfo, SysTenantEntity tenant) {
WxMpTemplateMessage templateMessage = getWxMpTemplateMessage(tenant.getDingdanwanchengtongzhiTemplateId(),
clerkUserInfo.getOpenid(),
"https://" + tenant.getTenantKey() + ".julyharbor.com/clerk/#/orderDetail/" + order.getId());
List<WxMpTemplateData> data = new ArrayList<>();
data.add(new WxMpTemplateData("time18", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")));
data.add(new WxMpTemplateData("character_string8", order.getOrderNo()));
data.add(new WxMpTemplateData("thing13", order.getCommodityName()));
templateMessage.setData(data);
try {
proxyWxMpService(tenant.getTenantId()).getTemplateMsgService().sendTemplateMsg(templateMessage);
} catch (WxErrorException e) {
log.error("订单完成发送消息异常", e);
}
}
private void sendUserOrderFinishMessage(PlayOrderInfoEntity order, PlayCustomUserInfoEntity customUserInfo, SysTenantEntity tenant) {
WxMpTemplateMessage templateMessage = getWxMpTemplateMessage(tenant.getDingdanwanchengtongzhiTemplateId(),
customUserInfo.getOpenid(),
"https://" + tenant.getTenantKey() + ".julyharbor.com/user/#/orderDetail/" + order.getId());
List<WxMpTemplateData> data = new ArrayList<>();
data.add(new WxMpTemplateData("time18", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")));
data.add(new WxMpTemplateData("character_string8", order.getOrderNo()));
data.add(new WxMpTemplateData("thing13", order.getCommodityName()));
templateMessage.setData(data);
try {
proxyWxMpService(tenant.getTenantId()).getTemplateMsgService().sendTemplateMsg(templateMessage);
} catch (WxErrorException e) {
log.error("订单完成发送消息异常", e);
}
}
public void sendOrderCancelMessage(PlayOrderInfoEntity orderInfo, String refundReason) {
SysTenantEntity tenant = tenantService.selectSysTenantByTenantId(orderInfo.getTenantId());
@@ -380,5 +409,31 @@ public class WxCustomMpService {
}
public void checkSubscribeThrowsExp(String openId, String tenantId) {
if (StrUtil.isBlankIfStr(openId)) {
throw new ServiceException("openId不能为空");
}
try {
WxMpUser wxMpUser = proxyWxMpService(tenantId).getUserService().userInfo(openId);
if (!wxMpUser.getSubscribe()) {
log.info("检测到用户未关注公众号:" + JSONObject.toJSONString(wxMpUser));
throw new ServiceException("请先关注公众号然后再来使用系统~");
}
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
}
public Boolean checkSubscribe(String openId, String tenantId) {
if (StrUtil.isBlankIfStr(openId)) {
throw new ServiceException("openId不能为空");
}
try {
WxMpUser wxMpUser = proxyWxMpService(tenantId).getUserService().userInfo(openId);
return wxMpUser.getSubscribe();
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,22 +1,29 @@
package com.starry.admin.modules.weichat.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSONObject;
import com.starry.admin.common.exception.ServiceException;
import com.starry.admin.common.oss.service.IOssFileService;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkLevelInfoService;
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.custom.service.IPlayCustomLevelInfoService;
import com.starry.admin.modules.custom.service.IPlayCustomUserInfoService;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.utils.ConvertUtil;
import com.starry.common.utils.IdUtils;
import java.io.InputStream;
import java.util.Date;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.stereotype.Service;
/**
@@ -42,12 +49,13 @@ public class WxOauthService {
@Resource
private IPlayCustomLevelInfoService playCustomLevelInfoService;
@Resource
IOssFileService ossFileService;
/**
* 微信用户登录 如果用户不存在,初始化用户并登录
*
* @param code
* 微信授权code
* @param code 微信授权code
* @return String 用户ID
* @author admin
* @since 2024/4/15 11:01
@@ -61,22 +69,24 @@ public class WxOauthService {
PlayClerkUserInfoEntity item = clerkUserInfoService.selectByOpenid(openId);
if (item == null) {
PlayClerkUserInfoEntity entity = ConvertUtil.entityToVo(userInfo, PlayClerkUserInfoEntity.class);
entity.setAvatar(userInfo.getHeadImgUrl());
entity.setWeiChatAvatar(userInfo.getHeadImgUrl());
entity.setAvatar(generateAvatar(userInfo.getHeadImgUrl()));
entity.setWeiChatAvatar(generateAvatar(userInfo.getHeadImgUrl()));
entity.setId(IdUtils.getUuid());
entity.setLevelId(playClerkLevelInfoService.getDefaultLevel().getId());
clerkUserInfoService.create(entity);
return entity.getId();
} else {
PlayClerkUserInfoEntity entity = new PlayClerkUserInfoEntity();
entity.setId(item.getId());
entity.setAvatar(userInfo.getHeadImgUrl());
entity.setWeiChatAvatar(userInfo.getHeadImgUrl());
clerkUserInfoService.updateById(entity);
return item.getId();
}
}
private String generateAvatar(String imageUrl) {
InputStream inputStream = HttpRequest.get(imageUrl).execute().bodyStream();
String fileAddress = ossFileService.upload(inputStream, SecurityUtils.getTenantId(),
"image");
return fileAddress;
}
public void clerkUserLogout(PlayClerkUserInfoEntity entity) {
entity.setToken("empty");
clerkUserInfoService.update(entity);
@@ -110,8 +120,7 @@ public class WxOauthService {
/**
* 获取微信授权Token
*
* @param code
* code
* @param code code
* @return WxOAuth2AccessToken
* @author admin
* @since 2024/4/8 14:47
@@ -132,8 +141,7 @@ public class WxOauthService {
/**
* 获取微信用户ID
*
* @param token
* code
* @param token code
* @return WxOAuth2AccessToken
* @author admin
* @since 2024/4/8 14:47
@@ -152,8 +160,7 @@ public class WxOauthService {
/**
* 获取微信用户ID
*
* @param token
* WxOAuth2AccessToken
* @param token WxOAuth2AccessToken
* @return WxOAuth2UserInfo
* @author admin
* @since 2024/4/8 14:47

View File

@@ -16,10 +16,9 @@ spring:
# druid数据源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
# 配置MySQL的驱动程序类
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
driverClassName: com.mysql.cj.jdbc.Driver
# 数据库连接地址(以MySql为例)
url: jdbc:p6spy:mysql://122.51.20.105:3306/play-with?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true
url: jdbc:mysql://122.51.20.105:3306/play-with?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true
# 数据库对应的用户名
username: root
# 数据库对应的密码

View File

@@ -21,6 +21,8 @@ mybatis-plus:
logic-not-delete-value: 0
# xml文件路径classpath* 代表所有模块的resources目录 classpath 不加星号代表当前模块下的resources目录
mapper-locations: classpath*:mapper/**/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
wx:
mp:

View File

@@ -2,7 +2,7 @@
<contextName>logback</contextName>
<!-- name的值是变量的名称value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后可以使“${}”来使用变量。 -->
<property name="log.path" value="./log"/>
<property name="log.path" value="./logs"/>
<property name="version" value="1.0"/>
<!-- 彩色日志 -->
@@ -12,9 +12,9 @@
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 - 包含关联ID -->
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr([%X{correlationId:--}]){yellow} %clr([%X{tenantKey:--}]){blue} %clr([%X{userId:--}]){green} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
@@ -32,15 +32,15 @@
<!-- detail info 文件保存 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/detail.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/detail/detail-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<maxFileSize>100MB</maxFileSize>
<!-- </timeBasedFileNamingAndTriggeringPolicy>-->
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{MM/dd/yyyy HH:mm:ss} %-5level [%thread] [%X{correlationId:--}] [%X{tenantKey:--}] [%X{userId:--}] %logger{16} - %msg%n</pattern>
<pattern>%d{MM/dd/yyyy HH:mm:ss} %-5level [%thread]%logger{16} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
</appender>
@@ -51,15 +51,15 @@
<file>${log.path}/error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{correlationId:--}] [%X{tenantKey:--}] [%X{userId:--}] %-5level %logger{50} - %msg%n</pattern>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<maxFileSize>100MB</maxFileSize>
<!-- </timeBasedFileNamingAndTriggeringPolicy>-->
<!--日志文件保留天数-->
<maxHistory>10</maxHistory>
</rollingPolicy>
@@ -77,17 +77,6 @@
<appender-ref ref="ERROR_FILE"/>
</root>
<!-- Set all application loggers to DEBUG -->
<logger name="com.starry" level="debug"/>
<logger name="com.ctrod" level="info"/>
<!-- Spring framework debug logging for requests -->
<logger name="org.springframework.web.servlet.DispatcherServlet" level="debug"/>
<logger name="org.springframework.security" level="debug"/>
<!-- Database query logging -->
<logger name="org.hibernate.SQL" level="debug"/>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace"/>
<logger name="com.baomidou.mybatisplus" level="debug"/>
<logger name="com.starry" level="info"/>
</configuration>

View File

@@ -1,21 +0,0 @@
#3.2.1以上使用modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2