Commit 9e2b3f66ade564783f9e357fd044b5a96a78e0e7
1 parent
97a1d2ed
feat(shop): 添加邮件发送功能并优化产品关联逻辑
- 新增邮件发送相关配置和代码,实现邮件发送功能 - 优化产品关联逻辑,解决空指针异常问题 - 更新数据库连接配置
Showing
11 changed files
with
253 additions
and
23 deletions
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
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 | ||
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<ProductMapper, ProductDO> 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<ProductMapper, ProductDO> 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(); | ... | ... |