optimizer: 域名管理支持多级域名 & fix:修改子域名,输入相同子域名引起的报错。优化前端交互内容显示。

This commit is contained in:
suxiang
2024-09-21 17:48:17 +08:00
parent 930ad52b3e
commit 4d35c8ffef
8 changed files with 55 additions and 27 deletions
@@ -181,7 +181,11 @@
timestamp: new Date(),
title: '',
type: '',
status: 'published'
status: 'published',
domain: '',
jks: undefined,
keyStorePassword: '',
forceHttps: ''
},
dialogFormVisible: false,
dialogStatus: '',
@@ -201,8 +205,8 @@
{ required: false, message: '请选择文件', trigger: 'blur' }
],
filePassword: [
{ required: false, message: 'jks密码不能为空', trigger: 'blur' }
]// TODO jks密码不为空仍无法通过验证
{ required: false, message: '密码不能为空', trigger: 'blur' }
]// TODO required改为true后,密码不为空,仍不能通过
},
downloadLoading: false,
selectObj: {
@@ -253,14 +257,15 @@
this.temp.jks = param.file
},
validateDomain(rule, value, callback) {
// 只允许输入一级域名,例如:example.com
const domainPattern = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/
// 匹配多级域名,例如:sub.example.com, sub.sub.example.com
const domainPattern = /^(?:[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}$/
if (!value) {
callback(new Error('主域名不能为空'))
callback(new Error('主域名不能为空'));
} else if (!domainPattern.test(value)) {
callback(new Error('请输入正确的域名格式'))
callback(new Error('请输入正确的域名格式'));
} else {
callback()
callback();
}
},
handleChange(file) {
@@ -419,7 +419,7 @@ export default {
domain: undefined,
domainId: defaultDomainId
});
// console.log(this.temp)
console.log(this.list)
},
// 删除指定的域名映射
removeDomainMapping(index) {
@@ -436,6 +436,7 @@ export default {
let allFullDomainList = []
for (const fullDomainMapping of item.fullDomainMappings) {
item.domainMappings.push({
id: fullDomainMapping.id || '',
subdomain: fullDomainMapping.subdomain || '', // 使用 || '' 保证字段非空
domainId: fullDomainMapping.domainNameId || '',
domain: fullDomainMapping.domain || ''
@@ -582,8 +583,10 @@ export default {
open(url)
},
handleUpdate(row) {
console.log(row)
this.temp = Object.assign({}, row) // copy obj
this.resetTemp()
console.log(this.temp)
this.temp = JSON.parse(JSON.stringify(row))
console.log(this.temp)
if (row.securityGroupId === 0) {
this.temp.securityGroupId = null
}
@@ -90,6 +90,7 @@ public class PortMappingUpdateReq {
@Data
public class DomainMapping {
private Integer id;
private Integer domainId;
private String subdomain;
}
@@ -16,11 +16,32 @@ import java.util.Set;
@Mapper
public interface DomainMapper extends BaseMapper<DomainNameDO> {
default DomainNameDO checkRepeat(String domain, Set<Integer> excludeIds) {
return this.selectOne(new LambdaQueryWrapper<DomainNameDO>()
.eq(DomainNameDO::getDomain, domain)
// 查询与输入域名相关的域名列表
List<DomainNameDO> domainList = this.selectList(new LambdaQueryWrapper<DomainNameDO>()
.notIn(excludeIds != null, DomainNameDO::getId, excludeIds)
.last("limit 1")
);
// 遍历数据库中的域名,检查是否存在重复(包括子域名)
for (DomainNameDO domainNameDO : domainList) {
String existingDomain = domainNameDO.getDomain();
// 完全相等的情况
if (existingDomain.equals(domain)) {
return domainNameDO;
}
// 是子域名关系
if (isSubdomainOrEqual(existingDomain, domain)) {
return domainNameDO;
}
}
// 如果没有找到重复的,返回 null
return null;
}
// 辅助方法:判断 domain1 是否是 domain2 的子域名,或者两者相等
private boolean isSubdomainOrEqual(String domain1, String domain2) {
// 判断是否是子域名关系,例如 "proxy.asgc.fun" 是 "asgc.fun" 的子域名
return domain1.endsWith("." + domain2) || domain2.endsWith("." + domain1);
}
default void updateEnableStatus(Integer id, Integer enable, Date updateTime) {
@@ -1,20 +1,13 @@
package org.dromara.neutrinoproxy.server.dal;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.neutrinoproxy.server.dal.entity.DomainNameDO;
import org.dromara.neutrinoproxy.server.dal.entity.DomainPortMappingDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import org.dromara.neutrinoproxy.server.service.bo.FullDomainNameBO;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author: Mirac
@@ -22,11 +15,11 @@ import java.util.Set;
*/
@Mapper
public interface DomainPortMappingMapper extends BaseMapper<DomainPortMappingDO> {
default Boolean checkRepeatBySubdomain(String subdomain, Integer domainNameId, Integer portMappingId) {
default Boolean checkRepeatBySubdomain(String subdomain, Integer domainNameId, Integer id) {
return StringUtils.isEmpty(subdomain)? Boolean.FALSE : this.selectCount(new LambdaQueryWrapper<DomainPortMappingDO>()
.eq(DomainPortMappingDO::getSubdomain, subdomain)
.eq(DomainPortMappingDO::getDomainNameId, domainNameId)
.ne(portMappingId != null, DomainPortMappingDO::getPortMappingId, portMappingId)
.ne(id != null, DomainPortMappingDO::getId, id)
.last("limit 1")
).intValue() > 0;
}
@@ -245,7 +245,8 @@ public class PortMappingService implements LifecycleBean {
DomainNameDO domainNameDO = domainNameDOMap.get(item.getDomainId());
ParamCheckUtil.checkNotNull(domainNameDO, ExceptionConstant.DOMAIN_NAME_NOT_EXIST);
//检查子域名是否重复
ParamCheckUtil.checkExpression(!domainPortMappingMapper.checkRepeatBySubdomain(item.getSubdomain(), item.getDomainId(), req.getId()),
boolean b = !domainPortMappingMapper.checkRepeatBySubdomain(item.getSubdomain(), item.getDomainId(), item.getId());
ParamCheckUtil.checkExpression(b,
ExceptionConstant.SUDOMAIN_NAME_CANNOT_REPEAT);
});
}
@@ -12,6 +12,10 @@ import org.dromara.neutrinoproxy.server.constant.HttpsStatusEnum;
@Data
@Accessors(chain = true)
public class FullDomainNameBO {
/**
* 域名端口映射id
*/
private Integer id;
/**
* 端口映射id
*/
@@ -3,7 +3,7 @@
<mapper namespace="org.dromara.neutrinoproxy.server.dal.DomainMapper">
<select id="selectFullDomainNameListByPortMappingIds" resultType="org.dromara.neutrinoproxy.server.service.bo.FullDomainNameBO">
SELECT pm.id AS portMappingId, dpm.subdomain as subdomain, dn.domain AS domain, dn.id as domainNameId, dn.force_https as forceHttps
SELECT dpm.id as id, pm.id AS portMappingId, dpm.subdomain as subdomain, dn.domain AS domain, dn.id as domainNameId, dn.force_https as forceHttps
FROM domain_port_mapping dpm
LEFT JOIN port_mapping pm ON pm.id = dpm.port_mapping_id
LEFT JOIN domain_name dn ON dn.id = dpm.domain_name_id
@@ -14,14 +14,14 @@
</select>
<select id="selectFullDomainNameList"
resultType="org.dromara.neutrinoproxy.server.service.bo.FullDomainNameBO">
SELECT pm.id AS portMappingId, dpm.subdomain as subdomain, dn.domain AS domain, dn.id as domainNameId, dn.force_https as forceHttps
SELECT dpm.id as id, pm.id AS portMappingId, dpm.subdomain as subdomain, dn.domain AS domain, dn.id as domainNameId, dn.force_https as forceHttps
FROM domain_port_mapping dpm
LEFT JOIN port_mapping pm ON pm.id = dpm.port_mapping_id
LEFT JOIN domain_name dn ON dn.id = dpm.domain_name_id
</select>
<select id="selectFullDomainNameListByDomainNameIds"
resultType="org.dromara.neutrinoproxy.server.service.bo.FullDomainNameBO">
SELECT pm.id AS portMappingId, dpm.subdomain as subdomain, dn.domain AS domain, dn.id as domainNameId, dn.force_https as forceHttps
SELECT dpm.id as id, pm.id AS portMappingId, dpm.subdomain as subdomain, dn.domain AS domain, dn.id as domainNameId, dn.force_https as forceHttps
FROM domain_port_mapping dpm
LEFT JOIN port_mapping pm ON pm.id = dpm.port_mapping_id
LEFT JOIN domain_name dn ON dn.id = dpm.domain_name_id