fix:1.仅限企业Email查询配额信息2.SSl/非SSL邮箱兼容

This commit is contained in:
nieziyan 2023-11-24 17:21:41 +08:00
parent dbff5a719b
commit 00b2036e6e
18 changed files with 283 additions and 52 deletions

View File

@ -125,4 +125,5 @@ public class SymbolConstant {
public static final String LINE = "\n";
public static final String AT = "@";
}

View File

@ -188,6 +188,38 @@ public class EmailServiceManager {
}
}
/*
* 测试收件邮箱账号是否可以正常使用(开启了SSL安全验证的邮箱)
* */
public boolean canReceiveSSL(){
Integer port = email.getPort();
String username = email.getUsername();
String password = email.getPassword();
String host = email.getEmailServerAddress();
Properties props = new Properties();
props.put("mail.store.protocol","imap");
props.put("mail.imap.host", host);
props.put("mail.imap.port", port);
props.put("mail.imap.auth", "true");
props.put("mail.imap.ssl.enable", "true");
// props.put("mail.imap.starttls.enable", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try(Store store = session.getStore()) {
store.connect(host, username, password);
return store.isConnected();
} catch (Exception e) {
log.error("收件邮箱服务SSL[Host:{}, Port:{}, Username:{}]连接异常: {}",host, port, username, e.getMessage());
return false;
}
}
/*
* 测试发件邮箱账号是否可以正常使用
* */
@ -201,7 +233,6 @@ public class EmailServiceManager {
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
@ -218,6 +249,38 @@ public class EmailServiceManager {
}
}
/*
* 测试发件邮箱账号是否可以正常使用(开启了SSL安全验证的邮箱)
* */
public boolean canSendSSL(){
Integer port = email.getPort();
String username = email.getUsername();
String password = email.getPassword();
String host = email.getEmailServerAddress();
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
// props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try (Transport transport = session.getTransport()){
transport.connect(host, username, password);
return true;
} catch (Exception e) {
log.error("发件邮箱服务SSL[Host:{}, Port:{}, Username:{}]连接异常: {}",host, port, username, e.getMessage());
return false;
}
}
/**
* 发送邮件 单发
*/

View File

@ -15,16 +15,18 @@ public class EmailUtil {
manager.init(email);
Integer emilType = email.getEmilType();
SysMailType emailType = SysMailType.valueOf(emilType);
// 根据邮箱账号类型(收件邮箱/发件邮箱)进行判断
// 邮箱是否开启了SSL不确定
if (ObjectUtil.isNotNull(emailType)){
switch (emailType){
case RECEIVE_EMAIL:
return manager.canReceive();
return manager.canReceive() || manager.canReceiveSSL();
case SEND_EMAIL:
return manager.canSend();
default:
break;
return manager.canSend() || manager.canSendSSL();
}
}
return false;
// 如果emailType(收件/发件)不确定 直接测试能否收件/发件
return manager.canReceive() || manager.canReceiveSSL()
|| manager.canSend() || manager.canSendSSL();
}
}

View File

