jcloud/dashboard/src2/components/JsiteDomainUploadRealNameDialog.vue

358 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<Dialog v-bind="$attrs" :options="{ title: '实名资料上传', size: 'lg' }" v-model="show">
<template #body-content>
<div class="p-4 sm:p-6">
<div class="space-y-4">
<!-- 域名显示 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">域名</label>
<div class="text-base text-black font-semibold">{{ domainDoc?.domain || domain }}</div>
</div>
<!-- 资料状态 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">资料状态</label>
<div class="flex space-x-2">
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
未传图片
</span>
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
未实名
</span>
</div>
</div>
<!-- 域名所有者 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">域名所有者</label>
<div class="text-sm text-gray-900">
(个人) 旷蓓娟
</div>
</div>
<!-- 所有者证件号码 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">所有者证件号码</label>
<div class="flex space-x-3">
<select
v-model="formData.idType"
class="px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white text-sm"
>
<option value="SFZ">身份证</option>
<option value="HZ">护照</option>
<option value="GAJMTX">港澳居民来往内地通行证</option>
<option value="TWJMTX">台湾居民来往大陆通行证</option>
<option value="WJLSFZ">外国人永久居留身份证</option>
<option value="GAJZZ">港澳台居民居住证</option>
<option value="ORG">组织机构代码证</option>
<option value="YYZZ">工商营业执照</option>
<option value="TYDM">统一社会信用代码证书</option>
</select>
<input
type="text"
v-model="formData.idNumber"
class="flex-1 px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm"
placeholder="请输入证件号码"
/>
</div>
</div>
<!-- 所有者证件材料 -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">所有者证件材料</label>
<div class="flex space-x-4">
<!-- 上传区域 -->
<div class="flex-1">
<div
@click="triggerFileInput"
@dragover.prevent
@drop.prevent="handleDrop"
class="border-2 border-dashed border-gray-300 rounded-md p-6 text-center cursor-pointer hover:border-blue-400 hover:bg-blue-50 transition-colors duration-200"
>
<div class="text-green-500 mb-2">
<svg class="w-8 h-8 mx-auto" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM6.293 6.707a1 1 0 010-1.414l3-3a1 1 0 011.414 0l3 3a1 1 0 01-1.414 1.414L11 5.414V13a1 1 0 11-2 0V5.414L7.707 6.707a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</div>
<p class="text-sm text-gray-600 font-medium">点击上传</p>
</div>
</div>
<!-- 说明文字 -->
<div class="flex-1">
<div class="text-xs text-gray-600 leading-relaxed mb-3">
请保证图片中证件四角完整证件上文字信息完整清晰请使用原件拍摄或彩色扫描件不要用复印件否则无法通过审核
</div>
</div>
</div>
</div>
<!-- 已上传文件列表 -->
<div v-if="uploadedFiles.length > 0" class="space-y-2">
<div
v-for="(file, index) in uploadedFiles"
:key="index"
class="flex items-center justify-between bg-gray-50 rounded-md p-2"
>
<div class="flex items-center">
<svg class="w-4 h-4 text-blue-600 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd" />
</svg>
<div>
<div class="text-xs 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"
>
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
</div>
</div>
</div>
</div>
<!-- 隐藏的文件输入框 -->
<input
ref="fileInput"
type="file"
accept="image/*,.pdf"
multiple
class="hidden"
@change="handleFileSelect"
/>
</template>
<template #actions>
<div class="w-full flex justify-end space-x-3">
<button
type="button"
class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none"
@click="$emit('close')"
>
重置
</button>
<button
type="button"
class="px-4 py-2 bg-black border border-transparent rounded-md text-sm font-medium text-white hover:bg-gray-800 focus:outline-none disabled:bg-gray-300 disabled:cursor-not-allowed"
@click="submitUpload"
:disabled="loading || !isValid"
>
{{ loading ? '提交中...' : '提交' }}
</button>
</div>
</template>
</Dialog>
</template>
<script>
import { Dialog, createResource } from 'jingrow-ui';
import { toast } from 'vue-sonner';
export default {
name: 'JsiteDomainUploadRealNameDialog',
components: {
Dialog
},
props: {
domain: String,
domainDoc: Object
},
emits: ['success', 'close'],
data() {
return {
show: true,
loading: false,
formData: {
idType: 'SFZ',
idNumber: ''
},
uploadedFiles: []
};
},
computed: {
isValid() {
return this.formData.idNumber.trim() && this.uploadedFiles.length > 0;
}
},
resources: {
getOwnerInfo() {
return {
url: 'jcloud.api.domain_west.get_domain_owner',
params: {
name: this.domainDoc?.domain_owner
},
onSuccess: (response) => {
return response;
},
onError: (error) => {
console.error('获取所有者信息失败:', error);
}
};
}
},
mounted() {
this.loadOwnerInfo();
},
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 => {
// 检查文件大小 (5MB限制)
if (file.size > 5 * 1024 * 1024) {
alert(`文件 ${file.name} 超过 5MB 限制`);
return false;
}
return true;
});
this.uploadedFiles = [...this.uploadedFiles, ...validFiles];
},
removeFile(index) {
this.uploadedFiles.splice(index, 1);
},
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];
},
async submitUpload() {
if (!this.validateForm()) {
return;
}
this.loading = true;
try {
// 创建FormData对象
const formData = new FormData();
// 获取域名
const domain = this.domainDoc?.domain || this.domain;
// 验证域名是否有效
if (!domain || domain === '36h8on65rd') {
console.error('域名信息无效:', domain);
alert('域名信息无效,请重试');
return;
}
// 确保域名格式正确
if (!domain.includes('.')) {
console.error('域名格式无效:', domain);
alert('域名格式无效,请重试');
return;
}
formData.append('domain', domain);
formData.append('idType', this.formData.idType);
formData.append('idNumber', this.formData.idNumber);
// 添加文件
this.uploadedFiles.forEach((file, index) => {
formData.append(`files_${index}`, file);
});
// 调用后端上传API
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
this.loading = false;
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
// Jingrow 响应格式:{message: {...}}
if (response && response.message && response.message.status === "success") {
// 直接关闭弹窗,不显示 toast
this.$emit('success');
this.$emit('close');
} else {
const errorMessage = response?.message?.message || response?.message || '上传失败,请重试';
console.error('上传失败:', errorMessage);
alert(errorMessage);
}
} catch (error) {
console.error('解析响应失败:', error);
alert('上传失败,请重试');
}
} else {
console.error('上传失败:', xhr.status, xhr.statusText);
alert('上传失败,请重试');
}
}
};
xhr.open('POST', '/api/action/jcloud.api.domain_west.upload_domain_real_name_files', true);
xhr.setRequestHeader('Accept', 'application/json');
// 添加CSRF token
if (window.csrf_token && window.csrf_token !== '{{ csrf_token }}') {
xhr.setRequestHeader('X-Jingrow-CSRF-Token', window.csrf_token);
}
xhr.send(formData);
} catch (error) {
console.error('上传实名资料失败:', error);
alert('上传失败,请重试');
} finally {
this.loading = false;
}
},
validateForm() {
if (!this.formData.idNumber.trim()) {
alert('请填写证件号码');
return false;
}
if (this.uploadedFiles.length === 0) {
alert('请上传证件材料');
return false;
}
return true;
},
async loadOwnerInfo() {
try {
if (this.domainDoc && this.domainDoc.domain_owner) {
// 获取域名所有者信息
const response = await this.$resources.getOwnerInfo.submit();
if (response && response.status === 'Success' && response.data) {
const owner = response.data;
// 填充身份证号码
if (owner.c_idnum_gswl) {
this.formData.idNumber = owner.c_idnum_gswl;
}
// 填充证件类型
if (owner.c_idtype_gswl) {
this.formData.idType = owner.c_idtype_gswl;
}
}
}
} catch (error) {
console.error('获取所有者信息失败:', error);
}
},
}
};
</script>