forked from github/cool-admin-java
feat: 邮箱配置管理+邮箱验证码修改密码
- 新增 BaseSysEmailConfigEntity 邮箱配置实体及CRUD - 新增 EmailSendService 邮件发送服务(动态SMTP) - 新增 sendEmailCode/updatePasswordByEmail 接口 - App修改密码改用邮箱验证码(原短信验证码保留) - 邮箱配置支持多条,仅一条可设为当前使用 - 新增测试邮件发送接口 - menu.json 新增邮箱配置菜单 - pom.xml 新增 spring-boot-starter-mail 依赖
This commit is contained in:
@@ -71,6 +71,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<!-- springframework end -->
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.cool.modules.base.controller.admin.sys;
|
||||
|
||||
import static com.cool.modules.base.entity.sys.table.BaseSysEmailConfigEntityTableDef.BASE_SYS_EMAIL_CONFIG_ENTITY;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.cool.core.annotation.CoolRestController;
|
||||
import com.cool.core.base.BaseController;
|
||||
import com.cool.core.exception.CoolPreconditions;
|
||||
import com.cool.core.request.R;
|
||||
import com.cool.modules.base.entity.sys.BaseSysEmailConfigEntity;
|
||||
import com.cool.modules.base.service.sys.BaseSysEmailConfigService;
|
||||
import com.cool.modules.base.service.sys.EmailSendService;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
|
||||
@Tag(name = "邮箱配置管理", description = "邮箱配置管理")
|
||||
@CoolRestController(api = {"add", "delete", "update", "page", "info"}, cname = "emailConfig")
|
||||
@RequiredArgsConstructor
|
||||
public class AdminBaseSysEmailConfigController extends BaseController<BaseSysEmailConfigService, BaseSysEmailConfigEntity> {
|
||||
|
||||
private final EmailSendService emailSendService;
|
||||
|
||||
@Override
|
||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
||||
setPageOption(createOp().fieldEq(BASE_SYS_EMAIL_CONFIG_ENTITY.ENABLED)
|
||||
.keyWordLikeFields(BASE_SYS_EMAIL_CONFIG_ENTITY.EMAIL, BASE_SYS_EMAIL_CONFIG_ENTITY.REMARK));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkPermission(String action) {
|
||||
}
|
||||
|
||||
@Operation(summary = "设为当前使用")
|
||||
@PostMapping("/setActive")
|
||||
public R setActive(@RequestAttribute JSONObject requestParams) {
|
||||
Long id = requestParams.getLong("id");
|
||||
CoolPreconditions.checkEmpty(id, "id不能为空");
|
||||
|
||||
BaseSysEmailConfigEntity entity = service.getById(id);
|
||||
CoolPreconditions.checkEmpty(entity, "邮箱配置不存在");
|
||||
CoolPreconditions.check(ObjUtil.equals(entity.getEnabled(), 0), "该邮箱配置已禁用,无法设为使用");
|
||||
|
||||
List<BaseSysEmailConfigEntity> activeList = service.list(
|
||||
QueryWrapper.create().eq(BaseSysEmailConfigEntity::getIsActive, 1));
|
||||
for (BaseSysEmailConfigEntity active : activeList) {
|
||||
active.setIsActive(0);
|
||||
active.updateById();
|
||||
}
|
||||
|
||||
entity.setIsActive(1);
|
||||
entity.updateById();
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "发送测试邮件")
|
||||
@PostMapping("/test")
|
||||
public R test(@RequestAttribute JSONObject requestParams) {
|
||||
Long id = requestParams.getLong("id");
|
||||
CoolPreconditions.checkEmpty(id, "id不能为空");
|
||||
|
||||
BaseSysEmailConfigEntity entity = service.getById(id);
|
||||
CoolPreconditions.checkEmpty(entity, "邮箱配置不存在");
|
||||
|
||||
emailSendService.sendTestMail(entity);
|
||||
|
||||
return R.okMsg("测试邮件发送成功");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.cool.modules.base.entity.sys;
|
||||
|
||||
import com.cool.core.base.BaseEntity;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import com.cool.core.annotation.ColumnDefine;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(value = "base_sys_email_config", comment = "邮箱配置")
|
||||
public class BaseSysEmailConfigEntity extends BaseEntity<BaseSysEmailConfigEntity> {
|
||||
|
||||
@ColumnDefine(comment = "邮箱地址", notNull = true)
|
||||
private String email;
|
||||
|
||||
@ColumnDefine(comment = "SMTP主机", notNull = true)
|
||||
private String host;
|
||||
|
||||
@ColumnDefine(comment = "SMTP端口", notNull = true)
|
||||
private Integer port;
|
||||
|
||||
@ColumnDefine(comment = "用户名", notNull = true)
|
||||
private String username;
|
||||
|
||||
@ColumnDefine(comment = "密码/授权码", notNull = true)
|
||||
private String password;
|
||||
|
||||
@ColumnDefine(comment = "是否启用SSL", defaultValue = "1")
|
||||
private Integer sslEnable;
|
||||
|
||||
@ColumnDefine(comment = "是否启用 0-禁用 1-启用", defaultValue = "1")
|
||||
private Integer enabled;
|
||||
|
||||
@ColumnDefine(comment = "是否为当前使用 0-否 1-是", defaultValue = "0")
|
||||
private Integer isActive;
|
||||
|
||||
@ColumnDefine(comment = "备注")
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cool.modules.base.mapper.sys;
|
||||
|
||||
import com.cool.modules.base.entity.sys.BaseSysEmailConfigEntity;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
|
||||
public interface BaseSysEmailConfigMapper extends BaseMapper<BaseSysEmailConfigEntity> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.cool.modules.base.service.sys;
|
||||
|
||||
import com.cool.core.base.BaseService;
|
||||
import com.cool.modules.base.entity.sys.BaseSysEmailConfigEntity;
|
||||
|
||||
public interface BaseSysEmailConfigService extends BaseService<BaseSysEmailConfigEntity> {
|
||||
|
||||
BaseSysEmailConfigEntity getActiveConfig();
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.cool.modules.base.service.sys;
|
||||
|
||||
import com.cool.modules.base.entity.sys.BaseSysEmailConfigEntity;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class EmailSendService {
|
||||
|
||||
private final BaseSysEmailConfigService emailConfigService;
|
||||
|
||||
public void sendCode(String toEmail, String code) {
|
||||
BaseSysEmailConfigEntity config = emailConfigService.getActiveConfig();
|
||||
if (config == null) {
|
||||
throw new RuntimeException("未配置可用的邮箱服务,请在系统管理中配置邮箱");
|
||||
}
|
||||
|
||||
JavaMailSender mailSender = buildMailSender(config);
|
||||
|
||||
try {
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
|
||||
helper.setFrom(config.getEmail());
|
||||
helper.setTo(toEmail);
|
||||
helper.setSubject("验证码");
|
||||
helper.setText("<div style=\"padding:20px;font-family:sans-serif;\">"
|
||||
+ "<h2>验证码</h2>"
|
||||
+ "<p>您的验证码为:<strong style=\"font-size:24px;color:#14b8a6;\">" + code + "</strong></p>"
|
||||
+ "<p style=\"color:#999;font-size:12px;\">验证码10分钟内有效,请勿泄露给他人。</p>"
|
||||
+ "</div>", true);
|
||||
mailSender.send(message);
|
||||
log.info("验证码邮件发送成功: to={}", toEmail);
|
||||
} catch (Exception e) {
|
||||
log.error("验证码邮件发送失败: to={}, error={}", toEmail, e.getMessage());
|
||||
throw new RuntimeException("邮件发送失败,请检查邮箱配置");
|
||||
}
|
||||
}
|
||||
|
||||
public void sendTestMail(BaseSysEmailConfigEntity config) {
|
||||
JavaMailSender mailSender = buildMailSender(config);
|
||||
|
||||
try {
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
|
||||
helper.setFrom(config.getEmail());
|
||||
helper.setTo(config.getEmail());
|
||||
helper.setSubject("测试邮件");
|
||||
helper.setText("<div style=\"padding:20px;font-family:sans-serif;\">"
|
||||
+ "<h2>测试邮件</h2>"
|
||||
+ "<p>这是一封测试邮件,如果您收到了说明邮箱配置正确。</p>"
|
||||
+ "<p style=\"color:#999;font-size:12px;\">发送时间:" + java.time.LocalDateTime.now() + "</p>"
|
||||
+ "</div>", true);
|
||||
mailSender.send(message);
|
||||
log.info("测试邮件发送成功: to={}", config.getEmail());
|
||||
} catch (Exception e) {
|
||||
log.error("测试邮件发送失败: to={}, error={}", config.getEmail(), e.getMessage());
|
||||
throw new RuntimeException("邮件发送失败,请检查邮箱配置:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private JavaMailSender buildMailSender(BaseSysEmailConfigEntity config) {
|
||||
JavaMailSenderImpl sender = new JavaMailSenderImpl();
|
||||
sender.setHost(config.getHost());
|
||||
sender.setPort(config.getPort());
|
||||
sender.setUsername(config.getUsername());
|
||||
sender.setPassword(config.getPassword());
|
||||
sender.setDefaultEncoding("UTF-8");
|
||||
|
||||
java.util.Properties props = sender.getJavaMailProperties();
|
||||
props.put("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
if (config.getSslEnable() != null && config.getSslEnable() == 1) {
|
||||
props.put("mail.smtp.ssl.enable", "true");
|
||||
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||
} else {
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
}
|
||||
props.put("mail.smtp.timeout", "5000");
|
||||
props.put("mail.smtp.connectiontimeout", "5000");
|
||||
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.cool.modules.base.service.sys.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.cool.core.base.BaseServiceImpl;
|
||||
import com.cool.core.exception.CoolPreconditions;
|
||||
import com.cool.modules.base.entity.sys.BaseSysEmailConfigEntity;
|
||||
import com.cool.modules.base.mapper.sys.BaseSysEmailConfigMapper;
|
||||
import com.cool.modules.base.service.sys.BaseSysEmailConfigService;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BaseSysEmailConfigServiceImpl extends BaseServiceImpl<BaseSysEmailConfigMapper, BaseSysEmailConfigEntity>
|
||||
implements BaseSysEmailConfigService {
|
||||
|
||||
@Override
|
||||
public BaseSysEmailConfigEntity getActiveConfig() {
|
||||
return getOne(QueryWrapper.create()
|
||||
.eq(BaseSysEmailConfigEntity::getIsActive, 1)
|
||||
.eq(BaseSysEmailConfigEntity::getEnabled, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyAfter(cn.hutool.json.JSONObject requestParams, BaseSysEmailConfigEntity entity, com.cool.core.base.ModifyEnum type) {
|
||||
if (type == com.cool.core.base.ModifyEnum.ADD || type == com.cool.core.base.ModifyEnum.UPDATE) {
|
||||
if (ObjUtil.isNotEmpty(entity.getIsActive()) && entity.getIsActive() == 1) {
|
||||
CoolPreconditions.check(entity.getId() == null && type == com.cool.core.base.ModifyEnum.UPDATE,
|
||||
"新增时无法设置活跃状态");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.cool.core.annotation.CoolRestController;
|
||||
import com.cool.core.request.R;
|
||||
import com.cool.core.util.CoolSecurityUtil;
|
||||
import com.cool.core.util.EntityUtils;
|
||||
import com.cool.modules.base.service.sys.EmailSendService;
|
||||
import com.cool.modules.user.entity.UserInfoEntity;
|
||||
import com.cool.modules.user.service.UserInfoService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -20,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
public class AppUserInfoController {
|
||||
|
||||
private final UserInfoService userInfoService;
|
||||
private final EmailSendService emailSendService;
|
||||
|
||||
@Operation(summary = "用户个人信息", description = "获得App、小程序或者其他应用的用户个人信息")
|
||||
@GetMapping("/person")
|
||||
@@ -42,6 +44,14 @@ public class AppUserInfoController {
|
||||
);
|
||||
}
|
||||
|
||||
@Operation(summary = "发送邮箱验证码")
|
||||
@PostMapping("/sendEmailCode")
|
||||
public R sendEmailCode() {
|
||||
Long userId = CoolSecurityUtil.getCurrentUserId();
|
||||
userInfoService.sendEmailCode(userId, emailSendService);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户密码")
|
||||
@PostMapping("/updatePassword")
|
||||
public R updatePassword(
|
||||
@@ -49,7 +59,7 @@ public class AppUserInfoController {
|
||||
) {
|
||||
String password = requestParams.get("password", String.class);
|
||||
String code = requestParams.get("code", String.class);
|
||||
userInfoService.updatePassword(CoolSecurityUtil.getCurrentUserId(), password, code);
|
||||
userInfoService.updatePasswordByEmail(CoolSecurityUtil.getCurrentUserId(), password, code);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@@ -85,4 +95,12 @@ public class AppUserInfoController {
|
||||
userInfoService.bindUsername(CoolSecurityUtil.getCurrentUserId(), username);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "修改邮箱")
|
||||
@PostMapping("/updateEmail")
|
||||
public R updateEmail(@RequestAttribute JSONObject requestParams) {
|
||||
String email = requestParams.getStr("email");
|
||||
userInfoService.updateEmail(CoolSecurityUtil.getCurrentUserId(), email);
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,28 @@
|
||||
package com.cool.modules.user.service;
|
||||
|
||||
import com.cool.core.base.BaseService;
|
||||
import com.cool.modules.base.service.sys.EmailSendService;
|
||||
import com.cool.modules.user.entity.UserInfoEntity;
|
||||
|
||||
public interface UserInfoService extends BaseService<UserInfoEntity> {
|
||||
/**
|
||||
* 用户个人信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
UserInfoEntity person(Long userId);
|
||||
|
||||
/**
|
||||
* 更新用户密码
|
||||
*/
|
||||
void updatePassword(Long userId, String password, String code);
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
void sendEmailCode(Long userId, EmailSendService emailSendService);
|
||||
|
||||
void updatePasswordByEmail(Long userId, String password, String code);
|
||||
|
||||
void logoff(Long currentUserId);
|
||||
|
||||
/**
|
||||
* 绑定手机号
|
||||
*/
|
||||
void bindPhone(Long currentUserId, String phone, String code);
|
||||
|
||||
/**
|
||||
* 绑定邮箱
|
||||
*/
|
||||
void bindEmail(Long currentUserId, String email);
|
||||
|
||||
/**
|
||||
* 绑定用户名
|
||||
*/
|
||||
void bindUsername(Long currentUserId, String username);
|
||||
|
||||
/**
|
||||
* 注销(管理端)
|
||||
*/
|
||||
void adminLogoff(Long userId);
|
||||
|
||||
/**
|
||||
* 删除前校验:必须已注销
|
||||
*/
|
||||
void checkLogoffBeforeDelete(Long userId);
|
||||
|
||||
String resetPassword(Long userId);
|
||||
@@ -51,4 +30,6 @@ public interface UserInfoService extends BaseService<UserInfoEntity> {
|
||||
void checkEmailUnique(String email, Long excludeId);
|
||||
|
||||
void checkUsernameUnique(String username, Long excludeId);
|
||||
|
||||
void updateEmail(Long currentUserId, String email);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@ package com.cool.modules.user.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.cool.core.base.BaseServiceImpl;
|
||||
import com.cool.core.cache.CoolCache;
|
||||
import com.cool.core.exception.CoolPreconditions;
|
||||
import com.cool.modules.base.service.sys.EmailSendService;
|
||||
import com.cool.modules.user.entity.UserInfoEntity;
|
||||
import com.cool.modules.user.mapper.UserInfoMapper;
|
||||
import com.cool.modules.user.service.UserInfoService;
|
||||
@@ -20,6 +23,9 @@ public class UserInfoServiceImpl extends BaseServiceImpl<UserInfoMapper, UserInf
|
||||
UserInfoService {
|
||||
|
||||
private final UserSmsUtil userSmsUtil;
|
||||
private final CoolCache coolCache;
|
||||
|
||||
private static final String EMAIL_CODE_CACHE_PREFIX = "email_code:";
|
||||
|
||||
@Override
|
||||
public UserInfoEntity person(Long userId) {
|
||||
@@ -36,6 +42,36 @@ public class UserInfoServiceImpl extends BaseServiceImpl<UserInfoMapper, UserInf
|
||||
info.updateById();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendEmailCode(Long userId, EmailSendService emailSendService) {
|
||||
UserInfoEntity info = getById(userId);
|
||||
CoolPreconditions.checkEmpty(info, "用户不存在");
|
||||
CoolPreconditions.check(StrUtil.isEmpty(info.getEmail()), "请先设置邮箱");
|
||||
|
||||
String code = RandomUtil.randomNumbers(6);
|
||||
String cacheKey = EMAIL_CODE_CACHE_PREFIX + userId;
|
||||
|
||||
coolCache.set(cacheKey, code, 600);
|
||||
|
||||
emailSendService.sendCode(info.getEmail(), code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePasswordByEmail(Long userId, String password, String code) {
|
||||
UserInfoEntity info = getById(userId);
|
||||
CoolPreconditions.checkEmpty(info, "用户不存在");
|
||||
|
||||
String cacheKey = EMAIL_CODE_CACHE_PREFIX + userId;
|
||||
Object cachedCode = coolCache.get(cacheKey);
|
||||
CoolPreconditions.check(ObjUtil.isEmpty(cachedCode), "验证码已过期,请重新获取");
|
||||
CoolPreconditions.check(!ObjUtil.equals(String.valueOf(cachedCode), code), "验证码错误");
|
||||
|
||||
coolCache.del(cacheKey);
|
||||
|
||||
info.setPassword(MD5.create().digestHex(password));
|
||||
info.updateById();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logoff(Long userId) {
|
||||
UserInfoEntity info = new UserInfoEntity();
|
||||
@@ -128,4 +164,13 @@ public class UserInfoServiceImpl extends BaseServiceImpl<UserInfoMapper, UserInf
|
||||
.ne(UserInfoEntity::getId, excludeId));
|
||||
CoolPreconditions.check(ObjUtil.isNotEmpty(existing), "该用户名已被其他用户使用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmail(Long userId, String email) {
|
||||
UserInfoEntity info = getById(userId);
|
||||
CoolPreconditions.checkEmpty(info, "用户不存在");
|
||||
checkEmailUnique(email, userId);
|
||||
info.setEmail(email);
|
||||
info.updateById();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,6 +364,80 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "邮箱配置",
|
||||
"router": null,
|
||||
"perms": null,
|
||||
"type": 0,
|
||||
"icon": "icon-message",
|
||||
"orderNum": 4,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": [
|
||||
{
|
||||
"name": "邮箱列表",
|
||||
"router": "/sys/email-config",
|
||||
"perms": null,
|
||||
"type": 1,
|
||||
"icon": "icon-message",
|
||||
"orderNum": 0,
|
||||
"viewPath": "cool/modules/base/views/email-config.vue",
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": [
|
||||
{
|
||||
"name": "新增",
|
||||
"router": null,
|
||||
"perms": "base:sys:emailConfig:add",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"name": "修改",
|
||||
"router": null,
|
||||
"perms": "base:sys:emailConfig:info,base:sys:emailConfig:update",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"name": "删除",
|
||||
"router": null,
|
||||
"perms": "base:sys:emailConfig:delete",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
},
|
||||
{
|
||||
"name": "查看",
|
||||
"router": null,
|
||||
"perms": "base:sys:emailConfig:page,base:sys:emailConfig:list,base:sys:emailConfig:info",
|
||||
"type": 2,
|
||||
"icon": null,
|
||||
"orderNum": 0,
|
||||
"viewPath": null,
|
||||
"keepAlive": true,
|
||||
"isShow": true,
|
||||
"childMenus": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "监控管理",
|
||||
"router": null,
|
||||
|
||||
Reference in New Issue
Block a user