690 lines
28 KiB
Vue
690 lines
28 KiB
Vue
<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>
|