域名详情页实名认证检测通过
This commit is contained in:
parent
81d623b653
commit
b8ae5c7b3d
@ -9,7 +9,49 @@
|
||||
<div class="rounded-md border">
|
||||
<div class="p-5">
|
||||
<div class="flex h-full flex-col sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="mb-4 sm:mb-0">
|
||||
<div class="mb-4 sm:mb-0">
|
||||
<!-- 实名认证状态 -->
|
||||
<div class="mb-4 p-4 bg-gradient-to-r from-gray-50 to-blue-50 rounded-xl border border-gray-200">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div v-if="realNameStatus === 'verified'" class="flex items-center space-x-3">
|
||||
<div class="inline-flex items-center rounded-full bg-gradient-to-r from-green-50 to-emerald-50 px-4 py-2 text-sm font-semibold text-green-800 border border-green-200 shadow-sm">
|
||||
<svg class="mr-2 h-4 w-4 text-green-600" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
实名认证
|
||||
</div>
|
||||
<button
|
||||
@click="showRealNameInfo"
|
||||
class="inline-flex items-center px-3 py-1.5 text-sm font-medium text-blue-700 bg-blue-100 hover:bg-blue-200 rounded-lg transition-colors duration-200 border border-blue-300"
|
||||
>
|
||||
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
查看认证信息
|
||||
</button>
|
||||
</div>
|
||||
<div v-else class="flex items-center space-x-3">
|
||||
<div class="inline-flex items-center rounded-full bg-gradient-to-r from-amber-50 to-orange-50 px-4 py-2 text-sm font-semibold text-amber-800 border border-amber-200 shadow-sm">
|
||||
<svg class="mr-2 h-4 w-4 text-amber-600" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
待实名认证
|
||||
</div>
|
||||
<button
|
||||
@click="showUploadRealName"
|
||||
class="inline-flex items-center px-3 py-1.5 text-sm font-medium text-white bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 rounded-lg transition-all duration-200 shadow-sm hover:shadow-md"
|
||||
>
|
||||
<svg class="mr-1.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
|
||||
</svg>
|
||||
上传实名资料
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="$domain.pg.end_date" class="mt-2 inline-flex items-center rounded-full bg-amber-50 px-4 py-2 text-sm font-medium text-amber-800">
|
||||
<ClockIcon class="mr-1.5 h-4 w-4 text-amber-500" />
|
||||
到期时间:{{ $format.date($domain.pg.end_date) }}
|
||||
@ -158,6 +200,8 @@ export default {
|
||||
autoRenewLoading: false,
|
||||
whoisProtectionLoading: false,
|
||||
domainOwner: null,
|
||||
realNameStatus: 'unverified', // 实名认证状态:verified, unverified
|
||||
realNameInfo: null, // 实名认证信息
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -196,6 +240,7 @@ export default {
|
||||
async getDomainOwner() {
|
||||
if (!this.$domain.pg?.domain_owner) {
|
||||
this.domainOwner = null;
|
||||
this.realNameStatus = 'unverified';
|
||||
return;
|
||||
}
|
||||
|
||||
@ -208,17 +253,33 @@ export default {
|
||||
onSuccess: (response) => {
|
||||
if (response && response.status === "Success" && response.data) {
|
||||
this.domainOwner = response.data;
|
||||
// 根据域名所有者记录的r_status字段设置实名认证状态
|
||||
// r_status是check字段类型,1表示已认证,0表示未认证
|
||||
const rStatus = response.data.r_status;
|
||||
|
||||
// 对于check字段,将值转换为布尔值进行判断
|
||||
const isVerified = Boolean(rStatus && (rStatus === 1 || rStatus === '1' || rStatus === true));
|
||||
|
||||
if (isVerified) {
|
||||
this.realNameStatus = 'verified';
|
||||
} else {
|
||||
this.realNameStatus = 'unverified';
|
||||
}
|
||||
} else {
|
||||
this.realNameStatus = 'unverified';
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('获取域名所有者信息失败:', error);
|
||||
this.domainOwner = null;
|
||||
this.realNameStatus = 'unverified';
|
||||
}
|
||||
});
|
||||
getOwnerRequest.submit();
|
||||
} catch (error) {
|
||||
console.error('获取域名所有者信息失败:', error);
|
||||
this.domainOwner = null;
|
||||
this.realNameStatus = 'unverified';
|
||||
}
|
||||
},
|
||||
renewDomain() {
|
||||
@ -323,6 +384,58 @@ export default {
|
||||
toast.success('域名续费成功!');
|
||||
this.$domain.reload();
|
||||
},
|
||||
// 显示实名认证信息
|
||||
showRealNameInfo() {
|
||||
const JsiteDomainRealNameInfoDialog = defineAsyncComponent(() => import('./JsiteDomainRealNameInfoDialog.vue'));
|
||||
|
||||
renderDialog(h(JsiteDomainRealNameInfoDialog, {
|
||||
domain: this.domain,
|
||||
domainDoc: this.$domain.pg,
|
||||
realNameInfo: this.realNameInfo
|
||||
}));
|
||||
},
|
||||
// 显示上传实名资料
|
||||
showUploadRealName() {
|
||||
const JsiteDomainUploadRealNameDialog = defineAsyncComponent(() => import('./JsiteDomainUploadRealNameDialog.vue'));
|
||||
|
||||
renderDialog(h(JsiteDomainUploadRealNameDialog, {
|
||||
domain: this.domain,
|
||||
domainDoc: this.$domain.pg,
|
||||
onSuccess: this.onUploadSuccess
|
||||
}));
|
||||
},
|
||||
// 上传成功回调
|
||||
onUploadSuccess() {
|
||||
toast.success('实名资料上传成功!');
|
||||
this.getDomainOwner(); // 重新获取域名所有者信息(包含实名认证状态)
|
||||
this.getRealNameInfo(); // 重新获取实名详细信息
|
||||
},
|
||||
// 获取域名实名认证信息
|
||||
async getRealNameInfo() {
|
||||
if (!this.$domain.pg?.domain) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const getRealNameRequest = createResource({
|
||||
url: 'jcloud.api.domain_west.get_west_domain_real_info',
|
||||
params: {
|
||||
domain: this.$domain.pg.domain
|
||||
},
|
||||
onSuccess: (response) => {
|
||||
if (response && response.status === "success" && response.data) {
|
||||
this.realNameInfo = response.data;
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('获取域名实名信息失败:', error);
|
||||
}
|
||||
});
|
||||
getRealNameRequest.submit();
|
||||
} catch (error) {
|
||||
console.error('获取域名实名信息失败:', error);
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// 监听域名数据变化,重新获取所有者信息
|
||||
@ -332,6 +445,7 @@ export default {
|
||||
this.getDomainOwner();
|
||||
} else {
|
||||
this.domainOwner = null;
|
||||
this.realNameStatus = 'unverified';
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
@ -366,7 +480,11 @@ export default {
|
||||
// 初始化时获取域名所有者信息
|
||||
if (this.$domain.pg?.domain_owner) {
|
||||
this.getDomainOwner();
|
||||
} else {
|
||||
this.realNameStatus = 'unverified';
|
||||
}
|
||||
// 获取域名实名认证信息
|
||||
this.getRealNameInfo();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
318
dashboard/src2/components/JsiteDomainRealNameInfoDialog.vue
Normal file
318
dashboard/src2/components/JsiteDomainRealNameInfoDialog.vue
Normal file
@ -0,0 +1,318 @@
|
||||
<template>
|
||||
<Dialog v-bind="$attrs" :options="{ title: '实名认证信息', size: '3xl' }">
|
||||
<template #body>
|
||||
<div v-if="loading" class="flex justify-center items-center py-12">
|
||||
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
|
||||
<span class="ml-3 text-gray-600">加载中...</span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="error" class="text-center py-12">
|
||||
<div class="text-red-500 mb-4">
|
||||
<AlertTriangleIcon class="h-12 w-12 mx-auto" />
|
||||
</div>
|
||||
<p class="text-gray-600">{{ error }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="realNameData" class="space-y-6">
|
||||
<!-- 认证状态 -->
|
||||
<div class="bg-gradient-to-r from-green-50 to-emerald-50 rounded-xl p-6 border border-green-200">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0">
|
||||
<CheckCircleIcon class="h-8 w-8 text-green-500" />
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<h3 class="text-lg font-medium text-green-900">认证已通过</h3>
|
||||
<p class="text-sm text-green-700">该域名已完成实名认证</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm">
|
||||
<div class="px-6 py-4 border-b border-gray-100">
|
||||
<h3 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<FileTextIcon class="h-5 w-5 mr-2 text-blue-600" />
|
||||
域名基本信息
|
||||
</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="space-y-4">
|
||||
<InfoItem label="域名" :value="realNameData.domain" />
|
||||
<InfoItem label="注册日期" :value="formatDate(realNameData.regdate)" />
|
||||
<InfoItem label="到期日期" :value="formatDate(realNameData.rexpiredate)" />
|
||||
<InfoItem label="认证状态" :value="getStatusText(realNameData.c_status)" />
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<InfoItem label="模板ID" :value="realNameData.c_sysid" />
|
||||
<InfoItem label="注册类型" :value="getRegTypeText(realNameData.c_regtype)" />
|
||||
<InfoItem label="域名状态" :value="realNameData.status" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 所有者信息 -->
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm">
|
||||
<div class="px-6 py-4 border-b border-gray-100">
|
||||
<h3 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<UserIcon class="h-5 w-5 mr-2 text-blue-600" />
|
||||
所有者信息
|
||||
</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="space-y-4">
|
||||
<InfoItem label="中文姓名" :value="getFullChineseName()" />
|
||||
<InfoItem label="英文姓名" :value="getFullEnglishName()" />
|
||||
<InfoItem v-if="realNameData.owner.dom_org_m" label="中文单位" :value="realNameData.owner.dom_org_m" />
|
||||
<InfoItem v-if="realNameData.owner.dom_org" label="英文单位" :value="realNameData.owner.dom_org" />
|
||||
<InfoItem label="邮箱" :value="realNameData.owner.dom_em" />
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<InfoItem label="电话" :value="realNameData.owner.dom_ph" />
|
||||
<InfoItem label="传真" :value="realNameData.owner.dom_fax" />
|
||||
<InfoItem label="国家/地区" :value="realNameData.owner.dom_co" />
|
||||
<InfoItem label="省份" :value="realNameData.owner.dom_st_m || realNameData.owner.dom_st" />
|
||||
<InfoItem label="城市" :value="realNameData.owner.dom_ct_m || realNameData.owner.dom_ct" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<InfoItem label="地址" :value="realNameData.owner.dom_adr_m || realNameData.owner.dom_adr1" />
|
||||
<InfoItem label="邮编" :value="realNameData.owner.dom_pc" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 联系人信息 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<!-- 管理联系人 -->
|
||||
<ContactCard
|
||||
title="管理联系人"
|
||||
icon="UserCircleIcon"
|
||||
:contact="realNameData.admin"
|
||||
type="admin"
|
||||
/>
|
||||
|
||||
<!-- 技术联系人 -->
|
||||
<ContactCard
|
||||
title="技术联系人"
|
||||
icon="SettingsIcon"
|
||||
:contact="realNameData.tech"
|
||||
type="tech"
|
||||
/>
|
||||
|
||||
<!-- 缴费联系人 -->
|
||||
<ContactCard
|
||||
title="缴费联系人"
|
||||
icon="CreditCardIcon"
|
||||
:contact="realNameData.billing"
|
||||
type="bill"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- DNS服务器 -->
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm">
|
||||
<div class="px-6 py-4 border-b border-gray-100">
|
||||
<h3 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<GlobeIcon class="h-5 w-5 mr-2 text-blue-600" />
|
||||
DNS服务器
|
||||
</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div v-for="(dns, index) in getDnsServers()" :key="index" class="bg-gray-50 rounded-lg p-4">
|
||||
<div class="text-sm font-medium text-gray-600 mb-1">DNS{{ index + 1 }}</div>
|
||||
<div class="font-mono text-sm text-gray-900">{{ dns || '未设置' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Dialog, createResource } from 'jingrow-ui';
|
||||
import { toast } from 'vue-sonner';
|
||||
import CheckCircleIcon from '~icons/lucide/check-circle';
|
||||
import AlertTriangleIcon from '~icons/lucide/alert-triangle';
|
||||
import FileTextIcon from '~icons/lucide/file-text';
|
||||
import UserIcon from '~icons/lucide/user';
|
||||
import UserCircleIcon from '~icons/lucide/user-circle';
|
||||
import SettingsIcon from '~icons/lucide/settings';
|
||||
import CreditCardIcon from '~icons/lucide/credit-card';
|
||||
import GlobeIcon from '~icons/lucide/globe';
|
||||
|
||||
// 信息项组件
|
||||
const InfoItem = {
|
||||
props: ['label', 'value'],
|
||||
template: `
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-gray-600">{{ label }}</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{ value || '未填写' }}</dd>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
|
||||
// 联系人卡片组件
|
||||
const ContactCard = {
|
||||
props: ['title', 'icon', 'contact', 'type'],
|
||||
components: { UserCircleIcon, SettingsIcon, CreditCardIcon },
|
||||
template: `
|
||||
<div class="bg-white rounded-xl border border-gray-200 shadow-sm">
|
||||
<div class="px-4 py-3 border-b border-gray-100">
|
||||
<h4 class="text-sm font-medium text-gray-900 flex items-center">
|
||||
<component :is="icon" class="h-4 w-4 mr-2 text-blue-600" />
|
||||
{{ title }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="p-4 space-y-3">
|
||||
<div>
|
||||
<div class="text-xs font-medium text-gray-600">姓名</div>
|
||||
<div class="text-sm text-gray-900">{{ getContactName() }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs font-medium text-gray-600">邮箱</div>
|
||||
<div class="text-sm text-gray-900">{{ contact[type + '_em'] || '未填写' }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs font-medium text-gray-600">电话</div>
|
||||
<div class="text-sm text-gray-900">{{ contact[type + '_ph'] || '未填写' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
getContactName() {
|
||||
const chineseName = (this.contact[this.type + '_ln_m'] || '') + (this.contact[this.type + '_fn_m'] || '');
|
||||
const englishName = (this.contact[this.type + '_ln'] || '') + ' ' + (this.contact[this.type + '_fn'] || '');
|
||||
return chineseName || englishName.trim() || '未填写';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'JsiteDomainRealNameInfoDialog',
|
||||
components: {
|
||||
Dialog,
|
||||
CheckCircleIcon,
|
||||
AlertTriangleIcon,
|
||||
FileTextIcon,
|
||||
UserIcon,
|
||||
UserCircleIcon,
|
||||
SettingsIcon,
|
||||
CreditCardIcon,
|
||||
GlobeIcon,
|
||||
InfoItem,
|
||||
ContactCard
|
||||
},
|
||||
props: {
|
||||
domain: String,
|
||||
domainDoc: Object,
|
||||
realNameInfo: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
error: null,
|
||||
realNameData: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async loadRealNameInfo() {
|
||||
if (this.realNameInfo) {
|
||||
this.realNameData = this.realNameInfo;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.domainDoc?.domain) {
|
||||
this.error = '域名信息不存在';
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
const getRealNameRequest = createResource({
|
||||
url: 'jcloud.api.domain_west.get_west_domain_real_info',
|
||||
params: {
|
||||
domain: this.domainDoc.domain
|
||||
},
|
||||
onSuccess: (response) => {
|
||||
if (response && response.status === "success" && response.data) {
|
||||
this.realNameData = response.data;
|
||||
} else {
|
||||
this.error = '获取实名认证信息失败';
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('获取域名实名信息失败:', error);
|
||||
this.error = '获取实名认证信息失败';
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
getRealNameRequest.submit();
|
||||
} catch (error) {
|
||||
console.error('获取域名实名信息失败:', error);
|
||||
this.error = '获取实名认证信息失败';
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '未知';
|
||||
try {
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleDateString('zh-CN');
|
||||
} catch {
|
||||
return dateStr;
|
||||
}
|
||||
},
|
||||
getStatusText(status) {
|
||||
const statusMap = {
|
||||
1: '已通过',
|
||||
2: '审核中',
|
||||
3: '审核失败',
|
||||
4: '待上传'
|
||||
};
|
||||
return statusMap[status] || status || '未知';
|
||||
},
|
||||
getRegTypeText(regType) {
|
||||
const typeMap = {
|
||||
'I': '个人',
|
||||
'E': '企业'
|
||||
};
|
||||
return typeMap[regType] || regType || '未知';
|
||||
},
|
||||
getFullChineseName() {
|
||||
if (!this.realNameData?.owner) return '未填写';
|
||||
const lastName = this.realNameData.owner.dom_ln_m || '';
|
||||
const firstName = this.realNameData.owner.dom_fn_m || '';
|
||||
return lastName + firstName || '未填写';
|
||||
},
|
||||
getFullEnglishName() {
|
||||
if (!this.realNameData?.owner) return '未填写';
|
||||
const lastName = this.realNameData.owner.dom_ln || '';
|
||||
const firstName = this.realNameData.owner.dom_fn || '';
|
||||
return (lastName + ' ' + firstName).trim() || '未填写';
|
||||
},
|
||||
getDnsServers() {
|
||||
if (!this.realNameData?.dns_hosts) return [];
|
||||
return [
|
||||
this.realNameData.dns_hosts.dns_host1,
|
||||
this.realNameData.dns_hosts.dns_host2,
|
||||
this.realNameData.dns_hosts.dns_host3,
|
||||
this.realNameData.dns_hosts.dns_host4,
|
||||
this.realNameData.dns_hosts.dns_host5,
|
||||
this.realNameData.dns_hosts.dns_host6
|
||||
].filter(Boolean);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadRealNameInfo();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
468
dashboard/src2/components/JsiteDomainUploadRealNameDialog.vue
Normal file
468
dashboard/src2/components/JsiteDomainUploadRealNameDialog.vue
Normal file
@ -0,0 +1,468 @@
|
||||
<template>
|
||||
<Dialog v-bind="$attrs" :options="{ title: '上传实名资料', size: '2xl' }">
|
||||
<template #body>
|
||||
<div class="space-y-6">
|
||||
<!-- 步骤指示器 -->
|
||||
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl p-6 border border-blue-200">
|
||||
<div class="flex items-start">
|
||||
<div class="flex-shrink-0">
|
||||
<InfoIcon class="h-6 w-6 text-blue-600" />
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<h3 class="text-lg font-medium text-blue-900 mb-2">实名认证说明</h3>
|
||||
<div class="text-sm text-blue-700 space-y-2">
|
||||
<p>• 个人用户:请上传身份证正反面照片</p>
|
||||
<p>• 企业用户:请上传营业执照和法人身份证</p>
|
||||
<p>• 文件格式支持:JPG、PNG、PDF,单个文件不超过5MB</p>
|
||||
<p>• 请确保证件信息清晰可见,避免反光或模糊</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="submitUpload" class="space-y-6">
|
||||
<!-- 认证类型选择 -->
|
||||
<div>
|
||||
<label class="text-base font-medium text-gray-900 block mb-4">认证类型</label>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<label class="relative cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
v-model="formData.certType"
|
||||
value="personal"
|
||||
class="sr-only peer"
|
||||
/>
|
||||
<div class="border-2 border-gray-200 rounded-xl p-4 peer-checked:border-blue-500 peer-checked:bg-blue-50 transition-all duration-200 hover:border-gray-300">
|
||||
<div class="flex items-center">
|
||||
<UserIcon class="h-6 w-6 text-gray-600 mr-3" />
|
||||
<div>
|
||||
<div class="font-medium text-gray-900">个人认证</div>
|
||||
<div class="text-sm text-gray-600">使用个人身份证进行认证</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="relative cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
v-model="formData.certType"
|
||||
value="enterprise"
|
||||
class="sr-only peer"
|
||||
/>
|
||||
<div class="border-2 border-gray-200 rounded-xl p-4 peer-checked:border-blue-500 peer-checked:bg-blue-50 transition-all duration-200 hover:border-gray-300">
|
||||
<div class="flex items-center">
|
||||
<BuildingIcon class="h-6 w-6 text-gray-600 mr-3" />
|
||||
<div>
|
||||
<div class="font-medium text-gray-900">企业认证</div>
|
||||
<div class="text-sm text-gray-600">使用营业执照进行认证</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 个人认证文件上传 -->
|
||||
<div v-if="formData.certType === 'personal'" class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- 身份证正面 -->
|
||||
<FileUpload
|
||||
label="身份证正面"
|
||||
description="请上传身份证正面照片"
|
||||
:files="formData.idCardFront"
|
||||
@update:files="formData.idCardFront = $event"
|
||||
accept="image/*,.pdf"
|
||||
:maxSize="5"
|
||||
required
|
||||
/>
|
||||
|
||||
<!-- 身份证反面 -->
|
||||
<FileUpload
|
||||
label="身份证反面"
|
||||
description="请上传身份证反面照片"
|
||||
:files="formData.idCardBack"
|
||||
@update:files="formData.idCardBack = $event"
|
||||
accept="image/*,.pdf"
|
||||
:maxSize="5"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 企业认证文件上传 -->
|
||||
<div v-if="formData.certType === 'enterprise'" class="space-y-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- 营业执照 -->
|
||||
<FileUpload
|
||||
label="营业执照"
|
||||
description="请上传营业执照照片或扫描件"
|
||||
:files="formData.businessLicense"
|
||||
@update:files="formData.businessLicense = $event"
|
||||
accept="image/*,.pdf"
|
||||
:maxSize="5"
|
||||
required
|
||||
/>
|
||||
|
||||
<!-- 法人身份证 -->
|
||||
<FileUpload
|
||||
label="法人身份证"
|
||||
description="请上传法人身份证正面照片"
|
||||
:files="formData.legalIdCard"
|
||||
@update:files="formData.legalIdCard = $event"
|
||||
accept="image/*,.pdf"
|
||||
:maxSize="5"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 联系信息 -->
|
||||
<div class="bg-gray-50 rounded-xl p-6">
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-4">联系信息</h3>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">联系人姓名</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="formData.contactName"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
placeholder="请输入联系人姓名"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">联系电话</label>
|
||||
<input
|
||||
type="tel"
|
||||
v-model="formData.contactPhone"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
placeholder="请输入联系电话"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-2">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">邮箱地址</label>
|
||||
<input
|
||||
type="email"
|
||||
v-model="formData.contactEmail"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
placeholder="请输入邮箱地址"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 备注 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">备注说明(可选)</label>
|
||||
<textarea
|
||||
v-model="formData.remark"
|
||||
rows="3"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
placeholder="如有特殊情况请在此说明..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<div class="flex justify-end space-x-4 pt-6 border-t">
|
||||
<Button variant="outline" @click="$emit('close')">
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
:loading="loading"
|
||||
class="px-8 bg-blue-600 hover:bg-blue-700 text-white"
|
||||
>
|
||||
提交认证
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Dialog, Button, createResource } from 'jingrow-ui';
|
||||
import { toast } from 'vue-sonner';
|
||||
import InfoIcon from '~icons/lucide/info';
|
||||
import UserIcon from '~icons/lucide/user';
|
||||
import BuildingIcon from '~icons/lucide/building';
|
||||
import UploadIcon from '~icons/lucide/upload';
|
||||
import FileIcon from '~icons/lucide/file';
|
||||
import XIcon from '~icons/lucide/x';
|
||||
|
||||
// 文件上传组件
|
||||
const FileUpload = {
|
||||
props: {
|
||||
label: String,
|
||||
description: String,
|
||||
files: Array,
|
||||
accept: String,
|
||||
maxSize: Number,
|
||||
required: Boolean
|
||||
},
|
||||
emits: ['update:files'],
|
||||
components: { UploadIcon, FileIcon, XIcon },
|
||||
template: `
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||||
{{ label }}
|
||||
<span v-if="required" class="text-red-500">*</span>
|
||||
</label>
|
||||
<p class="text-sm text-gray-600 mb-3">{{ description }}</p>
|
||||
|
||||
<div class="space-y-3">
|
||||
<!-- 文件上传区域 -->
|
||||
<div
|
||||
@click="triggerFileInput"
|
||||
@dragover.prevent
|
||||
@drop.prevent="handleDrop"
|
||||
class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center cursor-pointer hover:border-blue-400 hover:bg-blue-50 transition-colors duration-200"
|
||||
>
|
||||
<UploadIcon class="h-8 w-8 text-gray-400 mx-auto mb-2" />
|
||||
<p class="text-sm text-gray-600">点击上传或拖拽文件到此处</p>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
支持 {{ accept }} 格式,最大 {{ maxSize }}MB
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 已上传文件列表 -->
|
||||
<div v-if="files && files.length > 0" class="space-y-2">
|
||||
<div
|
||||
v-for="(file, index) in files"
|
||||
:key="index"
|
||||
class="flex items-center justify-between bg-gray-50 rounded-lg p-3"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<FileIcon class="h-5 w-5 text-blue-600 mr-2" />
|
||||
<div>
|
||||
<div class="text-sm font-medium text-gray-900">{{ file.name }}</div>
|
||||
<div class="text-xs text-gray-500">{{ formatFileSize(file.size) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
@click="removeFile(index)"
|
||||
class="text-gray-400 hover:text-red-500 transition-colors"
|
||||
>
|
||||
<XIcon class="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
:accept="accept"
|
||||
multiple
|
||||
class="hidden"
|
||||
@change="handleFileSelect"
|
||||
/>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
triggerFileInput() {
|
||||
this.$refs.fileInput.click();
|
||||
},
|
||||
handleFileSelect(event) {
|
||||
const files = Array.from(event.target.files);
|
||||
this.addFiles(files);
|
||||
},
|
||||
handleDrop(event) {
|
||||
const files = Array.from(event.dataTransfer.files);
|
||||
this.addFiles(files);
|
||||
},
|
||||
addFiles(newFiles) {
|
||||
const validFiles = newFiles.filter(file => {
|
||||
// 检查文件大小
|
||||
if (file.size > this.maxSize * 1024 * 1024) {
|
||||
toast.error(`文件 ${file.name} 超过 ${this.maxSize}MB 限制`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const currentFiles = this.files || [];
|
||||
this.$emit('update:files', [...currentFiles, ...validFiles]);
|
||||
},
|
||||
removeFile(index) {
|
||||
const currentFiles = [...this.files];
|
||||
currentFiles.splice(index, 1);
|
||||
this.$emit('update:files', currentFiles);
|
||||
},
|
||||
formatFileSize(bytes) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'JsiteDomainUploadRealNameDialog',
|
||||
components: {
|
||||
Dialog,
|
||||
Button,
|
||||
InfoIcon,
|
||||
UserIcon,
|
||||
BuildingIcon,
|
||||
FileUpload
|
||||
},
|
||||
props: {
|
||||
domain: String,
|
||||
domainDoc: Object
|
||||
},
|
||||
emits: ['success', 'close'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
formData: {
|
||||
certType: 'personal',
|
||||
idCardFront: [],
|
||||
idCardBack: [],
|
||||
businessLicense: [],
|
||||
legalIdCard: [],
|
||||
contactName: '',
|
||||
contactPhone: '',
|
||||
contactEmail: '',
|
||||
remark: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async submitUpload() {
|
||||
// 验证必填字段
|
||||
if (!this.validateForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
// 创建FormData对象
|
||||
const formData = new FormData();
|
||||
|
||||
// 添加基本信息
|
||||
formData.append('domain', this.domainDoc.domain);
|
||||
formData.append('certType', this.formData.certType);
|
||||
formData.append('contactName', this.formData.contactName);
|
||||
formData.append('contactPhone', this.formData.contactPhone);
|
||||
formData.append('contactEmail', this.formData.contactEmail);
|
||||
formData.append('remark', this.formData.remark);
|
||||
|
||||
// 添加文件
|
||||
if (this.formData.certType === 'personal') {
|
||||
if (this.formData.idCardFront.length > 0) {
|
||||
this.formData.idCardFront.forEach((file, index) => {
|
||||
formData.append(`idCardFront_${index}`, file);
|
||||
});
|
||||
}
|
||||
if (this.formData.idCardBack.length > 0) {
|
||||
this.formData.idCardBack.forEach((file, index) => {
|
||||
formData.append(`idCardBack_${index}`, file);
|
||||
});
|
||||
}
|
||||
} else if (this.formData.certType === 'enterprise') {
|
||||
if (this.formData.businessLicense.length > 0) {
|
||||
this.formData.businessLicense.forEach((file, index) => {
|
||||
formData.append(`businessLicense_${index}`, file);
|
||||
});
|
||||
}
|
||||
if (this.formData.legalIdCard.length > 0) {
|
||||
this.formData.legalIdCard.forEach((file, index) => {
|
||||
formData.append(`legalIdCard_${index}`, file);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 调用后端上传API
|
||||
const uploadRequest = createResource({
|
||||
url: 'jcloud.api.domain_west.upload_domain_real_name_files',
|
||||
method: 'POST',
|
||||
params: formData,
|
||||
onSuccess: (response) => {
|
||||
if (response && response.status === "success") {
|
||||
toast.success('实名资料上传成功,请等待审核');
|
||||
this.$emit('success');
|
||||
this.$emit('close');
|
||||
} else {
|
||||
toast.error(response.message || '上传失败,请重试');
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('上传实名资料失败:', error);
|
||||
toast.error('上传失败,请重试');
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
uploadRequest.submit();
|
||||
|
||||
} catch (error) {
|
||||
console.error('上传实名资料失败:', error);
|
||||
toast.error('上传失败,请重试');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
validateForm() {
|
||||
if (!this.formData.certType) {
|
||||
toast.error('请选择认证类型');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.formData.certType === 'personal') {
|
||||
if (!this.formData.idCardFront.length) {
|
||||
toast.error('请上传身份证正面');
|
||||
return false;
|
||||
}
|
||||
if (!this.formData.idCardBack.length) {
|
||||
toast.error('请上传身份证反面');
|
||||
return false;
|
||||
}
|
||||
} else if (this.formData.certType === 'enterprise') {
|
||||
if (!this.formData.businessLicense.length) {
|
||||
toast.error('请上传营业执照');
|
||||
return false;
|
||||
}
|
||||
if (!this.formData.legalIdCard.length) {
|
||||
toast.error('请上传法人身份证');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.formData.contactName.trim()) {
|
||||
toast.error('请填写联系人姓名');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.formData.contactPhone.trim()) {
|
||||
toast.error('请填写联系电话');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.formData.contactEmail.trim()) {
|
||||
toast.error('请填写邮箱地址');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证邮箱格式
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(this.formData.contactEmail)) {
|
||||
toast.error('请填写正确的邮箱地址');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@ -417,6 +417,83 @@ class WestDomain:
|
||||
}
|
||||
return self._make_request('/audit/', 'POST', body_params=body_params)
|
||||
|
||||
def get_upload_token(self, c_sysid: str, f_type_org: str, f_code_org: str,
|
||||
f_type_lxr: Optional[str] = None, f_code_lxr: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
获取实名上传token
|
||||
|
||||
Args:
|
||||
c_sysid: 模板标识
|
||||
f_type_org: 证件类型,详情见附录
|
||||
f_code_org: 证件号码
|
||||
f_type_lxr: 联系人证件类型(企业时填写)
|
||||
f_code_lxr: 联系人证件号码(企业时填写)
|
||||
|
||||
Returns:
|
||||
API响应结果,包含上传token
|
||||
"""
|
||||
body_params = {
|
||||
'act': 'uploadwcftoken',
|
||||
'c_sysid': c_sysid,
|
||||
'f_type_org': f_type_org,
|
||||
'f_code_org': f_code_org,
|
||||
}
|
||||
|
||||
# 添加可选参数
|
||||
if f_type_lxr:
|
||||
body_params['f_type_lxr'] = f_type_lxr
|
||||
if f_code_lxr:
|
||||
body_params['f_code_lxr'] = f_code_lxr
|
||||
|
||||
return self._make_request('/audit/', 'POST', body_params=body_params)
|
||||
|
||||
def upload_real_name_files(self, token: str, file_org: str, file_lxr: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
模板实名资料上传
|
||||
|
||||
Args:
|
||||
token: 实名上传Token
|
||||
file_org: 图片完整的base64
|
||||
file_lxr: 企业联系人图片完整的base64(只有token中设置了联系人的才上传)
|
||||
|
||||
Returns:
|
||||
API响应结果
|
||||
"""
|
||||
upload_url = "https://netservice.vhostgo.com/wcfservice/Service1.svc/Wcf_AuditUploadFile"
|
||||
|
||||
# 构建请求数据
|
||||
data = {
|
||||
'token': token,
|
||||
'file_org': file_org,
|
||||
}
|
||||
|
||||
# 添加可选参数
|
||||
if file_lxr:
|
||||
data['file_lxr'] = file_lxr
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
try:
|
||||
# 发送JSON格式的POST请求
|
||||
jingrow.log_error("西部数码实名上传调试", f"发送POST请求,URL: {upload_url}, 数据: {data}")
|
||||
response = requests.post(upload_url, json=data, headers=headers, timeout=30)
|
||||
|
||||
response.raise_for_status()
|
||||
|
||||
try:
|
||||
result = response.json()
|
||||
except json.JSONDecodeError:
|
||||
jingrow.log_error("西部数码实名上传响应解析失败", response_text=response.text)
|
||||
result = {"status": "error", "message": "无法解析API响应"}
|
||||
|
||||
return result
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
jingrow.log_error("西部数码实名上传请求失败", error=str(e), url=upload_url)
|
||||
return {"status": "error", "message": f"API请求失败: {str(e)}"}
|
||||
|
||||
|
||||
def format_date(date):
|
||||
"""格式化域名到期时间"""
|
||||
@ -1221,6 +1298,7 @@ def get_domain_owner(name):
|
||||
# 返回所有者信息
|
||||
owner_data = {
|
||||
"name": domain_owner.name,
|
||||
"r_status": domain_owner.r_status,
|
||||
"title": domain_owner.title,
|
||||
"fullname": domain_owner.fullname,
|
||||
"c_regtype": domain_owner.c_regtype,
|
||||
@ -1708,3 +1786,89 @@ def get_west_domain_real_info(**data):
|
||||
except Exception as e:
|
||||
jingrow.log_error("域名实名信息查询响应解析失败", error=str(e))
|
||||
return {"status": "error", "message": "域名实名信息查询响应解析失败"}
|
||||
|
||||
|
||||
@jingrow.whitelist()
|
||||
def get_west_upload_token(**data):
|
||||
"""获取西部数码实名上传token"""
|
||||
client = get_west_client()
|
||||
if not client:
|
||||
return {"status": "error", "message": "API客户端初始化失败"}
|
||||
|
||||
c_sysid = data.get('c_sysid')
|
||||
f_type_org = data.get('f_type_org')
|
||||
f_code_org = data.get('f_code_org')
|
||||
f_type_lxr = data.get('f_type_lxr')
|
||||
f_code_lxr = data.get('f_code_lxr')
|
||||
|
||||
if not all([c_sysid, f_type_org, f_code_org]):
|
||||
return {"status": "error", "message": "缺少必要参数:c_sysid, f_type_org, f_code_org"}
|
||||
|
||||
response = client.get_upload_token(c_sysid, f_type_org, f_code_org, f_type_lxr, f_code_lxr)
|
||||
|
||||
if response.get("status") == "error":
|
||||
return response
|
||||
|
||||
try:
|
||||
# 检查响应格式
|
||||
if response.get("result") != 200:
|
||||
return {"status": "error", "message": "API查询失败"}
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"token": response.get("data"),
|
||||
"clientid": response.get("clientid")
|
||||
}
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
jingrow.log_error("获取实名上传token响应解析失败", error=str(e))
|
||||
return {"status": "error", "message": "获取实名上传token响应解析失败"}
|
||||
|
||||
|
||||
@jingrow.whitelist()
|
||||
def west_upload_real_name_files(**data):
|
||||
"""西部数码模板实名资料上传"""
|
||||
client = get_west_client()
|
||||
if not client:
|
||||
return {"status": "error", "message": "API客户端初始化失败"}
|
||||
|
||||
token = data.get('token')
|
||||
file_org = data.get('file_org')
|
||||
file_lxr = data.get('file_lxr')
|
||||
|
||||
if not all([token, file_org]):
|
||||
return {"status": "error", "message": "缺少必要参数:token, file_org"}
|
||||
|
||||
response = client.upload_real_name_files(token, file_org, file_lxr)
|
||||
|
||||
if response.get("status") == "error":
|
||||
return response
|
||||
|
||||
try:
|
||||
# 解析响应格式
|
||||
d = response.get("d", {})
|
||||
result = d.get("Result")
|
||||
msg = d.get("Msg", "")
|
||||
|
||||
if result == 200:
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "实名资料上传成功",
|
||||
"data": {
|
||||
"result": result,
|
||||
"msg": msg
|
||||
}
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"status": "error",
|
||||
"message": f"实名资料上传失败: {msg}"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
jingrow.log_error("实名资料上传响应解析失败", error=str(e))
|
||||
return {"status": "error", "message": "实名资料上传响应解析失败"}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user