提交功能

This commit is contained in:
yyhouc 2023-07-07 18:39:32 +08:00
parent 7f618305e5
commit 50cf582bf9
12 changed files with 303 additions and 4 deletions

View File

@ -62,4 +62,9 @@ public interface CacheNames {
*/
String USER_FAIL_KEY = "blade:user::blade:fail:";
/**
* 邮箱修改密码验证码key
*/
String EMAIL_FORGET_KEY = "blade:auth::blade:email:forget:";
}

View File

@ -26,7 +26,6 @@ public interface CommonConstant {
* 默认密码
*/
String DEFAULT_PASSWORD = "123456";
/**
* 默认密码参数值
*/

View File

@ -169,5 +169,17 @@ public class DisasterInfo implements Serializable {
*/
@TableField(exist = false)
private String allocation;
/**
* 拒绝标题
*/
@TableField(exist = false)
private String refuseTitle;
/**
* 拒绝理由
*/
@TableField(exist = false)
private String refuseReason;
}

View File

@ -11,6 +11,6 @@ import org.springframework.cloud.client.SpringCloudApplication;
@SpringCloudApplication
public class VoRdmApplication {
public static void main(String[] args) {
BladeApplication.run(CommonConstant.KN_VORDM_MODULE_NAME, VoRdmApplication.class, args);
BladeApplication.run("yyhouc-"+CommonConstant.KN_VORDM_MODULE_NAME, VoRdmApplication.class, args);
}
}

View File

@ -4,16 +4,20 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.kening.vordm.entity.Administrator;
import com.kening.vordm.service.AdministratorService;
import lombok.AllArgsConstructor;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
/**
* 后台管理系统-chief管理员管理控制器
* @author liyuchen
@ -47,6 +51,7 @@ public class AdministratorController {
*/
@PostMapping("/add")
public R<Boolean> add(@RequestBody Administrator administrator){
CacheUtil.clear(USER_CACHE);
return R.status(service.saveChiefAdmin(administrator));
}
@ -57,6 +62,7 @@ public class AdministratorController {
*/
@PutMapping("/update")
public R<Boolean> update(@RequestBody Administrator administrator){
CacheUtil.clear(USER_CACHE);
return R.status(service.updateById(administrator));
}
@ -69,4 +75,26 @@ public class AdministratorController {
public R<Boolean> delete(@RequestParam String ids){
return R.status(service.deleteLogic(Func.toLongList(ids)));
}
/**
* 重置密码前发送邮件验证码
*/
@GetMapping("/sendEmailCode")
public R<Boolean> sendEmailCode(@RequestParam String email,@RequestParam String tenantId){
return R.data(service.sendEmailCode(email,tenantId));
}
/**
* 验证账号或邮箱是否存在
*/
@GetMapping("/checkAccountOrEmail")
public R<Boolean> checkAccountOrEmail(@RequestParam String email,@RequestParam String tenantId ){
return R.data(service.checkAccountOrEmail(email,tenantId));
}
/**
* 修改密码
*/
@PutMapping("/updatePassword")
public R<Boolean> updatePassword(@RequestParam String email,@RequestParam String newPassword,@RequestParam String tenantId,@RequestParam String code){
CacheUtil.clear(USER_CACHE);
return R.data(service.updatePassword(email,newPassword,tenantId,code));
}
}

View File

@ -1,5 +1,7 @@
package com.kening.vordm.controller;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@ -15,6 +17,8 @@ import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
@ -99,5 +103,30 @@ public class CrawlInfoController {
List<CrawlInfo> list = crawlInfoService.list(Wrappers.<CrawlInfo>query().lambda().eq(CrawlInfo::getDisasterId, disasterId).notIn(CrawlInfo::getType, "1","2","3","4"));
return R.data(list);
}
public static void main(String[] args) {
String key = encrypt("^RUWY6@d&%hVf5qYY9basW21KIaBmuER");
long time = System.currentTimeMillis()/1000;
System.out.println(time+"-"+encrypt((key+time)));
}
public static String encrypt(String plaintext) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plaintext.getBytes());
byte[] bytes = md.digest();
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xff);
if (hex.length() == 1) {
result.append("0");
}
result.append(hex);
}
return result.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -2,6 +2,7 @@ package com.kening.vordm.controller;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@ -337,14 +338,32 @@ public class DisasterInfoController {
private final AdministratorService administratorService;
@PostMapping("review")
public R<Boolean> review(@RequestBody DisasterInfo disasterInfo) {
//审核邮件实例化
Email email = new Email();
//查询邮箱
QueryWrapper<GuestInfo> qw = new QueryWrapper<>();
qw.apply("id = (select sponsor_id from guest_manage_disaster_ref where disaster_id = {0})", disasterInfo.getId());
GuestInfo guestInfo = guestInfoService.getOne(qw);
email.setTos(new String[]{ guestInfo.getEmail()});
//审批通过 响应状态0未审批1审批未通过2审批通过并正在响应3审批通过并且响应完成
if (disasterInfo.getRespondStatus() == 2) {
String numbering = serialNumberService.generateNumbering(disasterInfo.getDisasterType());
disasterInfo.setVordmId(numbering);
disasterInfo.setRespondTime(new Date());
email.setSubject("Your disaster response application has been approved!");
email.setText("Your disaster response application has been approved!");
}else{
email.setSubject(disasterInfo.getRefuseTitle());
email.setText(disasterInfo.getRefuseReason());
}
Boolean flag = disasterInfoService.updateById(disasterInfo);
return R.data(flag);
// Boolean flag = disasterInfoService.updateById(disasterInfo);
//保证数据在更新完后发送邮件防止数据更新失败邮件发送成功
try {
emailService.sendMimeMessage(email);
} catch (Exception e) {
return R.fail("发送失败");
}
return R.data(true);
}
private final EmailService emailService;
@ApiOperationSupport(order = 6)

View File

@ -23,4 +23,10 @@ public interface AdministratorService extends BaseService<Administrator> {
* @return
*/
boolean saveChiefAdmin(Administrator administrator);
boolean sendEmailCode(String email,String tenantId);
boolean checkAccountOrEmail(String email ,String tenantId);
boolean updatePassword(String email, String newPassword, String tenantId, String code);
}

View File

@ -16,6 +16,7 @@ public interface EmailService {
void sendMimeMessage(Email email) throws MessagingException;
void sendTemplate(Email email) throws MessagingException;
void sendTemplate(Email email,String template) throws MessagingException;
R sendUserPasswordEmail(UserVo userVo) throws MessagingException;
}

View File

@ -10,11 +10,16 @@ import com.kening.vordm.service.EmailService;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.cache.CacheNames;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.oss.MinioTemplate;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
@ -31,6 +36,8 @@ public class AdministratorServiceImpl extends BaseServiceImpl<AdministratorMappe
private final EmailService emailService;
private final BladeRedis bladeRedis;
@Value("${mail.home.link}")
private String link;
@ -94,4 +101,83 @@ public class AdministratorServiceImpl extends BaseServiceImpl<AdministratorMappe
}
return Boolean.TRUE;
}
@Override
public boolean sendEmailCode(String email ,String tenantId) {
//查询用户是否存在 条件邮箱加租户id
Administrator admin = getOne(Wrappers.<Administrator>lambdaQuery().eq(Administrator::getEmail,email).eq(Administrator::getTenantId,tenantId));
if(admin==null){
throw new RuntimeException("The email is not registered");
}
//随机生成6位数验证码
String code = String.valueOf((int)((Math.random()*9+1)*100000));
//将验证码存入redis 有效期10分钟
Duration duration = Duration.ofMinutes(10);
bladeRedis.setEx(CacheNames.EMAIL_FORGET_KEY +email,code,duration);
try {
//设置标题
String subject = "Verification code";
//设置要填充模板的参数
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("code", code);
dataMap.put("account",admin.getAccount());
dataMap.put("email",admin.getEmail());
Email emailObj = new Email();
emailObj.setSubject(subject);
emailObj.setHtmlText(true);
emailObj.setTos(new String[]{email});
emailObj.setDataMap(dataMap);
emailService.sendTemplate(emailObj, "forgotPassword");
log.info("邮件发送成功");
return true;
}catch (Exception e){
log.error("发送邮件失败:{}",e);
}
return false;
}
@Override
public boolean checkAccountOrEmail(String email,String tenantId) {
//查询用户是否存在
Administrator admin = getOne(Wrappers.<Administrator>lambdaQuery().eq(Administrator::getEmail,email).eq(Administrator::getTenantId,tenantId));
return admin!=null;
}
@Override
public boolean updatePassword(String email, String newPassword, String tenantId, String code) {
//首先根据邮箱租户id查询用户是否存在
Administrator admin = getOne(Wrappers.<Administrator>lambdaQuery().eq(Administrator::getEmail,email).eq(Administrator::getTenantId,tenantId));
if(admin==null){
throw new RuntimeException("The email is not registered");
}
//判断验证码是否为空
if(StringUtil.isBlank(code)){
throw new RuntimeException("Verification code cannot be empty");
}
//校验验证码是否正确
String codeRedis = bladeRedis.get(CacheNames.EMAIL_FORGET_KEY + email);
//如果codeRedis 验证码为空返回请发送验证码提示
if(StringUtil.isBlank(codeRedis)){
throw new RuntimeException("Please send the verification code first");
}
//将redis中的验证码设置为-100并且超时时间为50秒
bladeRedis.setEx(CacheNames.EMAIL_FORGET_KEY + email,"-100",Duration.ofSeconds(50));
//判断当前验证码是否为-100如果是-100则提示验证码已过期
if("-100".equals(codeRedis)){
throw new RuntimeException("Verification code has expired");
}
if(!code.equals(codeRedis)){
throw new RuntimeException("Verification code error");
}
//修改密码
admin.setPassword(DigestUtil.encrypt(newPassword));
if(updateById(admin)){
//删除redis中的验证码
bladeRedis.del(CacheNames.EMAIL_FORGET_KEY + email);
return true;
}
return false ;
}
}

