Commit 9e2b3f66ade564783f9e357fd044b5a96a78e0e7

Authored by 曾国涛
1 parent 97a1d2ed

feat(shop): 添加邮件发送功能并优化产品关联逻辑

- 新增邮件发送相关配置和代码,实现邮件发送功能
- 优化产品关联逻辑,解决空指针异常问题
- 更新数据库连接配置
admin/src/main/resources/application-test.yml
... ... @@ -57,9 +57,9 @@ spring:
57 57 testWhileIdle: true
58 58 testOnBorrow: true
59 59 testOnReturn: true
60   - password: 123456
  60 + password: canrd@2024
61 61 time-between-eviction-runs-millis: 1000
62   - url: jdbc:mysql://159.75.211.11:3306/canrd?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true
  62 + url: jdbc:mysql://39.108.227.113:3307/canrd?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true
63 63 username: root
64 64 redis:
65 65 database: 3
... ...
admin/src/main/resources/application.yml
... ... @@ -3,4 +3,4 @@ server:
3 3  
4 4 spring:
5 5 profiles:
6   - active: local
7 6 \ No newline at end of file
  7 + active: test
8 8 \ No newline at end of file
... ...
shop/pom.xml
... ... @@ -43,6 +43,10 @@
43 43 </dependency>
44 44 <dependency>
45 45 <groupId>org.springframework.boot</groupId>
  46 + <artifactId>spring-boot-starter-mail</artifactId>
  47 + </dependency>
  48 + <dependency>
  49 + <groupId>org.springframework.boot</groupId>
46 50 <artifactId>spring-boot-starter-freemarker</artifactId>
47 51 <version>3.3.5</version>
48 52 </dependency>
... ...
shop/src/main/java/com/canrd/shop/controller/EmailController.java 0 → 100644
  1 +package com.canrd.shop.controller;
  2 +
  3 +import com.canrd.shop.common.constant.ServerResult;
  4 +import com.canrd.shop.module.dto.SendTextEmailDto;
  5 +import com.canrd.shop.service.IEmailService;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.*;
  9 +
  10 +/**
  11 + * @author zgt
  12 + * @project canrd-services
  13 + * @description
  14 + * @date 2024/12/27
  15 + */
  16 +@RestController
  17 +@RequestMapping("/email")
  18 +public class EmailController {
  19 + @Autowired
  20 + private IEmailService emailService;
  21 +
  22 + /**
  23 + * 发送邮件到配置账号
  24 + * @param dto
  25 + * @return
  26 + */
  27 + @PostMapping("/send")
  28 + public ServerResult send(@Validated @RequestBody SendTextEmailDto dto){
  29 + String content ="姓名:"+ dto.getFirstName()+" " + dto.getLastName()+"\n" +"邮箱:"+ dto.getEmail()+"\n"+"消息:"+dto.getMessage();
  30 + emailService.sendTo(content);
  31 + return ServerResult.success();
  32 + }
  33 +}
... ...
shop/src/main/java/com/canrd/shop/module/dto/SendTextEmailDto.java 0 → 100644
  1 +package com.canrd.shop.module.dto;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import javax.validation.constraints.Email;
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +/**
  10 + * @author zgt
  11 + * @project canrd-services
  12 + * @description
  13 + * @date 2024/12/27
  14 + */
  15 +@Data
  16 +@AllArgsConstructor
  17 +@ToString
  18 +@NoArgsConstructor
  19 +@EqualsAndHashCode(callSuper = false)
  20 +@SuperBuilder
  21 +public class SendTextEmailDto {
  22 +
  23 + private String firstName;
  24 +
  25 + private String lastName;
  26 +
  27 + @Email
  28 + private String email;
  29 + @NotNull
  30 + private String message;
  31 +
  32 + private String subject;
  33 +
  34 +}
... ...
shop/src/main/java/com/canrd/shop/service/IEmailService.java 0 → 100644
  1 +package com.canrd.shop.service;
  2 +
  3 +import java.io.File;
  4 +import java.util.List;
  5 +
  6 +public interface IEmailService {
  7 +
  8 +
  9 +
  10 + /**
  11 + * 邮件发送
  12 + *
  13 + * @param name 发送人名称
  14 + * @param to 发送对象
  15 + * @param subject 主题
  16 + * @param content 内容
  17 + * @param isHtml 是否为html
  18 + * @param cc 抄送,多人用逗号隔开
  19 + * @param bcc 密送,多人用逗号隔开
  20 + * @param files 文件
  21 + */
  22 + void send(String name, String to, String subject, String content, Boolean isHtml, String cc, String bcc, List<File> files);
  23 +
  24 +
  25 + void sendText(String name, String to, String subject, String content);
  26 +
  27 + void sendHtml(String name, String to, String subject, String content);
  28 +
  29 + void sendTo(String content);
  30 +}
