diff --git a/dashboard/src2/components/JsiteDomainDNSRecords.vue b/dashboard/src2/components/JsiteDomainDNSRecords.vue
index 719da8d..e84a833 100644
--- a/dashboard/src2/components/JsiteDomainDNSRecords.vue
+++ b/dashboard/src2/components/JsiteDomainDNSRecords.vue
@@ -52,58 +52,83 @@
diff --git a/jcloud/api/domain_west.py b/jcloud/api/domain_west.py
index a02a700..45787d9 100644
--- a/jcloud/api/domain_west.py
+++ b/jcloud/api/domain_west.py
@@ -312,44 +312,106 @@ class WestDomain:
return self._make_request('/domain/?act=modifydns', 'POST', body_params=body_params)
def add_dns_record(self, domain: str, record_type: str,
- host: str, value: str, ttl: int = 600, level: int = 10) -> Dict[str, Any]:
+ host: str, value: str, ttl: int = 600, level: int = 10, line: str = "") -> Dict[str, Any]:
"""
添加DNS记录
Args:
domain: 域名
- record_type: 记录类型 (A, CNAME, MX, TXT等)
+ record_type: 记录类型 (A, CNAME, MX, TXT, AAAA, SRV)
host: 主机记录
value: 记录值
- ttl: TTL值
- level: 优先级(MX记录使用)
+ ttl: TTL值 (60~86400秒,默认900)
+ level: 优先级(MX记录使用,1-100,默认10)
+ line: 线路 (默认="", 电信="LTEL", 联通="LCNC", 移动="LMOB", 教育网="LEDU", 搜索引擎="LSEO")
"""
- record = {
- 'type': record_type,
+ body_params = {
+ 'act': 'adddnsrecord',
+ 'domain': domain,
'host': host,
+ 'type': record_type,
'value': value,
'ttl': ttl,
+ 'level': level,
+ 'line': line,
+ }
+ return self._make_request('/domain/', 'POST', body_params=body_params)
+
+ def modify_dns_record(self, domain: str, value: str, ttl: int = 600, level: int = 10,
+ record_id: Optional[str] = None, host: Optional[str] = None,
+ record_type: Optional[str] = None, line: str = "", old_value: Optional[str] = None) -> Dict[str, Any]:
+ """
+ 修改DNS记录
+
+ Args:
+ domain: 域名
+ value: 新的解析值
+ ttl: TTL值 (60~86400秒,默认900)
+ level: 优先级(MX记录使用,1-100,默认10)
+ record_id: 解析记录编号(优先使用)
+ host: 主机头(当record_id未提供时必填)
+ record_type: 解析类型(当record_id未提供时必填)
+ line: 线路 (默认="", 电信="LTEL", 联通="LCNC", 移动="LMOB", 教育网="LEDU", 搜索引擎="LSEO")
+ old_value: 旧解析值(可选,用于确定唯一记录)
+ """
+ body_params = {
+ 'act': 'moddnsrecord',
+ 'domain': domain,
+ 'value': value,
+ 'ttl': ttl,
+ 'level': level,
+ 'line': line,
}
- # 如果是MX记录,添加优先级
- if record_type == 'MX':
- record['level'] = level
-
- return self.modify_dns_records(domain, [record])
+ # 优先使用record_id
+ if record_id:
+ body_params['id'] = record_id
+ else:
+ # 必须提供host和type
+ if not host or not record_type:
+ return {"status": "error", "message": "当未提供记录ID时,主机头和解析类型为必填项"}
+ body_params['host'] = host
+ body_params['type'] = record_type
+
+ # 添加旧值(可选)
+ if old_value:
+ body_params['oldvalue'] = old_value
+
+ return self._make_request('/domain/', 'POST', body_params=body_params)
- def delete_dns_record(self, domain: str, record_id: str) -> Dict[str, Any]:
+ def delete_dns_record(self, domain: str, record_id: Optional[str] = None,
+ host: Optional[str] = None, record_type: Optional[str] = None,
+ value: Optional[str] = None, line: str = "") -> Dict[str, Any]:
"""
删除DNS记录
Args:
domain: 域名
- record_id: 记录ID
+ record_id: 解析记录ID(优先使用)
+ host: 主机头(当record_id未提供时必填)
+ record_type: 解析类型(当record_id未提供时必填)
+ value: 解析值(可选)
+ line: 线路 (默认="", 电信="LTEL", 联通="LCNC", 移动="LMOB", 教育网="LEDU", 搜索引擎="LSEO")
"""
body_params = {
+ 'act': 'deldnsrecord',
'domain': domain,
- 'record_id': record_id,
+ 'line': line,
}
- return self._make_request('/domain/?act=deletedns', 'POST', body_params=body_params)
+
+ # 优先使用record_id
+ if record_id:
+ body_params['id'] = record_id
+ else:
+ # 必须提供host和type
+ if not host or not record_type:
+ return {"status": "error", "message": "当未提供记录ID时,主机头和解析类型为必填项"}
+ body_params['host'] = host
+ body_params['type'] = record_type
+ if value:
+ body_params['value'] = value
+
+ return self._make_request('/domain/', 'POST', body_params=body_params)
def transfer_domain(self, domain: str, auth_code: str) -> Dict[str, Any]:
"""
@@ -822,7 +884,7 @@ def get_west_domain_dns_records(**data):
@jingrow.whitelist()
def west_domain_modify_dns(**data):
- """修改域名DNS记录"""
+ """修改域名DNS记录(批量修改,兼容旧版本)"""
client = get_west_client()
if not client:
return {"status": "error", "message": "API客户端初始化失败"}
@@ -835,23 +897,80 @@ def west_domain_modify_dns(**data):
if not records:
return {"status": "error", "message": "缺少DNS记录参数"}
- # 处理记录数据,确保MX记录有正确的优先级字段
- processed_records = []
+ # 逐个修改记录
+ results = []
for record in records:
- processed_record = {
- 'type': record.get('type'),
- 'host': record.get('host'),
- 'value': record.get('value'),
- 'ttl': record.get('ttl', 600)
- }
+ record_type = record.get('type')
+ host = record.get('host')
+ value = record.get('value')
+ ttl = record.get('ttl', 600)
+ level = record.get('level', 10)
+ line = record.get('line', '')
+ record_id = record.get('record_id')
+ old_value = record.get('old_value')
- # 如果是MX记录,添加优先级
- if record.get('type') == 'MX':
- processed_record['level'] = record.get('level', 10)
-
- processed_records.append(processed_record)
+ # 验证必要参数
+ if not value:
+ results.append({"status": "error", "message": "缺少解析值"})
+ continue
+
+ # 如果没有提供record_id,则必须提供host和record_type
+ if not record_id and (not host or not record_type):
+ results.append({"status": "error", "message": "当未提供记录ID时,主机头和解析类型为必填项"})
+ continue
+
+ # 验证TTL值
+ if ttl < 60 or ttl > 86400:
+ results.append({"status": "error", "message": "TTL值必须在60~86400秒之间"})
+ continue
+
+ # 验证优先级
+ if level < 1 or level > 100:
+ results.append({"status": "error", "message": "优先级必须在1~100之间"})
+ continue
+
+ # 验证记录类型
+ if record_type:
+ valid_types = ['A', 'CNAME', 'MX', 'TXT', 'AAAA', 'SRV']
+ if record_type not in valid_types:
+ results.append({"status": "error", "message": f"不支持的记录类型: {record_type}"})
+ continue
+
+ # 调用单个记录修改API
+ response = client.modify_dns_record(
+ domain, value, ttl, level, record_id, host, record_type, line, old_value
+ )
+
+ if response.get("status") == "error":
+ results.append(response)
+ elif response.get("result") != 200:
+ error_msg = response.get('msg', response.get('message', '未知错误'))
+ results.append({"status": "error", "message": f"修改DNS记录失败: {error_msg}"})
+ else:
+ results.append({
+ "status": "success",
+ "message": "DNS记录修改成功",
+ "data": {
+ "domain": domain,
+ "value": value,
+ "ttl": ttl,
+ "level": level,
+ "record_id": record_id,
+ "host": host,
+ "record_type": record_type,
+ "line": line
+ }
+ })
- return client.modify_dns_records(domain, processed_records)
+ # 返回批量操作结果
+ success_count = sum(1 for r in results if r.get("status") == "success")
+ error_count = len(results) - success_count
+
+ return {
+ "status": "success" if error_count == 0 else "partial_success",
+ "message": f"批量修改完成,成功: {success_count},失败: {error_count}",
+ "results": results
+ }
@jingrow.whitelist()
@@ -867,11 +986,54 @@ def west_domain_add_dns_record(**data):
value = data.get('value')
ttl = data.get('ttl', 600)
level = data.get('level', 10)
+ line = data.get('line', '')
if not all([domain, record_type, host, value]):
return {"status": "error", "message": "缺少必要参数"}
- return client.add_dns_record(domain, record_type, host, value, ttl, level)
+ # 验证记录类型
+ valid_types = ['A', 'CNAME', 'MX', 'TXT', 'AAAA', 'SRV']
+ if record_type not in valid_types:
+ return {"status": "error", "message": f"不支持的记录类型: {record_type},支持的类型: {', '.join(valid_types)}"}
+
+ # 验证TTL值
+ if ttl < 60 or ttl > 86400:
+ return {"status": "error", "message": "TTL值必须在60~86400秒之间"}
+
+ # 验证优先级
+ if level < 1 or level > 100:
+ return {"status": "error", "message": "优先级必须在1~100之间"}
+
+ response = client.add_dns_record(domain, record_type, host, value, ttl, level, line)
+
+ if response.get("status") == "error":
+ return response
+
+ try:
+ # 检查响应格式
+ if response.get("result") != 200:
+ error_msg = response.get('msg', response.get('message', '未知错误'))
+ return {"status": "error", "message": f"添加DNS记录失败: {error_msg}"}
+
+ # 返回成功结果
+ return {
+ "status": "success",
+ "message": "DNS记录添加成功",
+ "data": {
+ "id": response.get("data", {}).get("id"),
+ "domain": domain,
+ "host": host,
+ "type": record_type,
+ "value": value,
+ "ttl": ttl,
+ "level": level,
+ "line": line
+ }
+ }
+
+ except Exception as e:
+ jingrow.log_error("添加DNS记录响应解析失败", error=str(e))
+ return {"status": "error", "message": "添加DNS记录响应解析失败"}
@jingrow.whitelist()
@@ -883,13 +1045,52 @@ def west_domain_delete_dns_record(**data):
domain = data.get('domain')
record_id = data.get('record_id')
+ host = data.get('host')
+ record_type = data.get('record_type')
+ value = data.get('value')
+ line = data.get('line', '')
if not domain:
return {"status": "error", "message": "缺少域名参数"}
- if not record_id:
- return {"status": "error", "message": "缺少记录ID参数"}
- return client.delete_dns_record(domain, record_id)
+ # 如果没有提供record_id,则必须提供host和record_type
+ if not record_id and (not host or not record_type):
+ return {"status": "error", "message": "当未提供记录ID时,主机头和解析类型为必填项"}
+
+ # 验证记录类型
+ if record_type:
+ valid_types = ['A', 'CNAME', 'MX', 'TXT', 'AAAA', 'SRV']
+ if record_type not in valid_types:
+ return {"status": "error", "message": f"不支持的记录类型: {record_type},支持的类型: {', '.join(valid_types)}"}
+
+ response = client.delete_dns_record(domain, record_id, host, record_type, value, line)
+
+ if response.get("status") == "error":
+ return response
+
+ try:
+ # 检查响应格式
+ if response.get("result") != 200:
+ error_msg = response.get('msg', response.get('message', '未知错误'))
+ return {"status": "error", "message": f"删除DNS记录失败: {error_msg}"}
+
+ # 返回成功结果
+ return {
+ "status": "success",
+ "message": "DNS记录删除成功",
+ "data": {
+ "domain": domain,
+ "record_id": record_id,
+ "host": host,
+ "record_type": record_type,
+ "value": value,
+ "line": line
+ }
+ }
+
+ except Exception as e:
+ jingrow.log_error("删除DNS记录响应解析失败", error=str(e))
+ return {"status": "error", "message": "删除DNS记录响应解析失败"}
@jingrow.whitelist()
@@ -1955,3 +2156,146 @@ def west_upload_real_name_files(**data):
return {"status": "error", "message": "实名资料上传响应解析失败"}
+@jingrow.whitelist()
+def west_domain_modify_dns_record(**data):
+ """修改DNS记录"""
+ client = get_west_client()
+ if not client:
+ return {"status": "error", "message": "API客户端初始化失败"}
+
+ domain = data.get('domain')
+ value = data.get('value')
+ ttl = data.get('ttl', 600)
+ level = data.get('level', 10)
+ record_id = data.get('record_id')
+ host = data.get('host')
+ record_type = data.get('record_type')
+ line = data.get('line', '')
+ old_value = data.get('old_value')
+
+ if not domain:
+ return {"status": "error", "message": "缺少域名参数"}
+ if not value:
+ return {"status": "error", "message": "缺少新的解析值"}
+
+ # 验证TTL值
+ if ttl < 60 or ttl > 86400:
+ return {"status": "error", "message": "TTL值必须在60~86400秒之间"}
+
+ # 验证优先级
+ if level < 1 or level > 100:
+ return {"status": "error", "message": "优先级必须在1~100之间"}
+
+ # 如果没有提供record_id,则必须提供host和record_type
+ if not record_id and (not host or not record_type):
+ return {"status": "error", "message": "当未提供记录ID时,主机头和解析类型为必填项"}
+
+ # 验证记录类型
+ if record_type:
+ valid_types = ['A', 'CNAME', 'MX', 'TXT', 'AAAA', 'SRV']
+ if record_type not in valid_types:
+ return {"status": "error", "message": f"不支持的记录类型: {record_type},支持的类型: {', '.join(valid_types)}"}
+
+ response = client.modify_dns_record(
+ domain, value, ttl, level, record_id, host, record_type, line, old_value
+ )
+
+ if response.get("status") == "error":
+ return response
+
+ try:
+ # 检查响应格式
+ if response.get("result") != 200:
+ error_msg = response.get('msg', response.get('message', '未知错误'))
+ return {"status": "error", "message": f"修改DNS记录失败: {error_msg}"}
+
+ # 返回成功结果
+ return {
+ "status": "success",
+ "message": "DNS记录修改成功",
+ "data": {
+ "domain": domain,
+ "value": value,
+ "ttl": ttl,
+ "level": level,
+ "record_id": record_id,
+ "host": host,
+ "record_type": record_type,
+ "line": line
+ }
+ }
+
+ except Exception as e:
+ jingrow.log_error("修改DNS记录响应解析失败", error=str(e))
+ return {"status": "error", "message": "修改DNS记录响应解析失败"}
+
+
+@jingrow.whitelist()
+def test_dns_record_management():
+ """测试DNS记录管理功能"""
+ try:
+ # 测试参数
+ test_domain = "test.com"
+ test_host = "www"
+ test_value = "127.0.0.1"
+ test_record_type = "A"
+
+ client = get_west_client()
+ if not client:
+ return {"status": "error", "message": "API客户端初始化失败"}
+
+ # 测试1: 添加DNS记录
+ jingrow.log_error("DNS测试", "开始测试添加DNS记录")
+ add_result = client.add_dns_record(
+ domain=test_domain,
+ record_type=test_record_type,
+ host=test_host,
+ value=test_value,
+ ttl=900,
+ level=10,
+ line=""
+ )
+ jingrow.log_error("DNS测试", f"添加DNS记录结果: {add_result}")
+
+ # 测试2: 获取DNS记录列表
+ jingrow.log_error("DNS测试", "开始测试获取DNS记录列表")
+ list_result = client.get_dns_records_paginated(test_domain, 20, 1)
+ jingrow.log_error("DNS测试", f"获取DNS记录列表结果: {list_result}")
+
+ # 测试3: 修改DNS记录(如果添加成功)
+ if add_result.get("result") == 200:
+ record_id = add_result.get("data", {}).get("id")
+ if record_id:
+ jingrow.log_error("DNS测试", f"开始测试修改DNS记录,记录ID: {record_id}")
+ modify_result = client.modify_dns_record(
+ domain=test_domain,
+ value="127.0.0.2",
+ ttl=600,
+ level=10,
+ record_id=record_id,
+ line=""
+ )
+ jingrow.log_error("DNS测试", f"修改DNS记录结果: {modify_result}")
+
+ # 测试4: 删除DNS记录
+ jingrow.log_error("DNS测试", "开始测试删除DNS记录")
+ delete_result = client.delete_dns_record(
+ domain=test_domain,
+ record_id=record_id
+ )
+ jingrow.log_error("DNS测试", f"删除DNS记录结果: {delete_result}")
+
+ return {
+ "status": "success",
+ "message": "DNS记录管理功能测试完成",
+ "data": {
+ "add_result": add_result,
+ "list_result": list_result
+ }
+ }
+
+ except Exception as e:
+ jingrow.log_error("DNS测试异常", str(e))
+ return {"status": "error", "message": f"DNS记录管理功能测试失败: {str(e)}"}
+
+