View File

@ -52,6 +52,11 @@ public class EmailServiceImpl implements EmailService {
javaMailSender.send(buildTemplateMail(email));
}
@Override
public void sendTemplate(Email email, String template) throws MessagingException {
javaMailSender.send(buildTemplateMail(email,template));
}
@Override
public R sendUserPasswordEmail(UserVo userVo) throws MessagingException {
//通过邮箱判断当前用户是否存在
@ -97,6 +102,33 @@ public class EmailServiceImpl implements EmailService {
helper.setText(templateContent, true);
return message;
}
/**
* 构建模板邮件
* @param email
* @return
* @throws MessagingException
*/
public MimeMessage buildTemplateMail(Email email,String template) throws MessagingException {
//模板数据内容
Context context = new Context();
//插入模板数据
for (Map.Entry<String, Object> entry : email.getDataMap().entrySet()) {
context.setVariable(entry.getKey(), entry.getValue());
}
//使用的模板
String templateContent = templateEngine.process(template, context);
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//发送人
helper.setFrom(from);
//收件人
helper.setTo(email.getTos());
//主题
helper.setSubject(email.getSubject());
//发送内容
helper.setText(templateContent, true);
return message;
}
/**
* 构建邮件发送内容

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>邮件模板</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
body {
background-color: #ECECEC;
}
.container {
width: 800px;
margin: 50px auto;
}
.header {
height: 80px;
background-color: #49bcff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding-left: 30px;
}
.header h2 {
padding-top: 25px;
color: white;
}
.content {
background-color: #fff;
padding-left: 30px;
padding-bottom: 30px;
border-bottom: 1px solid #ccc;
}
.content h2 {
padding-top: 20px;
padding-bottom: 20px;
}
.content p {
padding-top: 10px;
}
.footer {
background-color: #fff;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
padding: 35px;
}
.footer p {
color: #747474;
padding-top: 10px;
}
</style>
</head>
<body>
<!--您好,感谢您的注册,这是一封验证邮件,请点击下面的链接完成注册,感谢您的支持!
<a href="#" th:href="@{http://www.baidu.com/register/{id}(id=${id})}">激活账号</a>-->
<div class="container">
<div class="content">
<h2>Hello, you are about to change your password!</h2>
<h3>Please do not disclose the verification code. His effective time is 10 minutes!</h3>
<p>Your account number<b><span th:text="${account}"></span></b></p>
<p>Your Email<b><span th:text="${email}"></span></b></p>
<p>Your verification code<b><span th:text="${code}"></span></b></p>
</div>
<div class="footer">
<p>This is system mail, please do not reply</p>
<p>Please take good care of your information to avoid misappropriation</p>
</div>
</div>
</body>
</html>