... ...
shop/src/main/java/com/canrd/shop/service/impl/EmailServiceImpl.java 0 → 100644
  1 +package com.canrd.shop.service.impl;
  2 +
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import com.canrd.shop.common.exception.BusinessException;
  5 +import com.canrd.shop.service.IEmailService;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.apache.commons.lang3.StringUtils;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.beans.factory.annotation.Value;
  10 +import org.springframework.mail.javamail.JavaMailSender;
  11 +import org.springframework.mail.javamail.MimeMessageHelper;
  12 +import org.springframework.stereotype.Service;
  13 +
  14 +import javax.mail.internet.InternetAddress;
  15 +import java.io.File;
  16 +import java.util.Date;
  17 +import java.util.List;
  18 +
  19 +/**
  20 + * @author zgt
  21 + * @project canrd-services
  22 + * @description
  23 + * @date 2024/12/27
  24 + */
  25 +@Slf4j
  26 +@Service
  27 +public class EmailServiceImpl implements IEmailService {
  28 +
  29 + @Value("${mail.to}")
  30 + private String to;
  31 +
  32 + @Autowired
  33 + private JavaMailSender javaMailSender;//注入邮件工具类
  34 +
  35 + @Value("${spring.mail.username}")
  36 + private String from;
  37 + @Override
  38 + public void send(String name, String to, String subject, String content, Boolean isHtml, String cc, String bcc, List<File> files) {
  39 +
  40 + if (StringUtils.isAnyBlank(from, to, subject, content)) {
  41 + throw new BusinessException("发送人,接收人,主题,内容均不可为空");
  42 + }
  43 + try {
  44 + //true表示支持复杂类型
  45 + MimeMessageHelper messageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(), true);
  46 + //邮件发信人
  47 + messageHelper.setFrom(new InternetAddress(name + "<" + from + ">"));
  48 + //邮件收信人
  49 + messageHelper.setTo(to.split(","));
  50 + //邮件主题
  51 + messageHelper.setSubject(subject);
  52 + //邮件内容
  53 + messageHelper.setText(content, isHtml);
  54 + //抄送
  55 + if (!StringUtils.isEmpty(cc)) {
  56 + messageHelper.setCc(cc.split(","));
  57 + }
  58 + //密送
  59 + if (!StringUtils.isEmpty(bcc)) {
  60 + messageHelper.setCc(bcc.split(","));
  61 + }
  62 + //添加邮件附件
  63 + if (CollectionUtil.isNotEmpty(files)) {
  64 + for (File file : files) {
  65 + messageHelper.addAttachment(file.getName(), file);
  66 + }
  67 + }
  68 + // 邮件发送时间
  69 + messageHelper.setSentDate(new Date());
  70 + //正式发送邮件
  71 + javaMailSender.send(messageHelper.getMimeMessage());
  72 + } catch (Exception e) {
  73 + throw new BusinessException("邮件发送失败", e);
  74 + }
  75 + }
  76 +
  77 +
  78 + @Override
  79 + public void sendText(String name, String to, String subject, String content) {
  80 + this.send(name, to, subject, content, false, null, null, null);
  81 + }
  82 +
  83 + @Override
  84 + public void sendHtml(String name, String to, String subject, String content) {
  85 + this.send(name, to, subject, content, true, null, null, null);
  86 + }
  87 +
  88 + @Override
  89 + public void sendTo(String content) {
  90 + this.send(from, to, "客户咨询", content, false, null, null, null);
  91 + }
  92 +
  93 +}
  94 +
  95 +
... ...
shop/src/main/java/com/canrd/shop/service/impl/ProductServiceImpl.java
... ... @@ -234,13 +234,31 @@ public class ProductServiceImpl extends ServiceImpl&lt;ProductMapper, ProductDO&gt; im
234 234 .collect(Collectors.toList());
235 235 List<String> collect = productCategoryRelationService.lambdaQuery()
236 236 .select(Productcategoryrelation::getProductId)
237   - .in(Productcategoryrelation::getCategoryId, cateIds)
238   - .notIn(Productcategoryrelation::getProductId,productVO.getRelatedProductIds())
  237 + .func(wrapper -> {
  238 + if (CollUtil.isEmpty(cateIds)){
  239 + wrapper.apply("1!=1");
  240 + }else {
  241 + wrapper.in(Productcategoryrelation::getCategoryId, cateIds);
  242 + }
  243 + })
  244 + .func(wrapper -> {
  245 + if (CollUtil.isEmpty(productVO.getRelatedProductIds())){
  246 + wrapper.apply("1!=1");
  247 + }else {
  248 + wrapper.notIn(Productcategoryrelation::getProductId,productVO.getRelatedProductIds());
  249 + }
  250 + })
239 251 .list().stream()
240 252 .map(Productcategoryrelation::getProductId)
241 253 .collect(Collectors.toList());
242 254 List<String> records = this.lambdaQuery()
243   - .in(ProductDO::getId, collect)
  255 + .func(wrapper -> {
  256 + if (CollUtil.isEmpty(collect)){
  257 + wrapper.apply("1!=1");
  258 + }else {
  259 + wrapper.in(ProductDO::getId, collect);
  260 + }
  261 + })