@ -393,8 +393,7 @@ public class FTPUtil {
* */
public List<String> removeFiles(List<String> paths){
List<String> failList = new ArrayList<>();
if (CollUtil.isEmpty(paths))
return failList;
if (CollUtil.isEmpty(paths)) return failList;
// 连接FTP服务
final FTPClient ftpClient = this.LoginFTP();
for (String path : paths) {
@ -402,14 +401,15 @@ public class FTPUtil {
if (StrUtil.isBlank(path)) continue;
boolean success = ftpClient.deleteFile(path);
if (!success) failList.add(path);
} catch (IOException e) {
} catch (Exception e) {
failList.add(path);
e.printStackTrace();
log.error("FTPUtil.removeFiles()删除文件[{}]失败: {}", path, e.getMessage());
}
}
// 关闭FTP连接
try {
if (ObjectUtil.isNotNull(ftpClient)) ftpClient.disconnect();
if (ObjectUtil.isNotNull(ftpClient))
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -61,6 +61,12 @@ public class SysEmail implements Serializable {
@TableField(value = "enabled")
private Integer enabled;
/**
* 是否企业邮箱0-不是1-
*/
@TableField(value = "is_qiye")
private Integer isQiye;
/**
* 创建日期
*/

View File

@ -0,0 +1,12 @@
package org.jeecg.modules.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum Qiye {
IS(1), NOT(0);
private final int value;
}

View File

@ -27,8 +27,6 @@ public class DatabaseStatusManager {
private long sleepTime;
private RedisUtil redisUtil;
private ISysDatabaseService databaseService;
private DbStatusThread(){
@ -48,8 +46,7 @@ public class DatabaseStatusManager {
}
private void init(){
sleepTime = 5 * 1000; // 睡眠时间30min
redisUtil = SpringContextUtils.getBean(RedisUtil.class);
sleepTime = 30 * 60 * 1000; // 睡眠时间30min
databaseService = SpringContextUtils.getBean(ISysDatabaseService.class);
}
}

View File

@ -49,7 +49,7 @@ public class EmailStatusManager {
}
private void init(){
sleepTime = 5 * 1000; // 睡眠时间30min
sleepTime = 30 * 60 * 1000; // 睡眠时间30min
emailService = SpringContextUtils.getBean(ISysEmailService.class);
}
}

View File

@ -5,4 +5,6 @@ package org.jeecg.modules.qiyeEmail.api;
* */
public interface AccountAPI {
String ACCOUNTINFO = "/api/gw/qiye/mailaccount/getMailAccountInfo";
String DOMAINS = "/api/open/org/getOrg";
}

View File

@ -13,11 +13,11 @@ public class InstanceSDK {
public static QiyeOpenPlatSDK getInstance() {
// 获取nacos armd.yaml配置文件中企业邮箱的相关配置信息
Environment env = SpringContextUtils.getBean(Environment.class);
String appId = env.getProperty("qiyeEmail.appId");
String orgOpenId = env.getProperty("qiyeEmail.orgOpenId");
String authCode = env.getProperty("qiyeEmail.authCode");
String urlPrefix = env.getProperty("qiyeEmail.urlPrefix");
Property property = Property.getInstance();
String appId = property.getAppId();
String orgOpenId = property.getOrgOpenId();
String authCode = property.getAuthCode();
String urlPrefix = property.getUrlPrefix();
// 使用配置信息初始化配置类
QiyeOpenPlatSDKConfig qiyeOpenPlatSDKConfig = QiyeOpenPlatSDKConfig.builder()
//应用ID

View File

@ -0,0 +1,33 @@
package org.jeecg.modules.qiyeEmail.base;
import lombok.Getter;
import org.jeecg.common.util.SpringContextUtils;
import org.springframework.core.env.Environment;
@Getter
public class Property {
private String appId;
private String orgOpenId;
private String authCode;
private String urlPrefix;
private Property(){
Environment env = SpringContextUtils.getBean(Environment.class);
appId = env.getProperty("qiyeEmail.appId");
orgOpenId = env.getProperty("qiyeEmail.orgOpenId");
authCode = env.getProperty("qiyeEmail.authCode");
urlPrefix = env.getProperty("qiyeEmail.urlPrefix");
/*appId = "qy20231114144636B85B";
orgOpenId = "9c96b0ec1e6be89a";
authCode = "O1eSXJwU";
urlPrefix = "https://api.qiye.163.com";*/
}
public static Property getInstance(){
return new Property();
}
}

View File

@ -5,7 +5,13 @@ import lombok.Data;
@Data
public class RParam {
private String domain;
// 获取账号配额信息 相关参数
private String domain; // 必须
private String account_name;
private String account_name; // 必须
// 获取企业邮箱域名列表 相关参数
private String orgOpenId; // 必须
private Boolean showAliasDomain; // 必须
}

View File

@ -0,0 +1,27 @@
package org.jeecg.modules.qiyeEmail.base.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class Domain {
private String domain;
private String domainOpenId;
private Integer enableAccessAddr;
private Integer visibleInAddr;
private Boolean alias;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private Boolean deleted;
}

View File

@ -0,0 +1,29 @@
package org.jeecg.modules.qiyeEmail.base.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Data
public class Domains {
/*private Integer enableAccessAddr;
private Integer visibleInAddr;
private String orgOpenId;
private String orgName;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private Boolean deleted;*/
private List<Domain> domainList;
}

View File

@ -6,35 +6,62 @@ import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import com.netease.qiye.qiyeopenplatform.sdk.QiyeOpenPlatSDK;
import com.netease.qiye.qiyeopenplatform.sdk.dto.Q;
import com.netease.qiye.qiyeopenplatform.sdk.dto.R;
import org.jeecg.modules.qiyeEmail.api.AccountAPI;
import org.jeecg.modules.qiyeEmail.base.InstanceSDK;
import org.jeecg.modules.qiyeEmail.base.Property;
import org.jeecg.modules.qiyeEmail.base.RParam;
import org.jeecg.modules.qiyeEmail.base.dto.AccountInfo;
import org.jeecg.modules.qiyeEmail.base.dto.Domain;
import org.jeecg.modules.qiyeEmail.base.dto.Domains;
import org.jeecg.modules.qiyeEmail.base.dto.ResponseText;
import springfox.bean.validators.plugins.schema.MinMaxAnnotationPlugin;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Account {
public static AccountInfo getMailAccountInfo(RParam rParam) {
// 获取已登录的SDK实例
QiyeOpenPlatSDK platSDK = InstanceSDK.getInstance();
// 设置请求参数
Q reqParam = Q.init(rParam);
// 使用SDK实例调用指定API 拿到请求结果
R result = platSDK.commonInvoke(reqParam, AccountAPI.ACCOUNTINFO);
// 反序列化Json为对象
String responseText = result.getResponseText();
AccountInfo accountInfo = new AccountInfo();
try {
// 获取已登录的SDK实例
QiyeOpenPlatSDK platSDK = InstanceSDK.getInstance();
// 设置请求参数
Q reqParam = Q.init(rParam);
// 使用SDK实例调用指定API 拿到请求结果
R<?> result = platSDK.commonInvoke(reqParam, AccountAPI.ACCOUNTINFO);
// 反序列化Json为对象
String responseText = result.getResponseText();
ObjectMapper objectMapper = new ObjectMapper();
ResponseText response = objectMapper.readValue(responseText, ResponseText.class);
accountInfo = BeanUtil.mapToBean(response.getCon(), AccountInfo.class, CopyOptions.create());
return accountInfo;
} catch (Exception e) {
e.printStackTrace();
return accountInfo;
}
}
/*
* 获取所有企业邮箱域名
* */
public static List<String> domains(){
// 获取已登录的SDK实例
QiyeOpenPlatSDK platSDK = InstanceSDK.getInstance();
// 设置请求参数
RParam rParam = new RParam();
rParam.setOrgOpenId(Property.getInstance().getOrgOpenId());
rParam.setShowAliasDomain(true);
Q reqParam = Q.init(rParam);
// 使用SDK实例调用指定API 拿到请求结果
R<Map<String, Object>> result = platSDK.commonInvoke(reqParam, AccountAPI.DOMAINS);
List<Domain> domains = BeanUtil.mapToBean(result.getData(), Domains.class, CopyOptions.create())
.getDomainList();
return domains.stream().map(Domain::getDomain).collect(Collectors.toList());
}
}

View File

@ -11,8 +11,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.constant.Prompt;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.modules.base.entity.postgre.SysEmail;
import org.jeecg.modules.base.entity.postgre.SysEmailLog;
import org.jeecg.modules.base.enums.Qiye;
import org.jeecg.modules.mapper.SysEmailLogMapper;
import org.jeecg.modules.mapper.SysEmailMapper;
import org.jeecg.modules.qiyeEmail.base.RParam;
@ -34,6 +36,8 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.jeecg.modules.base.enums.Qiye.IS;
@Service("sysEmailLogService")
public class SysEmailLogServiceImpl extends ServiceImpl<SysEmailLogMapper, SysEmailLog> implements ISysEmailLogService {
@ -76,16 +80,22 @@ public class SysEmailLogServiceImpl extends ServiceImpl<SysEmailLogMapper, SysEm
@Override
public Map<String, Object> space(String emailId) {
SysEmail sysEmail = sysEmailMapper.selectById(emailId);
Integer isQiye = sysEmail.getIsQiye();
String emailUsername = sysEmail.getUsername();
Map<String, Object> map = MapUtil.newHashMap();
if (ObjectUtil.isNull(sysEmail) || StrUtil.isBlank(emailUsername))
return map;
String[] info = StrUtil.split(emailUsername, "@");
String[] info = StrUtil.split(emailUsername, SymbolConstant.AT);
if (ArrayUtil.length(info) < 2)
return map;
String domain = info[1];
String accountName = info[0];
// 是否为网易企业邮箱账号
if (ObjectUtil.isNull(isQiye) || isQiye != IS.getValue())
return map;
RParam rParam = new RParam();
rParam.setDomain(info[1]);
rParam.setAccount_name(info[0]);
rParam.setDomain(domain);
rParam.setAccount_name(accountName);
AccountInfo mailAccountInfo = Account.getMailAccountInfo(rParam);
Integer usedQuota = mailAccountInfo.getUsedQuota();
Integer maxQuota = mailAccountInfo.getMaxQuota();

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -9,10 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.api.QueryRequest;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.constant.Prompt;
import org.jeecg.common.constant.RedisConstant;
import org.jeecg.common.constant.*;
import org.jeecg.common.email.emuns.SysMailType;
import org.jeecg.common.util.EmailUtil;
import org.jeecg.common.util.JDBCUtil;
@ -24,8 +22,10 @@ import org.jeecg.modules.base.entity.postgre.SysDatabase;
import org.jeecg.modules.base.entity.postgre.SysEmail;
import org.jeecg.modules.base.bizVo.SourceVo;
import org.jeecg.modules.base.enums.Enabled;
import org.jeecg.modules.base.enums.Qiye;
import org.jeecg.modules.entity.AlarmHistory;
import org.jeecg.modules.mapper.SysEmailMapper;
import org.jeecg.modules.qiyeEmail.service.Account;
import org.jeecg.modules.service.ISysEmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -113,11 +113,13 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
@Transactional
public Result<?> create(SysEmail sysEmail) {
String name = sysEmail.getName();
String username = sysEmail.getUsername();
LambdaQueryWrapper<SysEmail> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysEmail::getName,name);
if (CollUtil.isNotEmpty(list(wrapper)))
return Result.error("Name" + Prompt.NOT_REPEAT);
sysEmail.setIsQiye(isQiye(username));
boolean success = save(sysEmail);
if (success) {
saveOrUpdateStatus(sysEmail);
@ -133,13 +135,14 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
if (ObjectUtil.isNull(email))
return Result.error(Prompt.DATA_NOT_EXITS);
String name = sysEmail.getName();
String username = sysEmail.getUsername();
LambdaQueryWrapper<SysEmail> wrapper = new LambdaQueryWrapper<>();
if (!StrUtil.equals(name,email.getName())){
wrapper.eq(SysEmail::getName,name);
if (CollUtil.isNotEmpty(list(wrapper)))
return Result.error("Name" + Prompt.NOT_REPEAT);
wrapper.clear();
}
sysEmail.setIsQiye(isQiye(username));
boolean success = updateById(sysEmail);
if (success) {
saveOrUpdateStatus(sysEmail);
@ -249,4 +252,16 @@ public class SysEmailServiceImpl extends ServiceImpl<SysEmailMapper, SysEmail> i
if(redisUtil.hHasKey(statusKey, emailId))
redisUtil.hdel(statusKey, emailId);
}
private Integer isQiye(String username){
if (StrUtil.isBlank(username))
return Qiye.NOT.getValue();
String[] info = StrUtil.split(username, SymbolConstant.AT);
if (ArrayUtil.length(info) < 2)
return Qiye.NOT.getValue();
String domain = info[1];
List<String> domains = Account.domains();
boolean contains = CollUtil.contains(domains, domain);
return contains ? Qiye.IS.getValue() : Qiye.NOT.getValue();
}
}

View File

@ -104,21 +104,22 @@ public class GardsSampleDataServiceImpl extends ServiceImpl<GardsSampleDataMappe
@Override
public Result<?> deleteById(Integer sampleId, boolean sampleData,
boolean rnAuto, boolean rnMan) {
String ftpRootPath = ftpUtil.getFtpRootPath();
String savePath = ftpRootPath + pathProperties.getSaveFilePath() + StrUtil.SLASH;
String logPath = ftpRootPath + pathProperties.getLogPath() + StrUtil.SLASH;
/* 删除数据库数据 */
// 过滤掉多余的表
String ORIGINAL = "ORIGINAL";String RNAUTO = "RNAUTO";String RNMAN = "RNMAN";
List<String> suitable = ListUtil.toList(ORIGINAL, RNAUTO, RNMAN);
List<OwnerDto> ownerDtos = baseMapper.containSampleId("SAMPLE_ID").stream()
.filter(owner -> CollUtil.contains(suitable, owner.getOwner()))
.collect(Collectors.toList());
String DOT = StrUtil.DOT;
// 手动控制事务
TransactionDefinition txDef = new DefaultTransactionDefinition();
TransactionStatus txStatus = transactionManager.getTransaction(txDef);
final TransactionStatus txStatus = transactionManager.getTransaction(txDef);
try {
String ftpRootPath = ftpUtil.getFtpRootPath();
String savePath = ftpRootPath + pathProperties.getSaveFilePath() + StrUtil.SLASH;
String logPath = ftpRootPath + pathProperties.getLogPath() + StrUtil.SLASH;
/* 删除数据库数据 */
// 过滤掉多余的表
String ORIGINAL = "ORIGINAL";String RNAUTO = "RNAUTO";String RNMAN = "RNMAN";
List<String> suitable = ListUtil.toList(ORIGINAL, RNAUTO, RNMAN);
List<OwnerDto> ownerDtos = baseMapper.containSampleId("SAMPLE_ID").stream()
.filter(owner -> CollUtil.contains(suitable, owner.getOwner()))
.collect(Collectors.toList());
String DOT = StrUtil.DOT;
List<String> needDel = new ArrayList<>();
if (sampleData){
// 收集所有表名