feat(tender): 阶段3b 企业登录/注册 + 购买→支付→确认 闭环
- useHjcAuth:token 存 cookie(hjc_token),login/register/isLoggedIn
- 页面 /login /register(企业名称+密码)
- server/api/tender/{auth/login,auth/register,pay,mark-paid} 代理;order 代理从 cookie 读取 hjc_token 透传 Authorization
- BuyDocument:未登录跳登录;下单→pay(codeUrl)→确认 mark-paid→成功
- types 增 HjcUser
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
<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">
|
||||
<h1 class="text-2xl font-bold text-center text-gray-900">企业登录</h1>
|
||||
<form class="mt-6 space-y-4" @submit.prevent="submitForm">
|
||||
<div>
|
||||
<label class="text-sm text-gray-600">企业名称</label>
|
||||
<input v-model="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="password" type="password" 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">
|
||||
{{ 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="/register" class="text-blue-600 hover:underline">立即注册企业</NuxtLink>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { login } = useHjcAuth()
|
||||
const route = useRoute()
|
||||
const enterpriseName = ref('')
|
||||
const password = ref('')
|
||||
const loading = ref(false)
|
||||
const error = ref('')
|
||||
|
||||
async function submitForm() {
|
||||
error.value = ''
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await login(enterpriseName.value, password.value)
|
||||
if (res.ok) {
|
||||
return navigateTo((route.query.redirect as string) || '/tender')
|
||||
}
|
||||
error.value = res.message || '登录失败'
|
||||
} catch (e: any) {
|
||||
error.value = e?.message || '登录失败'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,72 @@
|
||||
<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">
|
||||
<h1 class="text-2xl font-bold text-center text-gray-900">企业注册</h1>
|
||||
<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">
|
||||
{{ 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>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { register } = useHjcAuth()
|
||||
const route = useRoute()
|
||||
const loading = ref(false)
|
||||
const error = ref('')
|
||||
const form = reactive({
|
||||
enterpriseName: '',
|
||||
password: '',
|
||||
creditCode: '',
|
||||
contactPhone: '',
|
||||
contactEmail: '',
|
||||
agentPhone: ''
|
||||
})
|
||||
|
||||
async function submitForm() {
|
||||
error.value = ''
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await register({ ...form })
|
||||
if (res.ok) {
|
||||
return navigateTo((route.query.redirect as string) || '/tender')
|
||||
}
|
||||
error.value = res.message || '注册失败'
|
||||
} catch (e: any) {
|
||||
error.value = e?.message || '注册失败'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user