Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java # yudao-module-mp/src/main/java/cn/iocoder/yudao/module/mp/service/handler/user/SubscribeHandler.java
This commit is contained in:
@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
|
||||
/**
|
||||
* 异步任务 Configuration
|
||||
@@ -21,13 +22,20 @@ public class YudaoAsyncAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (!(bean instanceof ThreadPoolTaskExecutor)) {
|
||||
return bean;
|
||||
// 处理 ThreadPoolTaskExecutor
|
||||
if (bean instanceof ThreadPoolTaskExecutor) {
|
||||
ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) bean;
|
||||
executor.setTaskDecorator(TtlRunnable::get);
|
||||
return executor;
|
||||
}
|
||||
// 修改提交的任务,接入 TransmittableThreadLocal
|
||||
ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) bean;
|
||||
executor.setTaskDecorator(TtlRunnable::get);
|
||||
return executor;
|
||||
// 处理 SimpleAsyncTaskExecutor
|
||||
// 参考 https://t.zsxq.com/CBoks 增加
|
||||
if (bean instanceof SimpleAsyncTaskExecutor) {
|
||||
SimpleAsyncTaskExecutor executor = (SimpleAsyncTaskExecutor) bean;
|
||||
executor.setTaskDecorator(TtlRunnable::get);
|
||||
return executor;
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -42,6 +42,7 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||
default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {
|
||||
// 特殊:不分页,直接查询全部
|
||||
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
|
||||
MyBatisUtils.addOrder(queryWrapper, sortingFields);
|
||||
List<T> list = selectList(queryWrapper);
|
||||
return new PageResult<>(list, (long) list.size());
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.framework.mybatis.core.util;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.func.Func1;
|
||||
import cn.hutool.core.lang.func.LambdaUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.SortingField;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.enums.DbTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
@@ -20,7 +22,6 @@ import net.sf.jsqlparser.schema.Table;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* MyBatis 工具类
|
||||
@@ -37,15 +38,27 @@ public class MyBatisUtils {
|
||||
// 页码 + 数量
|
||||
Page<T> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
|
||||
// 排序字段
|
||||
if (!CollectionUtil.isEmpty(sortingFields)) {
|
||||
page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder())
|
||||
? OrderItem.asc(StrUtil.toUnderlineCase(sortingField.getField()))
|
||||
: OrderItem.desc(StrUtil.toUnderlineCase(sortingField.getField())))
|
||||
.collect(Collectors.toList()));
|
||||
if (CollUtil.isNotEmpty(sortingFields)) {
|
||||
for (SortingField sortingField : sortingFields) {
|
||||
page.addOrder(new OrderItem().setAsc(SortingField.ORDER_ASC.equals(sortingField.getOrder()))
|
||||
.setColumn(StrUtil.toUnderlineCase(sortingField.getField())));
|
||||
}
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
public static <T> void addOrder(Wrapper<T> wrapper, Collection<SortingField> sortingFields) {
|
||||
if (CollUtil.isEmpty(sortingFields)) {
|
||||
return;
|
||||
}
|
||||
QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
|
||||
for (SortingField sortingField : sortingFields) {
|
||||
query.orderBy(true,
|
||||
SortingField.ORDER_ASC.equals(sortingField.getOrder()),
|
||||
StrUtil.toUnderlineCase(sortingField.getField()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将拦截器添加到链中
|
||||
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
||||
|
@@ -126,8 +126,10 @@ public class SecurityFrameworkUtils {
|
||||
|
||||
// 额外设置到 request 中,用于 ApiAccessLogFilter 可以获取到用户编号;
|
||||
// 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
|
||||
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
|
||||
WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
|
||||
if (request != null) {
|
||||
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
|
||||
WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
|
||||
}
|
||||
}
|
||||
|
||||
private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
|
||||
|
@@ -10,7 +10,9 @@
|
||||
<if test="endTime != null">
|
||||
AND in_time < #{endTime}
|
||||
</if>
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getRequiredTenantId()}
|
||||
<if test="@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId() != null">
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId()}
|
||||
</if>
|
||||
AND deleted = 0) -
|
||||
(SELECT IFNULL(SUM(total_price), 0)
|
||||
FROM erp_purchase_return
|
||||
@@ -18,7 +20,9 @@
|
||||
<if test="endTime != null">
|
||||
AND return_time < #{endTime}
|
||||
</if>
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getRequiredTenantId()}
|
||||
<if test="@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId() != null">
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId()}
|
||||
</if>
|
||||
AND deleted = 0)
|
||||
</select>
|
||||
|
||||
|
@@ -10,7 +10,9 @@
|
||||
<if test="endTime != null">
|
||||
AND out_time < #{endTime}
|
||||
</if>
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getRequiredTenantId()}
|
||||
<if test="@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId() != null">
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId()}
|
||||
</if>
|
||||
AND deleted = 0) -
|
||||
(SELECT IFNULL(SUM(total_price), 0)
|
||||
FROM erp_sale_return
|
||||
@@ -18,7 +20,9 @@
|
||||
<if test="endTime != null">
|
||||
AND return_time < #{endTime}
|
||||
</if>
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getRequiredTenantId()}
|
||||
<if test="@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId() != null">
|
||||
AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId()}
|
||||
</if>
|
||||
AND deleted = 0)
|
||||
</select>
|
||||
|
||||
|
@@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.infra.framework.file.core.utils;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tika.Tika;
|
||||
import org.apache.tika.mime.MimeTypeException;
|
||||
import org.apache.tika.mime.MimeTypes;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -86,8 +85,8 @@ public class FileTypeUtils {
|
||||
response.setContentType(contentType);
|
||||
// 针对 video 的特殊处理,解决视频地址在移动端播放的兼容性问题
|
||||
if (StrUtil.containsIgnoreCase(contentType, "video")) {
|
||||
response.setHeader("Content-Length", String.valueOf(content.length - 1));
|
||||
response.setHeader("Content-Range", String.valueOf(content.length - 1));
|
||||
response.setHeader("Content-Length", String.valueOf(content.length));
|
||||
response.setHeader("Content-Range", "bytes 0-" + (content.length - 1) + "/" + content.length);
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
}
|
||||
// 输出附件
|
||||
|
@@ -86,7 +86,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
|
||||
activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
|
||||
}
|
||||
// 查找是否有其它活动,选择了该产品
|
||||
List<CombinationActivityDO> matchActivityList = filterList(activityList, activity -> ObjectUtil.equal(activity.getId(), spuId));
|
||||
List<CombinationActivityDO> matchActivityList = filterList(activityList, activity -> ObjectUtil.equal(activity.getSpuId(), spuId));
|
||||
if (CollUtil.isNotEmpty(matchActivityList)) {
|
||||
throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
|
@@ -76,8 +76,8 @@
|
||||
<select id="selectListByPayTimeBetweenAndGroupByMonth"
|
||||
resultType="cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeOrderTrendRespVO">
|
||||
SELECT DATE_FORMAT(pay_time, '%Y-%m') AS date,
|
||||
COUNT(1) AS orderPayCount,
|
||||
SUM(pay_price) AS orderPayPrice
|
||||
COUNT(1) AS order_pay_count,
|
||||
SUM(pay_price) AS order_pay_price
|
||||
FROM trade_order
|
||||
WHERE pay_status = TRUE
|
||||
AND create_time BETWEEN #{beginTime} AND #{endTime}
|
||||
@@ -95,8 +95,8 @@
|
||||
|
||||
<select id="selectPaySummaryByPayStatusAndPayTimeBetween"
|
||||
resultType="cn.iocoder.yudao.module.statistics.controller.admin.trade.vo.TradeOrderSummaryRespVO">
|
||||
SELECT IFNULL(SUM(pay_price), 0) AS orderPayPrice,
|
||||
COUNT(1) AS orderPayCount
|
||||
SELECT IFNULL(SUM(pay_price), 0) AS order_pay_price,
|
||||
COUNT(1) AS order_pay_count
|
||||
FROM trade_order
|
||||
WHERE pay_status = #{payStatus}
|
||||
AND pay_time BETWEEN #{beginTime} AND #{endTime}
|
||||
|
@@ -39,7 +39,8 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_NOT_FOUND = new ErrorCode(1_011_000_034, "交易订单更新支付订单退款状态失败,原因:退款单不存在");
|
||||
ErrorCode ORDER_UPDATE_PAID_ORDER_REFUNDED_FAIL_REFUND_STATUS_NOT_SUCCESS = new ErrorCode(1_011_000_035, "交易订单更新支付订单退款状态失败,原因:退款单状态不是【退款成功】");
|
||||
ErrorCode ORDER_PICK_UP_FAIL_NOT_VERIFY_USER = new ErrorCode(1_011_000_036, "交易订单自提失败,原因:你没有核销该门店订单的权限");
|
||||
ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_037, "交易订单创建失败,原因:用户积分不足");
|
||||
ErrorCode ORDER_PICK_UP_FAIL_COMBINATION_NOT_SUCCESS = new ErrorCode(1_011_000_037, "交易订单自提失败,原因:商品拼团记录不是【成功】状态");
|
||||
ErrorCode ORDER_CREATE_FAIL_INSUFFICIENT_USER_POINTS = new ErrorCode(1_011_000_038, "交易订单创建失败,原因:用户积分不足");
|
||||
|
||||
// ========== After Sale 模块 1-011-000-100 ==========
|
||||
ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在");
|
||||
|
@@ -141,9 +141,8 @@ public class AfterSaleController {
|
||||
public CommonResult<Boolean> updateAfterSaleRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) {
|
||||
log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO);
|
||||
if (StrUtil.startWithAny(notifyReqDTO.getMerchantRefundId(), "order-")) {
|
||||
tradeOrderUpdateService.updatePaidOrderRefunded(
|
||||
Long.parseLong(notifyReqDTO.getMerchantRefundId()),
|
||||
notifyReqDTO.getPayRefundId());
|
||||
Long orderId = Long.parseLong(StrUtil.subAfter(notifyReqDTO.getMerchantRefundId(), "order-", true));
|
||||
tradeOrderUpdateService.updatePaidOrderRefunded(orderId, notifyReqDTO.getPayRefundId());
|
||||
} else {
|
||||
afterSaleService.updateAfterSaleRefunded(
|
||||
Long.parseLong(notifyReqDTO.getMerchantRefundId()),
|
||||
|
@@ -25,6 +25,9 @@ import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
|
||||
@@ -121,6 +124,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||
public SocialClientApi socialClientApi;
|
||||
@Resource
|
||||
public PayRefundApi payRefundApi;
|
||||
@Resource
|
||||
private CombinationRecordApi combinationRecordApi;
|
||||
|
||||
@Resource
|
||||
private TradeOrderProperties tradeOrderProperties;
|
||||
@@ -775,6 +780,14 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||
if (ObjUtil.notEqual(DeliveryTypeEnum.PICK_UP.getType(), order.getDeliveryType())) {
|
||||
throw exception(ORDER_RECEIVE_FAIL_DELIVERY_TYPE_NOT_PICK_UP);
|
||||
}
|
||||
// 情况一:如果是拼团订单,则校验拼团是否成功
|
||||
if (TradeOrderTypeEnum.isCombination(order.getType())) {
|
||||
CombinationRecordRespDTO combinationRecord = combinationRecordApi.getCombinationRecordByOrderId(
|
||||
order.getUserId(), order.getId());
|
||||
if (!CombinationRecordStatusEnum.isSuccess(combinationRecord.getStatus())) {
|
||||
throw exception(ORDER_PICK_UP_FAIL_COMBINATION_NOT_SUCCESS);
|
||||
}
|
||||
}
|
||||
DeliveryPickUpStoreDO deliveryPickUpStore = pickUpStoreService.getDeliveryPickUpStore(order.getPickUpStoreId());
|
||||
if (deliveryPickUpStore == null
|
||||
|| !CollUtil.contains(deliveryPickUpStore.getVerifyUserIds(), userId)) {
|
||||
|
@@ -1,10 +1,13 @@
|
||||
package cn.iocoder.yudao.module.mp.service.handler.user;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder;
|
||||
import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService;
|
||||
import cn.iocoder.yudao.module.mp.service.user.MpUserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.error.WxMpErrorMsgEnum;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
@@ -13,7 +16,6 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -40,6 +42,13 @@ public class SubscribeHandler implements WxMpMessageHandler {
|
||||
wxMpUser = weixinService.getUserService().userInfo(wxMessage.getFromUser());
|
||||
} catch (WxErrorException e) {
|
||||
log.error("[handle][粉丝({})] 获取粉丝信息失败!", wxMessage.getFromUser(), e);
|
||||
// 特殊情况(个人账号,无接口权限):https://t.zsxq.com/cLFq5
|
||||
if (ObjUtil.equal(e.getError().getErrorCode(), WxMpErrorMsgEnum.CODE_48001)) {
|
||||
wxMpUser = new WxMpUser();
|
||||
wxMpUser.setOpenId(wxMessage.getFromUser());
|
||||
wxMpUser.setSubscribe(true);
|
||||
wxMpUser.setSubscribeTime(System.currentTimeMillis() / 1000L);
|
||||
}
|
||||
}
|
||||
|
||||
// 第二步,保存粉丝信息
|
||||
|
@@ -38,7 +38,8 @@ public class SocialUserController {
|
||||
@PostMapping("/bind")
|
||||
@Operation(summary = "社交绑定,使用 code 授权码")
|
||||
public CommonResult<Boolean> socialBind(@RequestBody @Valid SocialUserBindReqVO reqVO) {
|
||||
socialUserService.bindSocialUser(BeanUtils.toBean(reqVO, SocialUserBindReqDTO.class)
|
||||
socialUserService.bindSocialUser(new SocialUserBindReqDTO().setSocialType(reqVO.getType())
|
||||
.setCode(reqVO.getCode()).setState(reqVO.getState())
|
||||
.setUserId(getLoginUserId()).setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
Reference in New Issue
Block a user