From 8b0c05e15733dca35408119e1639d36c6d19a744 Mon Sep 17 00:00:00 2001 From: jingrow Date: Sat, 2 Aug 2025 04:34:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=9F=9F=E5=90=8D=E6=A8=A1?= =?UTF-8?q?=E6=9D=BFapi=E7=AB=AF=E7=82=B9=E6=B5=8B=E8=AF=95=E6=88=90?= =?UTF-8?q?=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src2/components/DomainOwnerDialog.vue | 69 +++- jcloud/api/domain_west.py | 379 +++++++++++++++++- .../pagetype/domain_owner/domain_owner.json | 14 +- .../pagetype/domain_owner/domain_owner.py | 3 +- 4 files changed, 439 insertions(+), 26 deletions(-) diff --git a/dashboard/src2/components/DomainOwnerDialog.vue b/dashboard/src2/components/DomainOwnerDialog.vue index 1a238fd..226a32b 100644 --- a/dashboard/src2/components/DomainOwnerDialog.vue +++ b/dashboard/src2/components/DomainOwnerDialog.vue @@ -194,15 +194,15 @@ > - +
- +
+86 0) { @@ -331,7 +332,47 @@ export default { return; } - this.$emit('submit', this.formData); + try { + // 准备提交数据 + const submitData = { ...this.formData }; + + // 添加国家信息 + submitData.c_co = this.selectedCountry; + submitData.cocode = this.selectedCountry === 'CN' ? '+86' : ''; + + console.log('准备提交的数据:', submitData); + + // 调用API创建域名所有者(包含模板创建) + console.log('开始调用API...'); + const response = await new Promise((resolve, reject) => { + jingrow.call({ + method: 'jcloud.api.domain_west.create_domain_owner_with_template', + args: submitData, + callback: (r) => { + console.log('API调用结果:', r); + resolve(r); + }, + error: (r) => { + console.error('API调用错误:', r); + reject(r); + } + }); + }); + console.log('API调用结果:', response); + + if (response.status === 'Success') { + console.log('域名所有者创建成功:', response); + alert('域名所有者创建成功!'); + this.$emit('submit', response.data); + this.closeDialog(); + } else { + console.error('创建失败:', response); + alert(`创建失败: ${response.message}`); + } + } catch (error) { + console.error('创建域名所有者失败:', error); + alert('创建失败,请检查网络连接或联系管理员'); + } }, validateForm() { const errors = []; @@ -357,8 +398,14 @@ export default { if (!this.formData.c_pc) { errors.push('请输入邮编'); } - if (!this.formData.c_ph_num) { - errors.push('请输入联系电话'); + // 验证手机号码 + if (!this.formData.c_ph) { + errors.push('请输入手机号码'); + } + + // 企业类型验证 + if (this.formData.c_regtype === 'E' && !this.formData.c_org_m) { + errors.push('企业类型必须填写单位名称'); } if (!this.formData.c_em) { errors.push('请输入电子邮箱'); @@ -383,7 +430,8 @@ export default { c_dt_m: '', c_adr_m: '', c_pc: '', - c_ph_num: '', + c_ph_type: '0', + c_ph: '', c_em: '', c_idtype_gswl: '', c_idnum_gswl: '' @@ -435,7 +483,8 @@ export default { { value: 'YYZZ', label: '营业执照' }, { value: 'ORG', label: '组织机构代码证' } ]; - } + }, + } }; \ No newline at end of file diff --git a/jcloud/api/domain_west.py b/jcloud/api/domain_west.py index 636806e..3ecb14b 100644 --- a/jcloud/api/domain_west.py +++ b/jcloud/api/domain_west.py @@ -11,7 +11,7 @@ from datetime import datetime from urllib.parse import urlencode from typing import Dict, Any, Optional, List from jcloud.utils import get_current_team - +from pypinyin import lazy_pinyin class WestDomain: """西部数码域名API客户端""" @@ -85,6 +85,8 @@ class WestDomain: try: if method.upper() == 'POST': data = body_params or {} + # 确保中文字符正确编码 + jingrow.log_error("西部数码API调试", f"发送POST请求,URL: {url}, 数据: {data}") response = requests.post(url, data=data, headers=headers, timeout=30) else: response = requests.get(url, headers=headers, timeout=30) @@ -362,11 +364,28 @@ class WestDomain: template_id: 模板ID """ body_params = { - 'act': 'gettemplate', + 'act': 'auditinfo', 'c_sysid': template_id, } return self._make_request('/audit/', 'POST', body_params=body_params) + def create_domain_template(self, template_data: Dict[str, Any]) -> Dict[str, Any]: + """ + 创建域名模板 + + Args: + template_data: 模板数据,包含所有必要的字段 + """ + body_params = { + 'act': 'auditsub', + **template_data + } + + # 对body_params进行GBK编码 + encoded_data = urlencode(body_params, encoding='gbk').encode('gbk') + + return self._make_request('/audit/', 'POST', body_params=encoded_data) + def get_west_client() -> WestDomain: """获取西部数码域名API客户端实例""" @@ -665,7 +684,7 @@ def west_domain_get_templates(**data): @jingrow.whitelist() -def west_domain_get_template_detail(**data): +def get_west_template_detail(**data): """获取指定模板详情""" client = get_west_client() if not client: @@ -1070,6 +1089,161 @@ def get_domain_owners(): jingrow.log_error("获取域名所有者列表失败", str(e)) return {"status": "Error", "message": f"获取域名所有者列表失败: {str(e)}"} +@jingrow.whitelist() +def create_domain_template(**data): + """创建域名模板""" + client = get_west_client() + if not client: + return {"status": "error", "message": "API客户端初始化失败"} + + # 验证必填字段 + required_fields = ['c_regtype', 'c_ln_m', 'c_fn_m', 'c_st_m', 'c_ct_m', 'c_adr_m', 'c_pc', 'c_em', 'c_idtype_gswl', 'c_idnum_gswl'] + for field in required_fields: + if not data.get(field): + return {"status": "error", "message": f"字段 {field} 是必填项"} + + # 验证电话号码字段(根据c_ph_type判断) + c_ph_type = data.get('c_ph_type', '0') # 默认为手机 + if c_ph_type == '0': # 手机 + if not data.get('c_ph'): + return {"status": "error", "message": "手机号码 c_ph 是必填项"} + elif c_ph_type == '1': # 座机 + if not data.get('c_ph_code'): + return {"status": "error", "message": "座机区号 c_ph_code 是必填项"} + if not data.get('c_ph_num'): + return {"status": "error", "message": "座机号码 c_ph_num 是必填项"} + + # 验证字段长度 + if len(data.get('c_ln_m', '')) < 1 or len(data.get('c_ln_m', '')) > 16: + return {"status": "error", "message": "姓(中文)长度必须为1~16位"} + + if len(data.get('c_fn_m', '')) < 1 or len(data.get('c_fn_m', '')) > 64: + return {"status": "error", "message": "名(中文)长度必须为1~64位"} + + if len(data.get('c_st_m', '')) < 2 or len(data.get('c_st_m', '')) > 10: + return {"status": "error", "message": "省份(中文)长度必须为2~10位"} + + # 验证完整姓名长度 + fullname = data.get('c_ln_m', '') + data.get('c_fn_m', '') + if len(fullname) < 2 or len(fullname) > 64: + return {"status": "error", "message": "完整姓名(中文)长度必须为2~64位"} + + # 生成英文姓名 + if data.get('c_ln_m') and data.get('c_fn_m'): + last_name_pinyin = ' '.join(lazy_pinyin(data['c_ln_m'])) + first_name_pinyin = ' '.join(lazy_pinyin(data['c_fn_m'])) + data['c_ln'] = last_name_pinyin.title() + data['c_fn'] = first_name_pinyin.title() + else: + # 设置默认的英文姓名 + data['c_ln'] = data.get('c_ln', '') + data['c_fn'] = data.get('c_fn', '') + + # 生成英文地址 + if data.get('c_adr_m'): + address_pinyin = ' '.join(lazy_pinyin(data['c_adr_m'])) + data['c_adr'] = address_pinyin.title() + else: + data['c_adr'] = data.get('c_adr', '') + + # 生成英文省份和城市 + if data.get('c_st_m'): + state_pinyin = ' '.join(lazy_pinyin(data['c_st_m'])) + data['c_st'] = state_pinyin.title() + else: + data['c_st'] = data.get('c_st', '') + + if data.get('c_ct_m'): + city_pinyin = ' '.join(lazy_pinyin(data['c_ct_m'])) + data['c_ct'] = city_pinyin.title() + else: + data['c_ct'] = data.get('c_ct', '') + + # 生成英文单位名称 + if data.get('c_org_m'): + org_pinyin = ' '.join(lazy_pinyin(data['c_org_m'])) + data['c_org'] = org_pinyin.title() + else: + data['c_org'] = data.get('c_org', '') + + # 设置默认值 + template_data = { + 'c_regtype': data['c_regtype'], + 'c_ln_m': data['c_ln_m'], + 'c_fn_m': data['c_fn_m'], + 'c_co': data.get('c_co', 'CN'), + 'cocode': data.get('cocode', '+86'), + 'c_st_m': data['c_st_m'], + 'c_ct_m': data['c_ct_m'], + 'c_dt_m': data.get('c_dt_m', ''), + 'c_adr_m': data['c_adr_m'], + 'c_pc': data['c_pc'], + 'c_ph_type': data.get('c_ph_type', '0'), + 'c_em': data['c_em'], + 'c_ln': data.get('c_ln', ''), # 使用生成的英文姓,如果没有则为空 + 'c_fn': data.get('c_fn', ''), # 使用生成的英文名,如果没有则为空 + 'c_st': data.get('c_st', ''), # 使用生成的英文省份,如果没有则为空 + 'c_ct': data.get('c_ct', ''), # 使用生成的英文城市,如果没有则为空 + 'c_adr': data.get('c_adr', ''), # 使用生成的英文地址,如果没有则为空 + 'c_idtype_gswl': data['c_idtype_gswl'], + 'c_idnum_gswl': data['c_idnum_gswl'], + 'fullname': data.get('c_ln_m', '') + data.get('c_fn_m', '') # 完整姓名 + } + + # 添加企业相关字段 + if data['c_regtype'] == 'E': + if not data.get('c_org_m'): + return {"status": "error", "message": "企业类型必须填写单位名称"} + template_data['c_org_m'] = data['c_org_m'] + template_data['c_org'] = data.get('c_org', '') # 英文单位名称 + + # 添加区县信息 + if data.get('c_dt_m'): + template_data['c_dt_m'] = data['c_dt_m'] + + # 添加香港域名相关字段 + if data.get('c_idtype_hk'): + template_data['c_idtype_hk'] = data['c_idtype_hk'] + if data.get('c_idnum_hk'): + template_data['c_idnum_hk'] = data['c_idnum_hk'] + + # 根据c_ph_type添加电话相关字段 + if data.get('c_ph_type') == '1': # 座机 + if data.get('c_ph_code'): + template_data['c_ph_code'] = data['c_ph_code'] + if data.get('c_ph_num'): + template_data['c_ph_num'] = data['c_ph_num'] + # 构建完整的电话号码格式 + if data.get('c_ph_code') and data.get('c_ph_num'): + template_data['c_ph_all'] = f"{data.get('cocode', '+86')}.{data['c_ph_code']}-{data['c_ph_num']}" + else: # 手机 + if data.get('c_ph'): + template_data['c_ph'] = data['c_ph'] + + try: + jingrow.log_error("西部模板API发送", f"模板数据: {template_data}") + result = client.create_domain_template(template_data) + + if result.get('result') == 200: + c_sysid = result.get('data', {}).get('c_sysid') + jingrow.log_error("西部模板API成功", f"模板ID: {c_sysid}") + return { + "status": "success", + "message": "域名模板创建成功", + "data": { + "c_sysid": c_sysid + } + } + else: + error_msg = result.get('msg', result.get('message', '未知错误')) + jingrow.log_error("西部模板API失败", f"错误: {error_msg}") + return {"status": "error", "message": f"创建域名模板失败: {error_msg}"} + + except Exception as e: + jingrow.log_error("西部模板API异常", str(e)) + return {"status": "error", "message": f"创建域名模板失败: {str(e)}"} + + @jingrow.whitelist() def create_domain_owner(**data): """创建新的域名所有者""" @@ -1094,44 +1268,59 @@ def create_domain_owner(**data): return {"status": "Error", "message": "座机区号 c_ph_code 是必填项"} if not data.get('c_ph_num'): return {"status": "Error", "message": "座机号码 c_ph_num 是必填项"} - - # 生成英文信息 - from pypinyin import lazy_pinyin - + # 生成英文姓名 if data.get('c_ln_m') and data.get('c_fn_m'): last_name_pinyin = ' '.join(lazy_pinyin(data['c_ln_m'])) first_name_pinyin = ' '.join(lazy_pinyin(data['c_fn_m'])) data['c_ln'] = last_name_pinyin.title() data['c_fn'] = first_name_pinyin.title() + else: + # 设置默认的英文姓名 + data['c_ln'] = data.get('c_ln', '') + data['c_fn'] = data.get('c_fn', '') # 生成英文地址 if data.get('c_adr_m'): address_pinyin = ' '.join(lazy_pinyin(data['c_adr_m'])) data['c_adr'] = address_pinyin.title() + else: + data['c_adr'] = data.get('c_adr', '') # 生成英文省份和城市 if data.get('c_st_m'): state_pinyin = ' '.join(lazy_pinyin(data['c_st_m'])) data['c_st'] = state_pinyin.title() + else: + data['c_st'] = data.get('c_st', '') if data.get('c_ct_m'): city_pinyin = ' '.join(lazy_pinyin(data['c_ct_m'])) data['c_ct'] = city_pinyin.title() + else: + data['c_ct'] = data.get('c_ct', '') # 生成英文单位名称 if data.get('c_org_m'): org_pinyin = ' '.join(lazy_pinyin(data['c_org_m'])) data['c_org'] = org_pinyin.title() + else: + data['c_org'] = data.get('c_org', '') # 设置默认值 data['team'] = team - data['c_co'] = 'CN' # 中国 - data['cocode'] = '+86' - data['c_ph_type'] = '0' # 手机 - data['reg_contact_type'] = 'cg' # 常规 + data['c_co'] = data.get('c_co', 'CN') # 中国 + data['cocode'] = data.get('cocode', '+86') + data['c_ph_type'] = data.get('c_ph_type', '0') # 手机 + data['reg_contact_type'] = data.get('reg_contact_type', 'cg') # 常规 + + # 确保c_sysid字段存在(如果提供) + if data.get('c_sysid'): + data['c_sysid'] = data['c_sysid'] + + # 生成完整姓名和标题 + data['fullname'] = data.get('c_ln_m', '') + data.get('c_fn_m', '') - # 生成标题 if data['c_regtype'] == 'I': # 个人 data['title'] = f"{data['c_ln_m']}{data['c_fn_m']} - 个人" else: # 企业 @@ -1144,6 +1333,7 @@ def create_domain_owner(**data): }) domain_owner.insert(ignore_permissions=True) + jingrow.log_error("域名所有者创建成功", f"名称: {domain_owner.name}, 标题: {domain_owner.title}") return { "status": "Success", "message": "域名所有者创建成功", @@ -1153,6 +1343,169 @@ def create_domain_owner(**data): } } except Exception as e: - jingrow.log_error("创建域名所有者失败", str(e)) + jingrow.log_error("域名所有者创建失败", str(e)) return {"status": "Error", "message": f"创建域名所有者失败: {str(e)}"} + +@jingrow.whitelist() +def create_domain_owner_with_template(**data): + """创建域名所有者(包含模板创建)""" + try: + # 第一步:创建域名模板 + template_result = create_domain_template(**data) + + if template_result.get("status") != "success": + return template_result + + # 获取模板ID + c_sysid = template_result.get("data", {}).get("c_sysid") + if not c_sysid: + return {"status": "Error", "message": "创建域名模板成功但未返回模板ID"} + + # 第二步:创建域名所有者记录 + data['c_sysid'] = c_sysid + owner_result = create_domain_owner(**data) + + if owner_result.get("status") != "Success": + return owner_result + + # 成功完成 + result = { + "status": "Success", + "message": "域名所有者创建成功", + "data": { + "c_sysid": c_sysid, + "owner_name": owner_result.get("data", {}).get("name"), + "owner_title": owner_result.get("data", {}).get("title") + } + } + jingrow.log_error("域名所有者完整创建成功", f"模板ID: {c_sysid}, 所有者: {owner_result.get('data', {}).get('name')}") + return result + + except Exception as e: + jingrow.log_error("域名所有者完整创建失败", str(e)) + return {"status": "Error", "message": f"创建域名所有者失败: {str(e)}"} + + +@jingrow.whitelist() +def test_create_domain_owner_with_template(): + """测试创建域名所有者(包含模板创建)的API端点""" + try: + # 硬编码的测试参数 + test_data = { + 'c_regtype': 'I', + 'c_ln_m': '李', + 'c_fn_m': '长生', + 'c_co': 'CN', + 'cocode': '+86', + 'c_st_m': '广东省', + 'c_ct_m': '广州市', + 'c_dt_m': '花都区', + 'c_adr_m': '狮岭镇龙头市场2栋', + 'c_pc': '510000', + 'c_ph_type': '0', + 'c_ph': '13926598569', + 'c_em': '13926598569@139.com', + 'c_idtype_gswl': 'SFZ', + 'c_idnum_gswl': '430524198506259568' + } + + # 调用create_domain_owner_with_template函数 + result = create_domain_template(**test_data) + + jingrow.log_error("测试API结果", f"结果: {result}") + return result + + except Exception as e: + jingrow.log_error("测试API异常", str(e)) + return {"status": "Error", "message": f"测试API调用失败: {str(e)}"} + + """硬编码参数测试创建域名模板""" + try: + import requests + import hashlib + import time + import json + from urllib.parse import urlencode + + # 硬编码的API配置 + username = "yanyukuang" # 请替换为实际的用户名 + password = "Jingrow@20250731" # 请替换为实际的密码 + api_base_url = "https://api.west.cn/api/v2" + + # 生成认证token + current_time = int(time.time() * 1000) + token_string = f"{username}{password}{current_time}" + token = hashlib.md5(token_string.encode('utf-8')).hexdigest() + + # 构建公共参数 + common_params = { + 'username': username, + 'time': str(current_time), + 'token': token, + } + + # 直接在template_data中硬编码所有数据 + template_data = { + 'act': 'auditsub', + 'c_regtype': 'I', + 'fullname': '张强', + 'c_co': 'CN', + 'cocode': '+86', + 'c_st_m': '广东省', + 'c_ct_m': '广州市', + 'c_dt_m': '花都区', + 'c_adr_m': '狮岭镇龙头市场二栋', + 'c_pc': '510000', + 'c_ph_type': '0', + 'c_ph': '13926598569', + 'c_em': '13926598569@139.com', + 'c_ln': 'Zhang', + 'c_fn': 'Qiang', + 'c_st': 'GD', + 'c_ct': 'guangzhou', + 'c_adr': 'Shi Ling Zhen Long Tou Shi Chang 2 Dong' + } + + # 构建URL + param_string = urlencode(common_params) + url = f"{api_base_url}/audit/?{param_string}" + + headers = { + 'Content-Type': 'application/x-www-form-urlencoded' + } + + # 发送请求 + jingrow.log_error("硬编码测试API发送", f"URL: {url}") + jingrow.log_error("硬编码测试API数据", f"模板数据: {template_data}") + + # 使用urlencode编码POST数据,指定GBK编码 + encoded_data = urlencode(template_data, encoding='gbk').encode('gbk') + + response = requests.post(url, data=encoded_data, headers=headers, timeout=30) + response.raise_for_status() + + try: + result = response.json() + except json.JSONDecodeError: + jingrow.log_error("硬编码测试API响应解析失败", response_text=response.text) + result = {"status": "error", "message": "无法解析API响应"} + + jingrow.log_error("硬编码测试API结果", f"结果: {result}") + + if result.get('result') == 200: + c_sysid = result.get('data', {}).get('c_sysid') + return { + "status": "success", + "message": "域名模板创建成功", + "data": { + "c_sysid": c_sysid + } + } + else: + error_msg = result.get('msg', result.get('message', '未知错误')) + return {"status": "error", "message": f"创建域名模板失败: {error_msg}"} + + except Exception as e: + jingrow.log_error("硬编码测试API异常", str(e)) + return {"status": "error", "message": f"测试API调用失败: {str(e)}"} \ No newline at end of file diff --git a/jcloud/jcloud/pagetype/domain_owner/domain_owner.json b/jcloud/jcloud/pagetype/domain_owner/domain_owner.json index e9994fa..c032251 100644 --- a/jcloud/jcloud/pagetype/domain_owner/domain_owner.json +++ b/jcloud/jcloud/pagetype/domain_owner/domain_owner.json @@ -53,8 +53,10 @@ { "fieldname": "c_regtype", "fieldtype": "Select", + "in_list_view": 1, "label": "所有者类型", - "options": "\nI\nE" + "options": "\nI\nE", + "reqd": 1 }, { "fieldname": "c_org_m", @@ -69,16 +71,19 @@ { "fieldname": "c_ln_m", "fieldtype": "Data", + "in_list_view": 1, "label": "(中文)联系人姓" }, { "fieldname": "c_fn_m", "fieldtype": "Data", + "in_list_view": 1, "label": "(中文)联系人名" }, { "fieldname": "c_co", "fieldtype": "Data", + "in_list_view": 1, "label": "所属国家或地区简称" }, { @@ -89,11 +94,13 @@ { "fieldname": "c_st_m", "fieldtype": "Data", + "in_list_view": 1, "label": "(中文)所属省" }, { "fieldname": "c_ct_m", "fieldtype": "Data", + "in_list_view": 1, "label": "(中文)所属市" }, { @@ -122,6 +129,7 @@ { "fieldname": "c_ph", "fieldtype": "Data", + "in_list_view": 1, "label": "手机号码" }, { @@ -212,13 +220,15 @@ { "fieldname": "c_sysid", "fieldtype": "Data", + "in_list_view": 1, + "in_standard_filter": 1, "label": "模板标识" } ], "grid_page_length": 50, "index_web_pages_for_search": 1, "links": [], - "modified": "2025-08-01 21:43:44.119231", + "modified": "2025-08-01 22:27:42.613190", "modified_by": "Administrator", "module": "Jcloud", "name": "Domain Owner", diff --git a/jcloud/jcloud/pagetype/domain_owner/domain_owner.py b/jcloud/jcloud/pagetype/domain_owner/domain_owner.py index 36710fe..2b53c2a 100644 --- a/jcloud/jcloud/pagetype/domain_owner/domain_owner.py +++ b/jcloud/jcloud/pagetype/domain_owner/domain_owner.py @@ -65,7 +65,8 @@ class DomainOwner(Document): "team", "cocode", "c_idtype_gswl", - "c_idnum_gswl" + "c_idnum_gswl", + "c_sysid" ) @staticmethod