chore: 初始化平台管理端
This commit is contained in:
689
src/views/onboarding/status/index.vue
Normal file
689
src/views/onboarding/status/index.vue
Normal file
@@ -0,0 +1,689 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { fetchUploadFile } from '@/api/files'
|
||||
import { bindInitialTenantSubscription, submitTenantVerification } from '@/api/tenant-onboarding'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
// 1. 从 URL 读取 tenantId / tenantPackageId,后续提交时携带
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const tenantId = computed(() => route.query.tenantId as string | undefined)
|
||||
const tenantPackageId = computed(() => route.query.tenantPackageId as string | undefined)
|
||||
const { t } = useI18n()
|
||||
|
||||
// 定义表单数据接口
|
||||
interface ProfileForm {
|
||||
BusinessLicenseNumber: string
|
||||
BusinessLicenseUrl: string
|
||||
LegalPersonName: string
|
||||
LegalPersonIdNumber: string
|
||||
LegalPersonIdFrontUrl: string
|
||||
LegalPersonIdBackUrl: string
|
||||
BankAccountName: string
|
||||
BankName: string
|
||||
BankAccountNumber: string
|
||||
}
|
||||
|
||||
// 使用 reactive 定义响应式数据
|
||||
const form = reactive<ProfileForm>({
|
||||
BusinessLicenseNumber: '',
|
||||
BusinessLicenseUrl: '',
|
||||
LegalPersonName: '',
|
||||
LegalPersonIdNumber: '',
|
||||
LegalPersonIdFrontUrl: '',
|
||||
LegalPersonIdBackUrl: '',
|
||||
BankAccountName: '',
|
||||
BankName: '',
|
||||
BankAccountNumber: ''
|
||||
})
|
||||
|
||||
type UploadField = keyof Pick<
|
||||
ProfileForm,
|
||||
'BusinessLicenseUrl' | 'LegalPersonIdFrontUrl' | 'LegalPersonIdBackUrl'
|
||||
>
|
||||
|
||||
// 2. 上传状态与文件名
|
||||
const isUploading = reactive<Record<UploadField, boolean>>({
|
||||
BusinessLicenseUrl: false,
|
||||
LegalPersonIdFrontUrl: false,
|
||||
LegalPersonIdBackUrl: false
|
||||
})
|
||||
|
||||
const uploadedFileName = reactive<Record<UploadField, string>>({
|
||||
BusinessLicenseUrl: '',
|
||||
LegalPersonIdFrontUrl: '',
|
||||
LegalPersonIdBackUrl: ''
|
||||
})
|
||||
|
||||
// 3. 隐藏 input 引用
|
||||
const businessLicenseInputRef = ref<HTMLInputElement | null>(null)
|
||||
const legalPersonFrontInputRef = ref<HTMLInputElement | null>(null)
|
||||
const legalPersonBackInputRef = ref<HTMLInputElement | null>(null)
|
||||
|
||||
const fileInputMap: Record<UploadField, typeof businessLicenseInputRef> = {
|
||||
BusinessLicenseUrl: businessLicenseInputRef,
|
||||
LegalPersonIdFrontUrl: legalPersonFrontInputRef,
|
||||
LegalPersonIdBackUrl: legalPersonBackInputRef
|
||||
}
|
||||
|
||||
const openFileDialog = (field: UploadField) => {
|
||||
// 3.1 触发隐藏 input 选择文件
|
||||
fileInputMap[field].value?.click()
|
||||
}
|
||||
|
||||
const handleFileChange = async (field: UploadField, event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
const file = target.files?.[0]
|
||||
if (!file) return
|
||||
|
||||
// 3.2 清空 input,支持重复选择同一文件
|
||||
target.value = ''
|
||||
|
||||
await uploadFile(field, file)
|
||||
}
|
||||
|
||||
const uploadFile = async (field: UploadField, file: File) => {
|
||||
// 1. 设置上传中状态
|
||||
isUploading[field] = true
|
||||
try {
|
||||
// 2. 调用上传接口并获取地址
|
||||
// 2.1 入驻资质上传目前统一使用 business_license 类型
|
||||
const res = await fetchUploadFile(file, 'business_license')
|
||||
const url = res.url || ''
|
||||
if (!url) {
|
||||
alert('上传失败,请重试')
|
||||
return
|
||||
}
|
||||
|
||||
// 3. 写入表单地址与文件名
|
||||
form[field] = url
|
||||
uploadedFileName[field] = res.fileName || file.name
|
||||
} catch (error) {
|
||||
alert((error as Error).message || '上传失败,请重试')
|
||||
} finally {
|
||||
isUploading[field] = false
|
||||
}
|
||||
}
|
||||
|
||||
// 提交处理
|
||||
const isSubmitting = ref<boolean>(false)
|
||||
|
||||
const handleSubmit = async () => {
|
||||
// 1. 表单基本校验
|
||||
if (!form.BusinessLicenseUrl || !form.LegalPersonIdFrontUrl || !form.LegalPersonIdBackUrl) {
|
||||
alert('请确保所有证件照片已上传')
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 校验租户与套餐参数
|
||||
if (!tenantId.value || !tenantPackageId.value) {
|
||||
ElMessage.warning(t('onboarding.messages.missingTenantInfo'))
|
||||
return
|
||||
}
|
||||
|
||||
if (isSubmitting.value) return
|
||||
|
||||
// 3. 组装实名提交命令(字段转为后端 camelCase)
|
||||
const verificationCommand: Api.Tenant.SubmitTenantVerificationCommand = {
|
||||
tenantId: tenantId.value,
|
||||
businessLicenseNumber: form.BusinessLicenseNumber,
|
||||
businessLicenseUrl: form.BusinessLicenseUrl,
|
||||
legalPersonName: form.LegalPersonName,
|
||||
legalPersonIdNumber: form.LegalPersonIdNumber,
|
||||
legalPersonIdFrontUrl: form.LegalPersonIdFrontUrl,
|
||||
legalPersonIdBackUrl: form.LegalPersonIdBackUrl,
|
||||
bankAccountName: form.BankAccountName,
|
||||
bankAccountNumber: form.BankAccountNumber,
|
||||
bankName: form.BankName
|
||||
}
|
||||
|
||||
// 4. 串行执行:提交实名资料 -> 绑定套餐订阅
|
||||
isSubmitting.value = true
|
||||
try {
|
||||
await submitTenantVerification(tenantId.value, verificationCommand)
|
||||
|
||||
await bindInitialTenantSubscription(tenantId.value, {
|
||||
tenantId: tenantId.value,
|
||||
tenantPackageId: tenantPackageId.value,
|
||||
autoRenew: false
|
||||
})
|
||||
|
||||
ElMessage.success(t('onboarding.messages.submitSuccess'))
|
||||
|
||||
await router.push({
|
||||
name: 'TenantOnboardingWaiting',
|
||||
query: {
|
||||
tenantId: tenantId.value,
|
||||
tenantPackageId: tenantPackageId.value
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[OnboardingStatus] 提交审核失败:', error)
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-screen flex overflow-hidden bg-slate-50 text-slate-800 font-sans antialiased">
|
||||
<!-- 左侧:信息与指引 (Left Side - Context) -->
|
||||
<div
|
||||
class="hidden lg:flex lg:w-4/12 relative bg-slate-900 flex-col justify-between p-12 text-white"
|
||||
>
|
||||
<!-- 背景图案 -->
|
||||
<div class="absolute inset-0 overflow-hidden pointer-events-none">
|
||||
<div
|
||||
class="absolute top-0 right-0 w-96 h-96 bg-indigo-600/20 rounded-full blur-3xl -translate-y-1/2 translate-x-1/2"
|
||||
></div>
|
||||
<div
|
||||
class="absolute bottom-0 left-0 w-80 h-80 bg-blue-600/20 rounded-full blur-3xl translate-y-1/2 -translate-x-1/2"
|
||||
></div>
|
||||
<!-- 网格纹理 -->
|
||||
<div
|
||||
class="absolute inset-0"
|
||||
style="
|
||||
background-image: radial-gradient(rgb(255 255 255 / 10%) 1px, transparent 1px);
|
||||
background-size: 32px 32px;
|
||||
opacity: 0.2;
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<!-- 顶部 Logo -->
|
||||
<div class="relative z-10 flex items-center gap-2 text-indigo-300">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
||||
<line x1="3" x2="21" y1="9" y2="9" />
|
||||
<line x1="9" x2="9" y1="21" y2="9" />
|
||||
</svg>
|
||||
<span class="font-bold tracking-wide text-white">CloudSaaS</span>
|
||||
</div>
|
||||
|
||||
<!-- 中间说明 -->
|
||||
<div class="relative z-10">
|
||||
<h2 class="text-3xl font-bold mb-6">最后一步:<br />实名认证与资质审核</h2>
|
||||
<p class="text-slate-300 leading-relaxed mb-8">
|
||||
依据相关法律法规,我们需要验证您的企业资质以开通正式服务。您提交的所有信息将通过银行级加密传输,仅用于资质审核。
|
||||
</p>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-start gap-4">
|
||||
<div
|
||||
class="w-8 h-8 rounded-full bg-indigo-500/20 flex items-center justify-center shrink-0 text-indigo-400 mt-1"
|
||||
>
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-medium text-white">注册账号</h4>
|
||||
<p class="text-sm text-slate-400">已完成</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div
|
||||
class="w-8 h-8 rounded-full bg-indigo-500/20 flex items-center justify-center shrink-0 text-indigo-400 mt-1"
|
||||
>
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-medium text-white">选择套餐</h4>
|
||||
<p class="text-sm text-slate-400">已完成</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-4">
|
||||
<div
|
||||
class="w-8 h-8 rounded-full bg-white text-indigo-900 font-bold flex items-center justify-center shrink-0 mt-1 shadow-lg shadow-indigo-900/50"
|
||||
>
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-medium text-white">资质审核</h4>
|
||||
<p class="text-sm text-indigo-300">进行中...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部帮助 -->
|
||||
<div class="relative z-10 text-sm text-slate-400">
|
||||
遇到问题?<a href="#" class="text-white underline decoration-indigo-500 underline-offset-4"
|
||||
>联系人工客服</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:资料表单 (Right Side - Form) -->
|
||||
<div class="flex-1 flex flex-col h-full bg-white overflow-hidden relative">
|
||||
<!-- 顶部导航栏 (Mobile/Context) -->
|
||||
<div
|
||||
class="h-16 border-b border-slate-100 flex items-center justify-between px-6 shrink-0 bg-white/80 backdrop-blur z-20"
|
||||
>
|
||||
<span class="font-semibold text-slate-700">租户资料补全</span>
|
||||
<div
|
||||
class="text-xs text-slate-400 bg-slate-50 px-3 py-1 rounded-full border border-slate-100"
|
||||
>
|
||||
资料仅用于审核,不会泄露
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 可滚动区域 -->
|
||||
<div class="flex-1 overflow-y-auto p-6 md:p-10 scroll-smooth">
|
||||
<div class="max-w-3xl mx-auto space-y-10 pb-20">
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<!-- 模块 1: 企业资质 (Business License) -->
|
||||
<section class="space-y-6">
|
||||
<div class="flex items-center gap-3 pb-2 border-b border-slate-100">
|
||||
<div class="p-2 bg-indigo-50 text-indigo-600 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="20" height="14" x="2" y="3" rx="2" />
|
||||
<line x1="8" x2="16" y1="21" y2="21" />
|
||||
<line x1="12" x2="12" y1="17" y2="21" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-bold text-slate-800">企业资质信息</h3>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- 营业执照编号 -->
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
营业执照编号 <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="form.BusinessLicenseNumber"
|
||||
placeholder="请输入统一社会信用代码"
|
||||
class="w-full px-4 py-2.5 bg-white border border-slate-200 rounded-lg text-sm focus:outline-none focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/10 transition-all placeholder:text-slate-400"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 营业执照上传 -->
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
营业执照照片 <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<!-- 上传组件 -->
|
||||
<div
|
||||
class="upload-card relative border-2 border-dashed border-slate-300 rounded-xl p-8 flex flex-col items-center justify-center text-center cursor-pointer transition-all bg-slate-50 min-h-[160px]"
|
||||
:class="{ 'opacity-60 pointer-events-none': isUploading.BusinessLicenseUrl }"
|
||||
@click="openFileDialog('BusinessLicenseUrl')"
|
||||
>
|
||||
<input
|
||||
ref="businessLicenseInputRef"
|
||||
type="file"
|
||||
accept="image/*,application/pdf"
|
||||
class="hidden"
|
||||
@change="(e) => handleFileChange('BusinessLicenseUrl', e)"
|
||||
/>
|
||||
<div v-if="!form.BusinessLicenseUrl" class="flex flex-col items-center">
|
||||
<div
|
||||
class="w-12 h-12 bg-white rounded-full shadow-sm flex items-center justify-center text-indigo-500 mb-3"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
||||
<polyline points="17 8 12 3 7 8" />
|
||||
<line x1="12" x2="12" y1="3" y2="15" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="text-sm font-medium text-slate-700">点击上传营业执照</p>
|
||||
<p class="text-xs text-slate-400 mt-1">支持 JPG, PNG, PDF (最大 5MB)</p>
|
||||
</div>
|
||||
<!-- 上传成功后的预览状态 -->
|
||||
<div
|
||||
v-else
|
||||
class="w-full flex items-center justify-between bg-white p-3 rounded-lg border border-indigo-100 shadow-sm"
|
||||
>
|
||||
<div class="flex items-center gap-3 overflow-hidden">
|
||||
<div
|
||||
class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center text-indigo-600 shrink-0"
|
||||
>IMG</div
|
||||
>
|
||||
<div class="flex flex-col text-left truncate">
|
||||
<span class="text-sm font-medium text-slate-700 truncate">{{
|
||||
uploadedFileName.BusinessLicenseUrl || 'license_scan_2025.jpg'
|
||||
}}</span>
|
||||
<span class="text-xs text-green-600">上传成功</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
@click.stop="form.BusinessLicenseUrl = ''"
|
||||
class="text-slate-400 hover:text-rose-500 p-2"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M18 6 6 18" />
|
||||
<path d="m6 6 12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 模块 2: 法人信息 (Legal Person) -->
|
||||
<section class="space-y-6 pt-4">
|
||||
<div class="flex items-center gap-3 pb-2 border-b border-slate-100">
|
||||
<div class="p-2 bg-indigo-50 text-indigo-600 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87" />
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-bold text-slate-800">法人身份信息</h3>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- 法人姓名 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
法人姓名 <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="form.LegalPersonName"
|
||||
class="w-full px-4 py-2.5 bg-white border border-slate-200 rounded-lg text-sm focus:outline-none focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/10 transition-all placeholder:text-slate-400"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 身份证号 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
身份证号 <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="form.LegalPersonIdNumber"
|
||||
class="w-full px-4 py-2.5 bg-white border border-slate-200 rounded-lg text-sm focus:outline-none focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/10 transition-all placeholder:text-slate-400"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 身份证正面 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
身份证正面 (人像面) <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<div
|
||||
class="upload-card border-2 border-dashed border-slate-300 rounded-xl p-4 flex flex-col items-center justify-center text-center cursor-pointer bg-slate-50 h-32"
|
||||
:class="{ 'opacity-60 pointer-events-none': isUploading.LegalPersonIdFrontUrl }"
|
||||
@click="openFileDialog('LegalPersonIdFrontUrl')"
|
||||
>
|
||||
<input
|
||||
ref="legalPersonFrontInputRef"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
class="hidden"
|
||||
@change="(e) => handleFileChange('LegalPersonIdFrontUrl', e)"
|
||||
/>
|
||||
<div v-if="!form.LegalPersonIdFrontUrl" class="text-slate-500 text-xs">
|
||||
<svg
|
||||
class="w-8 h-8 mx-auto mb-2 text-indigo-400 opacity-80"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
||||
<circle cx="8.5" cy="8.5" r="1.5" />
|
||||
<polyline points="21 15 16 10 5 21" />
|
||||
</svg>
|
||||
点击上传人像面
|
||||
</div>
|
||||
<div v-else class="text-green-600 flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
<span class="text-sm">已选择文件</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 身份证反面 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
身份证反面 (国徽面) <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<div
|
||||
class="upload-card border-2 border-dashed border-slate-300 rounded-xl p-4 flex flex-col items-center justify-center text-center cursor-pointer bg-slate-50 h-32"
|
||||
:class="{ 'opacity-60 pointer-events-none': isUploading.LegalPersonIdBackUrl }"
|
||||
@click="openFileDialog('LegalPersonIdBackUrl')"
|
||||
>
|
||||
<input
|
||||
ref="legalPersonBackInputRef"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
class="hidden"
|
||||
@change="(e) => handleFileChange('LegalPersonIdBackUrl', e)"
|
||||
/>
|
||||
<div v-if="!form.LegalPersonIdBackUrl" class="text-slate-500 text-xs">
|
||||
<svg
|
||||
class="w-8 h-8 mx-auto mb-2 text-indigo-400 opacity-80"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
||||
<line x1="3" y1="9" x2="21" y2="9" />
|
||||
<line x1="9" y1="21" x2="9" y2="9" />
|
||||
</svg>
|
||||
点击上传国徽面
|
||||
</div>
|
||||
<div v-else class="text-green-600 flex items-center gap-2">
|
||||
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
<span class="text-sm">已选择文件</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 模块 3: 对公账户 (Bank Account) -->
|
||||
<section class="space-y-6 pt-4">
|
||||
<div class="flex items-center gap-3 pb-2 border-b border-slate-100">
|
||||
<div class="p-2 bg-indigo-50 text-indigo-600 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M3 21h18" />
|
||||
<path d="M5 21V7" />
|
||||
<path d="M19 21V7" />
|
||||
<path d="M4 7h16" />
|
||||
<path d="M15 7 12 2 9 7" />
|
||||
<line x1="10" x2="10" y1="14" y2="17" />
|
||||
<line x1="14" x2="14" y1="14" y2="17" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-lg font-bold text-slate-800">对公结算账户</h3>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<!-- 开户名 -->
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
开户名 (公司名称) <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="form.BankAccountName"
|
||||
placeholder="需与营业执照名称一致"
|
||||
class="w-full px-4 py-2.5 bg-white border border-slate-200 rounded-lg text-sm focus:outline-none focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/10 transition-all placeholder:text-slate-400"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 开户行 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
开户银行 <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="form.BankName"
|
||||
placeholder="如:招商银行北京分行"
|
||||
class="w-full px-4 py-2.5 bg-white border border-slate-200 rounded-lg text-sm focus:outline-none focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/10 transition-all placeholder:text-slate-400"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 银行账号 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700 mb-2">
|
||||
银行账号 <span class="text-rose-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="form.BankAccountNumber"
|
||||
class="w-full px-4 py-2.5 bg-white border border-slate-200 rounded-lg text-sm focus:outline-none focus:border-indigo-500 focus:ring-4 focus:ring-indigo-500/10 transition-all placeholder:text-slate-400 font-mono"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div class="pt-8 flex items-center justify-end gap-4 border-t border-slate-100 mt-10">
|
||||
<button
|
||||
type="button"
|
||||
class="px-6 py-2.5 rounded-lg text-slate-500 hover:bg-slate-50 hover:text-slate-700 font-medium transition-colors"
|
||||
>
|
||||
上一步
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="isSubmitting"
|
||||
:class="{ 'opacity-60 cursor-not-allowed': isSubmitting }"
|
||||
class="flex items-center gap-2 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold py-2.5 px-8 rounded-lg shadow-lg shadow-indigo-500/30 transition-all transform hover:-translate-y-0.5 active:translate-y-0 disabled:hover:bg-indigo-600"
|
||||
>
|
||||
提交审核
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M5 12h14" />
|
||||
<path d="m12 5 7 7-7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 底部版权 (Mobile) -->
|
||||
<div class="text-center text-xs text-slate-400 pb-6 md:hidden">
|
||||
© 2025 CloudSaaS Inc.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 自定义滚动条,让右侧滚动更优雅 */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #cbd5e1;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.upload-card:hover {
|
||||
background-color: #f5f3ff; /* indigo-50 */
|
||||
border-color: #6366f1; /* indigo-500 */
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user