244 262 .eq(ProductDO::getIsmarketable, true)
245 263 .select(ProductDO::getId)
246 264 .page(new Page<>(1, 10 - productVO.getRelatedProductIds().size())).getRecords().stream()
... ... @@ -248,13 +266,6 @@ public class ProductServiceImpl extends ServiceImpl&lt;ProductMapper, ProductDO&gt; im
248 266 productVO.getRelatedProductIds().addAll(records);
249 267 }
250 268  
251   -// List<JournalCategoryRelation> journalCategoryRelations = journalCategoryService.lambdaQuery()
252   -// .in(JournalCategoryRelation::getCategoryId, categoryIds)
253   -// .list();
254   -// List<Long> journalIds = journalCategoryRelations.stream().map(JournalCategoryRelation::getJournalId).collect(Collectors.toList());
255   -// List<Journal> journals = journalService.lambdaQuery()
256   -// .in(Journal::getId, journalIds)
257   -// .list();
258 269 List<JournalCategoryRelation> journalCategoryRelations = null;
259 270 if (categoryIds != null && !categoryIds.isEmpty()) {
260 271 // 查询 journalCategoryRelations,仅在 categoryIds 不为空时执行
... ...
shop/src/main/resources/application-test.yml
... ... @@ -57,14 +57,14 @@ spring:
57 57 testWhileIdle: true
58 58 testOnBorrow: true
59 59 testOnReturn: true
60   - password: canrd@2024
  60 + password: 123456
61 61 time-between-eviction-runs-millis: 1000
62   - url: jdbc:mysql://39.108.227.113:3307/canrd_overseas?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true
  62 + url: jdbc:mysql://192.168.31.242:13306/canrd_overseas?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&failOverReadOnly=false&maxReconnects=10&allowMultiQueries=true&useAffectedRows=true&autoReconnectForPools=true
63 63 username: root
64 64  
65 65  
66   -logging:
67   - config: classpath:log4j2-dev.xml
  66 +#logging:
  67 +# config: classpath:log4j2-dev.xml
68 68  
69 69  
70 70 static-html:
... ...
shop/src/main/resources/application.yml
... ... @@ -8,3 +8,22 @@ spring:
8 8 throw-exception-if-no-handler-found: true
9 9 resources:
10 10 add-mappings: false
  11 + mail:
  12 + host: smtp.mxhichina.com
  13 + port: 465
  14 + username: overseas@canrd.com
  15 + password: Canrd@overseas
  16 + protocol: smtps
  17 + properties:
  18 + mail:
  19 + smtp:
  20 + auth: true
  21 + starttls:
  22 + enable: true
  23 + required: true
  24 + socketFactory:
  25 + port: 465
  26 + class: javax.net.ssl.SSLSocketFactory
  27 +
  28 +mail:
  29 + to: contact@canrd.com
... ...
shop/src/test/java/com/canrd/shop/TranslateTest.java
... ... @@ -16,12 +16,7 @@ import com.canrd.shop.module.dto.ProductCategoryDO;
16 16 import com.canrd.shop.module.dto.ProductDO;
17 17 import com.canrd.shop.module.dto.ProductFunctionDO;
18 18 import com.canrd.shop.module.dto.TicketTypeDO;
19   -import com.canrd.shop.service.ProductAttributeMapStoreService;
20   -import com.canrd.shop.service.ProductAttributeService;
21   -import com.canrd.shop.service.ProductCategoryService;
22   -import com.canrd.shop.service.ProductFunctionService;
23   -import com.canrd.shop.service.ProductService;
24   -import com.canrd.shop.service.TicketTypeService;
  19 +import com.canrd.shop.service.*;
25 20 import lombok.extern.slf4j.Slf4j;
26 21 import org.apache.commons.io.FileUtils;
27 22 import org.junit.Test;
... ... @@ -75,6 +70,14 @@ public class TranslateTest {
75 70 @Autowired
76 71 private ChatGptUtil chatGptUtil;
77 72  
  73 + @Autowired
  74 + private IEmailService emailService;
  75 +
  76 + @Test
  77 + public void translateProductAttributeMapStoreTest(){
  78 + emailService.sendText("zgt","2100047874@qq.com","test","测试一下");
  79 + return;
  80 + }
78 81 @Test
79 82 public void translateTicketTypeTest(){
80 83 List<TicketTypeDO> ticketTypeDOS = ticketTypeService.list();
... ... @@ -130,6 +133,7 @@ public class TranslateTest {
130 133 });
131 134 }
132 135  
  136 +
133 137 @Test
134 138 public void translateFunctionTest(){
135 139 List<ProductFunctionDO> productFunctionDOS = productFunctionService.list();
... ...