162 lines
9.1 KiB
Vue
162 lines
9.1 KiB
Vue
<script setup lang="ts">
|
||
import { nextTick, reactive, ref } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
||
import { CheckCircle2, Mail, Phone } from '@lucide/vue'
|
||
import { registerMerchant } from '@/modules/auth/api/auth'
|
||
import AuthShell from '@/modules/auth/components/AuthShell.vue'
|
||
|
||
interface RegisterForm {
|
||
username: string
|
||
companyName: string
|
||
displayName: string
|
||
legalPerson: string
|
||
phone: string
|
||
contactEmail: string
|
||
countryCode: string
|
||
address: string
|
||
password: string
|
||
agreement: boolean
|
||
}
|
||
|
||
const router = useRouter()
|
||
const formRef = ref<FormInstance>()
|
||
const submitting = ref(false)
|
||
const submitted = ref(false)
|
||
const submittedAt = ref('')
|
||
const form = reactive<RegisterForm>({ username: '', companyName: '', displayName: '', legalPerson: '', phone: '', contactEmail: '', countryCode: 'CN', address: '', password: '', agreement: false })
|
||
|
||
const rules: FormRules<RegisterForm> = {
|
||
username: [
|
||
{ required: true, message: '请输入登录用户名', trigger: 'blur' },
|
||
{ pattern: /^[A-Za-z][A-Za-z0-9_.@-]{3,63}$/, message: '用户名须以字母开头,并由 4–64 位字母、数字或 _.@- 组成', trigger: 'blur' },
|
||
],
|
||
companyName: [
|
||
{ required: true, message: '请输入企业名称', trigger: 'blur' },
|
||
{ min: 2, max: 100, message: '企业名称长度应为 2–100 个字符', trigger: 'blur' },
|
||
],
|
||
displayName: [
|
||
{ required: true, message: '请输入联系人姓名', trigger: 'blur' },
|
||
{ max: 64, message: '联系人姓名最多 64 个字符', trigger: 'blur' },
|
||
],
|
||
legalPerson: [
|
||
{ max: 64, message: '法定代表人最多 64 个字符', trigger: 'blur' },
|
||
],
|
||
contactEmail: [
|
||
{ type: 'email', message: '请输入有效的邮箱地址', trigger: 'blur' },
|
||
],
|
||
phone: [
|
||
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的中国大陆手机号', trigger: 'blur' },
|
||
],
|
||
password: [
|
||
{ required: true, message: '请设置登录密码', trigger: 'blur' },
|
||
{ min: 8, max: 72, message: '密码长度应为 8–72 位', trigger: 'blur' },
|
||
],
|
||
agreement: [{ validator: (_rule, value, callback) => value ? callback() : callback(new Error('请先阅读并同意服务协议和隐私政策')), trigger: 'change' }],
|
||
}
|
||
|
||
async function submit() {
|
||
if (!formRef.value || submitting.value) return
|
||
const valid = await formRef.value.validate().catch(() => false)
|
||
if (!valid) {
|
||
await nextTick()
|
||
document.querySelector<HTMLElement>('.auth-form-panel .el-form-item.is-error input')?.focus()
|
||
return
|
||
}
|
||
|
||
submitting.value = true
|
||
try {
|
||
const legalPerson = form.legalPerson.trim()
|
||
await registerMerchant({
|
||
username: form.username.trim(),
|
||
password: form.password,
|
||
displayName: form.displayName.trim(),
|
||
companyName: form.companyName.trim(),
|
||
...(legalPerson ? { legalPerson } : {}),
|
||
phone: form.phone.trim(),
|
||
contactEmail: form.contactEmail.trim() || undefined,
|
||
countryCode: form.countryCode,
|
||
address: form.address.trim() || undefined,
|
||
})
|
||
submittedAt.value = new Intl.DateTimeFormat('zh-CN', {
|
||
year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false,
|
||
}).format(new Date())
|
||
submitted.value = true
|
||
ElMessage.success('企业账号注册成功')
|
||
} catch (error) {
|
||
ElMessage.error(error instanceof Error ? error.message : '注册失败,请检查信息后重试')
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
}
|
||
|
||
</script>
|
||
|
||
<template>
|
||
<AuthShell
|
||
variant="register"
|
||
switch-text="已有企业账号?"
|
||
switch-label="立即登录"
|
||
switch-to="/login"
|
||
visual-title="加入柏悦,开启高效跨境物流协作"
|
||
visual-description="创建企业账号后即可进入客户工作台,维护团队、资料与头程订单。"
|
||
:features="['注册成功即可登录', '企业资料独立审核', '审核期间可维护订单草稿']"
|
||
>
|
||
<div class="auth-form-content auth-form-content--register">
|
||
<template v-if="!submitted">
|
||
<div class="auth-form-heading">
|
||
<h1>企业注册</h1>
|
||
<p>填写账号与企业基本信息,注册成功后即可登录。</p>
|
||
</div>
|
||
<el-form ref="formRef" :model="form" :rules="rules" class="register-form" label-position="top" size="large" @submit.prevent="submit">
|
||
<section class="register-section" aria-labelledby="account-section-title">
|
||
<h2 id="account-section-title">账号信息</h2>
|
||
<div class="register-form-grid">
|
||
<el-form-item label="登录用户名" prop="username" required><el-input v-model="form.username" autocomplete="username" maxlength="64" placeholder="以字母开头,支持数字和 _.@-" /></el-form-item>
|
||
<el-form-item label="登录密码" prop="password" required><el-input v-model="form.password" type="password" autocomplete="new-password" maxlength="72" show-password placeholder="请设置 8–72 位密码" /></el-form-item>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="register-section" aria-labelledby="company-section-title">
|
||
<h2 id="company-section-title">企业信息</h2>
|
||
<div class="register-form-grid">
|
||
<el-form-item label="企业名称" prop="companyName" class="register-form-full" required><el-input v-model="form.companyName" maxlength="100" placeholder="请输入营业执照上的企业名称" /></el-form-item>
|
||
<el-form-item label="法定代表人(选填)" prop="legalPerson"><el-input v-model="form.legalPerson" maxlength="64" placeholder="可在企业资料中后续补充" /></el-form-item>
|
||
<el-form-item label="国家/地区" prop="countryCode"><el-select v-model="form.countryCode" class="register-select"><el-option label="中国大陆(CN)" value="CN" /></el-select></el-form-item>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="register-section" aria-labelledby="contact-section-title">
|
||
<h2 id="contact-section-title">联系信息</h2>
|
||
<div class="register-form-grid">
|
||
<el-form-item label="联系人" prop="displayName" required><el-input v-model="form.displayName" maxlength="64" placeholder="请输入联系人姓名" /></el-form-item>
|
||
<el-form-item label="登录手机号" prop="phone" required><el-input v-model="form.phone" type="tel" autocomplete="tel" inputmode="numeric" maxlength="11" placeholder="请输入 11 位手机号" :prefix-icon="Phone" /><span class="register-security-note">注册时同时初始化公司联系电话;注册后两者可分别修改,互不联动。</span></el-form-item>
|
||
<el-form-item label="联系邮箱" prop="contactEmail"><el-input v-model="form.contactEmail" type="email" autocomplete="email" maxlength="128" placeholder="选填,用于接收业务通知" :prefix-icon="Mail" /></el-form-item>
|
||
<el-form-item label="企业地址" prop="address"><el-input v-model="form.address" maxlength="255" placeholder="选填,最多 255 个字符" /></el-form-item>
|
||
</div>
|
||
</section>
|
||
|
||
<el-form-item prop="agreement" class="agreement-item">
|
||
<div class="agreement-control">
|
||
<el-checkbox v-model="form.agreement"><span class="agreement-required" aria-hidden="true">*</span>我已阅读并同意</el-checkbox>
|
||
<span><RouterLink to="/legal/terms" target="_blank" rel="noopener">《用户服务协议》</RouterLink> 和 <RouterLink to="/legal/privacy" target="_blank" rel="noopener">《隐私政策》</RouterLink></span>
|
||
</div>
|
||
</el-form-item>
|
||
<p class="register-security-note">注册成功后账号可立即登录;首次登录需上传营业执照,法人身份证、货代资质证书和银行开户许可证可选填。提交平台审核通过后才能提交订单。</p>
|
||
<el-button native-type="submit" class="register-submit" type="success" :loading="submitting">注册企业账号</el-button>
|
||
</el-form>
|
||
</template>
|
||
|
||
<section v-else class="registration-result" aria-live="polite">
|
||
<CheckCircle2 :size="42" />
|
||
<h1>企业账号注册成功</h1>
|
||
<p><strong>{{ form.username }}</strong> 现在可以直接登录客户工作台,无需等待注册审核。</p>
|
||
<dl><div><dt>企业名称</dt><dd>{{ form.companyName }}</dd></div><div><dt>登录账号</dt><dd>{{ form.username }}</dd></div><div><dt>注册时间</dt><dd>{{ submittedAt }}</dd></div><div><dt>账号状态</dt><dd><el-tag type="success" effect="light">可登录</el-tag></dd></div></dl>
|
||
<div class="registration-next-step" role="note"><strong>提交订单前还需完成企业审核</strong><span>登录后请在“企业资料”上传营业执照并提交审核;法人身份证及其他资质可选填。审核期间仍可维护资料、成员和订单草稿。</span></div>
|
||
<div class="registration-result-actions"><el-button type="primary" @click="router.push({ path: '/login', query: { account: form.username } })">立即登录</el-button></div>
|
||
</section>
|
||
</div>
|
||
</AuthShell>
|
||
</template>
|