diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/cors/CorsResponseHeaderFilter.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/cors/CorsResponseHeaderFilter.java deleted file mode 100644 index 041a98529..000000000 --- a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/cors/CorsResponseHeaderFilter.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.gateway.filter.cors; - -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter; -import org.springframework.core.Ordered; -import org.springframework.http.HttpHeaders; -import org.springframework.stereotype.Component; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * 解决 Spring Cloud Gateway 2.x 跨域时,出现重复 Origin 的 BUG - * - * 参考文档: - * - * @author 芋道源码 - */ -@Component -public class CorsResponseHeaderFilter implements GlobalFilter, Ordered { - - @Override - public int getOrder() { - // 指定此过滤器位于 NettyWriteResponseFilter 之后 - // 即待处理完响应体后接着处理响应头 - return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1; - } - - @Override - public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - return chain.filter(exchange).then(Mono.defer(() -> { - // https://gitee.com/zhijiantianya/yudao-cloud/pulls/177/ - List keysToModify = exchange.getResponse().getHeaders().entrySet().stream() - .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1)) - .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) - || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS))) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - keysToModify.forEach(key->{ - List values = exchange.getResponse().getHeaders().get(key); - if (values != null && !values.isEmpty()) { - exchange.getResponse().getHeaders().put(key, Collections.singletonList(values.get(0))); - } - }); - return chain.filter(exchange); - })); - } - -} diff --git a/yudao-gateway/src/main/resources/application.yaml b/yudao-gateway/src/main/resources/application.yaml index 4b61df602..44527af5f 100644 --- a/yudao-gateway/src/main/resources/application.yaml +++ b/yudao-gateway/src/main/resources/application.yaml @@ -194,6 +194,8 @@ spring: - RewritePath=/admin-api/iot/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs x-forwarded: prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀 + default-filters: # 全局过滤器,对应 GatewayFilterDefinition 数组 + - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin server: port: 48080 diff --git a/yudao-module-ai/yudao-module-ai-server/pom.xml b/yudao-module-ai/yudao-module-ai-server/pom.xml index 25549c538..890635a5e 100644 --- a/yudao-module-ai/yudao-module-ai-server/pom.xml +++ b/yudao-module-ai/yudao-module-ai-server/pom.xml @@ -240,6 +240,12 @@ org.springframework.ai spring-ai-starter-mcp-server-webmvc ${spring-ai.version} + + + io.swagger.core.v3 + swagger-annotations-jakarta + + diff --git a/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java b/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java index 6a2209121..f57fe1898 100644 --- a/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java +++ b/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java @@ -65,11 +65,17 @@ public class TradeOrderLogAspect { public void doAfterReturning(JoinPoint joinPoint, TradeOrderLog orderLog) { try { // 1.1 操作用户 - Integer userType = getUserType(); - Long userId = getUserId(); + Integer userType = USER_TYPE.get(); + if (ObjectUtil.isNull(userType)) { + userType = getUserType(); + } + Long userId = USER_ID.get(); + if (ObjectUtil.isNull(userId)) { + userId = getUserId(); + } // 1.2 订单信息 Long orderId = ORDER_ID.get(); - if (orderId == null) { // 如果未设置,只有注解,说明不需要记录日志 + if (ObjectUtil.isNull(orderId)) { // 如果未设置,只有注解,说明不需要记录日志 return; } Integer beforeStatus = BEFORE_STATUS.get(); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java index dbc010ded..f5be00c73 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.system.api.mail.dto; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; import lombok.Data; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotNull; + +import java.io.File; import java.util.List; import java.util.Map; @@ -34,7 +36,6 @@ public class MailSendSingleToUserReqDTO { */ private List<@Email String> bccMails; - /** * 邮件模板编号 */ @@ -44,5 +45,9 @@ public class MailSendSingleToUserReqDTO { * 邮件模板参数 */ private Map templateParams; + /** + * 附件内容 + */ + private File[] attachments; } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java index 2725aa1a6..c2fa29f74 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java @@ -3,11 +3,10 @@ package cn.iocoder.yudao.module.system.api.mail; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.system.api.mail.dto.MailSendSingleToUserReqDTO; import cn.iocoder.yudao.module.system.service.mail.MailSendService; +import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.Resource; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @RestController // 提供 RESTful API 接口,给 Feign 调用 @@ -21,14 +20,14 @@ public class MailSendApiImpl implements MailSendApi { public CommonResult sendSingleMailToAdmin(MailSendSingleToUserReqDTO reqDTO) { return success(mailSendService.sendSingleMailToAdmin(reqDTO.getUserId(), reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(), - reqDTO.getTemplateCode(), reqDTO.getTemplateParams())); + reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments())); } @Override public CommonResult sendSingleMailToMember(MailSendSingleToUserReqDTO reqDTO) { return success(mailSendService.sendSingleMailToMember(reqDTO.getUserId(), reqDTO.getToMails(), reqDTO.getCcMails(), reqDTO.getBccMails(), - reqDTO.getTemplateCode(), reqDTO.getTemplateParams())); + reqDTO.getTemplateCode(), reqDTO.getTemplateParams(), reqDTO.getAttachments())); } } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index bff92147b..cad3add1b 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; @@ -32,6 +33,7 @@ public class AdminUserApiImpl implements AdminUserApi { private DeptService deptService; @Override + @DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致无法查询用户。类似:https://github.com/YunaiV/ruoyi-vue-pro/issues/1051 public CommonResult getUser(Long id) { AdminUserDO user = userService.getUser(id); return success(BeanUtils.toBean(user, AdminUserRespDTO.class)); diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java index fe4e5dd07..4bd87fde5 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java @@ -1,12 +1,11 @@ package cn.iocoder.yudao.module.system.mq.message.mail; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - +import java.io.File; import java.util.Collection; -import java.util.List; /** * 邮箱发送消息 @@ -54,5 +53,9 @@ public class MailSendMessage { */ @NotEmpty(message = "邮件内容不能为空") private String content; + /** + * 邮件附件 + */ + private File[] attachments; } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java index 24f849a9e..7616f2c07 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java @@ -1,16 +1,13 @@ package cn.iocoder.yudao.module.system.mq.producer.mail; import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; -import javax.annotation.Resource; - +import java.io.File; import java.util.Collection; -import java.util.List; - -import static java.util.Collections.singletonList; /** * Mail 邮件相关消息的 Producer @@ -39,12 +36,13 @@ public class MailProducer { */ public void sendMailSendMessage(Long sendLogId, Collection toMails, Collection ccMails, Collection bccMails, - Long accountId, String nickname, String title, String content) { + Long accountId, String nickname, String title, String content, File[] attachments) { MailSendMessage message = new MailSendMessage() .setLogId(sendLogId) .setToMails(toMails).setCcMails(ccMails).setBccMails(bccMails) .setAccountId(accountId).setNickname(nickname) - .setTitle(title).setContent(content); + .setTitle(title).setContent(content) + .setAttachments(attachments); applicationContext.publishEvent(message); } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java index 1b600bc90..9863a4f43 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.mail; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; +import java.io.File; import java.util.Collection; import java.util.Map; @@ -27,9 +28,9 @@ public interface MailSendService { */ default Long sendSingleMailToAdmin(Long userId, Collection toMails, Collection ccMails, Collection bccMails, - String templateCode, Map templateParams) { + String templateCode, Map templateParams, File... attachments) { return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.ADMIN.getValue(), - templateCode, templateParams); + templateCode, templateParams, attachments); } /** @@ -45,9 +46,9 @@ public interface MailSendService { */ default Long sendSingleMailToMember(Long userId, Collection toMails, Collection ccMails, Collection bccMails, - String templateCode, Map templateParams) { + String templateCode, Map templateParams, File... attachments) { return sendSingleMail(toMails, ccMails, bccMails, userId, UserTypeEnum.MEMBER.getValue(), - templateCode, templateParams); + templateCode, templateParams, attachments); } /** @@ -64,7 +65,7 @@ public interface MailSendService { */ Long sendSingleMail(Collection toMails, Collection ccMails, Collection bccMails, Long userId, Integer userType, - String templateCode, Map templateParams); + String templateCode, Map templateParams, File... attachments); /** * 执行真正的邮件发送 diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java index 05e4fec47..8a728eb81 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.system.service.mail; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Validator; import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.mail.MailAccount; -import cn.hutool.extra.mail.MailUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; @@ -15,11 +13,14 @@ import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; import cn.iocoder.yudao.module.system.service.member.MemberService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.dromara.hutool.extra.mail.MailAccount; +import org.dromara.hutool.extra.mail.MailUtil; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import javax.annotation.Resource; +import java.io.File; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Map; @@ -56,7 +57,8 @@ public class MailSendServiceImpl implements MailSendService { @Override public Long sendSingleMail(Collection toMails, Collection ccMails, Collection bccMails, Long userId, Integer userType, - String templateCode, Map templateParams) { + String templateCode, Map templateParams, + File... attachments) { // 1.1 校验邮箱模版是否合法 MailTemplateDO template = validateMailTemplate(templateCode); // 1.2 校验邮箱账号是否合法 @@ -94,7 +96,7 @@ public class MailSendServiceImpl implements MailSendService { // 发送 MQ 消息,异步执行发送短信 if (isSend) { mailProducer.sendMailSendMessage(sendLogId, toMailSet, ccMailSet, bccMailSet, - account.getId(), template.getNickname(), title, content); + account.getId(), template.getNickname(), title, content, attachments); } return sendLogId; } @@ -119,11 +121,11 @@ public class MailSendServiceImpl implements MailSendService { public void doSendMail(MailSendMessage message) { // 1. 创建发送账号 MailAccountDO account = validateMailAccount(message.getAccountId()); - MailAccount mailAccount = buildMailAccount(account, message.getNickname()); + MailAccount mailAccount = buildMailAccount(account, message.getNickname()); // 2. 发送邮件 try { String messageId = MailUtil.send(mailAccount, message.getToMails(), message.getCcMails(), message.getBccMails(), - message.getTitle(), message.getContent(), true); + message.getTitle(), message.getContent(), true, message.getAttachments()); // 3. 更新结果(成功) mailLogService.updateMailSendResult(message.getLogId(), messageId, null); } catch (Exception e) { @@ -135,7 +137,7 @@ public class MailSendServiceImpl implements MailSendService { private MailAccount buildMailAccount(MailAccountDO account, String nickname) { String from = StrUtil.isNotEmpty(nickname) ? nickname + " <" + account.getMail() + ">" : account.getMail(); return new MailAccount().setFrom(from).setAuth(true) - .setUser(account.getUsername()).setPass(account.getPassword()) + .setUser(account.getUsername()).setPass(account.getPassword().toCharArray()) .setHost(account.getHost()).setPort(account.getPort()) .setSslEnable(account.getSslEnable()).setStarttlsEnable(account.getStarttlsEnable()); }