feat(tender): 企业注册与 h5 对齐(一站式表单 + 证件上传 + OCR 回填);修复登录/注册代理路由 404
- 新增 app/components/HjcEnterpriseForm.vue:与 h5 EnterpriseForm 行为一致的共享表单,
字段集 / 必填规则 / OCR 回填 / 提示文案逐条对齐
- register.vue:一站式注册,一次性提交企业 + 经办人 + 授权 + 证件材料;
企业联系电话、企业地址选填,其余(含企业邮箱)必填,4 类证件必传
- tender/qualification.vue:改用共享组件,补「经办人身份证号」,
以真实文件上传 + OCR 取代原「证件 URL 文本框」;
审核中(0)/已通过(1) 只读,驳回(2)/未提交(-1) 可编辑重提
- 新增 server/api/tender/upload.post.ts(multipart 原样转发 → /hjc/auth/upload,匿名,
登录前后均可用)与 server/api/tender/ocr/recognize.post.ts(→ /hjc/ocr/recognize)
- 修正 datetime-local(YYYY-MM-DDTHH:mm)与后端 yyyy-MM-dd HH:mm:ss 的格式转换
- fix: server/api/tender/auth/{login,register}.post.ts 实际路由为 /api/tender/auth/*,
而客户端调用 /api/tender/{login,register},导致登录与注册此前均 404;
已按文件注释与同级接口约定移至扁平路径 server/api/tender/{login,register}.post.ts
- register / login / enterprise-save 三个代理改为原样透传 ApiResult{code,message,data},
useHjcAuth 与资质页按 code===0 判定,避免后端校验失败信息被吞掉
This commit is contained in:
+46
-31
@@ -1,37 +1,31 @@
|
||||
<template>
|
||||
<div class="min-h-[60vh] flex items-center justify-center px-4">
|
||||
<div class="w-full max-w-md rounded-lg border border-gray-200 p-8">
|
||||
<div class="min-h-[60vh] flex items-center justify-center px-4 py-10">
|
||||
<div class="w-full max-w-2xl rounded-lg border border-gray-200 p-8">
|
||||
<h1 class="text-2xl font-bold text-center text-gray-900">企业注册</h1>
|
||||
<p class="mt-2 text-center text-sm text-gray-500">填写企业与经办人信息、上传证件后提交审核</p>
|
||||
|
||||
<form class="mt-6 space-y-4" @submit.prevent="submitForm">
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">企业名称</label>
|
||||
<input v-model="form.enterpriseName" class="mt-1 w-full rounded-md border border-gray-300 px-4 py-2 text-sm" placeholder="企业名称" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">登录密码</label>
|
||||
<input v-model="form.password" type="password" class="mt-1 w-full rounded-md border border-gray-300 px-4 py-2 text-sm" placeholder="密码" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">纳税人识别号</label>
|
||||
<input v-model="form.creditCode" class="mt-1 w-full rounded-md border border-gray-300 px-4 py-2 text-sm" placeholder="统一社会信用代码" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">企业联系电话</label>
|
||||
<input v-model="form.contactPhone" class="mt-1 w-full rounded-md border border-gray-300 px-4 py-2 text-sm" placeholder="联系电话" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">企业邮箱</label>
|
||||
<input v-model="form.contactEmail" type="email" class="mt-1 w-full rounded-md border border-gray-300 px-4 py-2 text-sm" placeholder="邮箱" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">经办人手机号</label>
|
||||
<input v-model="form.agentPhone" class="mt-1 w-full rounded-md border border-gray-300 px-4 py-2 text-sm" placeholder="经办人手机号" />
|
||||
</div>
|
||||
<button type="submit" class="w-full rounded-md bg-blue-600 py-3 text-white font-medium hover:bg-blue-700 disabled:opacity-50" :disabled="loading">
|
||||
<HjcEnterpriseForm
|
||||
ref="entForm"
|
||||
v-model:form="form"
|
||||
v-model:materials="materials"
|
||||
show-password
|
||||
/>
|
||||
|
||||
<p class="text-center text-xs text-gray-500">
|
||||
企业联系电话、企业地址选填,其余项必填;提交后等待平台审核,审核通过方可购买标书
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="w-full rounded-md bg-blue-600 py-3 font-medium text-white hover:bg-blue-700 disabled:opacity-50"
|
||||
:disabled="loading"
|
||||
>
|
||||
{{ loading ? '注册中...' : '注册并登录' }}
|
||||
</button>
|
||||
<p v-if="error" class="text-center text-sm text-red-500">{{ error }}</p>
|
||||
</form>
|
||||
|
||||
<p class="mt-4 text-center text-sm text-gray-500">
|
||||
已注册?
|
||||
<NuxtLink to="/login" class="text-blue-600 hover:underline">去登录</NuxtLink>
|
||||
@@ -45,20 +39,41 @@ const { register } = useHjcAuth()
|
||||
const route = useRoute()
|
||||
const loading = ref(false)
|
||||
const error = ref('')
|
||||
const form = reactive({
|
||||
enterpriseName: '',
|
||||
const entForm = ref<any>(null)
|
||||
|
||||
const form = ref<Record<string, any>>({
|
||||
name: '',
|
||||
password: '',
|
||||
creditCode: '',
|
||||
address: '',
|
||||
contactPhone: '',
|
||||
contactEmail: '',
|
||||
agentPhone: ''
|
||||
agentName: '',
|
||||
idCardNo: '',
|
||||
agentEmail: '',
|
||||
agentPhone: '',
|
||||
authorizeExpire: ''
|
||||
})
|
||||
|
||||
const materials = ref<any[]>([
|
||||
{ materialType: 'idcard_front', label: '身份证人像面', materialName: '身份证人像面', fileUrl: '' },
|
||||
{ materialType: 'idcard_back', label: '身份证国徽面', materialName: '身份证国徽面', fileUrl: '' },
|
||||
{ materialType: 'handbook', label: '授权委托书', materialName: '授权委托书', fileUrl: '' },
|
||||
{ materialType: 'license', label: '营业执照', materialName: '营业执照', fileUrl: '' }
|
||||
])
|
||||
|
||||
async function submitForm() {
|
||||
error.value = ''
|
||||
if (!entForm.value?.validate()) return
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await register({ ...form })
|
||||
// buildPayload 返回 { name, ... };注册接口用 enterpriseName 作为登录账号
|
||||
const { name, ...rest } = entForm.value.buildPayload()
|
||||
const res = await register({
|
||||
enterpriseName: name,
|
||||
password: form.value.password,
|
||||
...rest
|
||||
})
|
||||
if (res.ok) {
|
||||
return navigateTo((route.query.redirect as string) || '/tender')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user