feat(collect-code): 实现个人信息收集和电子签名功能

- 添加个人信息收集页面,包括手机号、姓名、性别、生日等信息
- 实现电子签名流程,包括协议确认和签名结果展示
-优化登录页面布局,增加倒计时和返回功能
- 更新测试环境配置,统一 API 和 WebSocket URL
This commit is contained in:
xingyy 2025-02-19 15:14:01 +08:00
parent 3be7cec1c2
commit 6f49f3d8e0
10 changed files with 159 additions and 31 deletions

View File

@ -29,3 +29,11 @@ export async function userArtworks(data) {
data
})
}
export async function fddInfo(data) {
return await request( {
url:'/api/v1/contract/fdd-info',
method: 'POST',
data
})
}

View File

@ -138,8 +138,8 @@ const goLogin = async () => {
</van-field>
</div>
<div class="flex justify-end mt-[10px]" @click="changeToPwd">
<div class="text-[14px] text-[#2B53AC]">
<div class="flex justify-end mt-[10px]" >
<div class="text-[14px] text-[#2B53AC]" @click="changeToPwd">
{{ loginType === 0 ? '密码登录' : '验证码登录' }}
</div>
</div>
@ -166,11 +166,15 @@ const goLogin = async () => {
<div class="text-[16px] text-[#000]">+86 {{ phoneNum }}</div>
</div>
<van-password-input :value="code" :gutter="10" :mask="false" focused @focus="showKeyboard = true" />
<div :class="`${countdown > 0 ? 'text-#BDBDBD' : 'text-#2B53AC'} text-14px`">
{{ $t('login.reSend') }}<span v-if="countdown > 0">({{ countdown }})</span>
<div class="flex justify-between">
<div :class="`${countdown>0?'text-#BDBDBD':'text-#2B53AC'} text-14px`">
{{ $t('login.reSend') }}<span v-if="countdown>0">({{countdown}})</span>
</div>
<div @click="goBack" class="text-#2B53AC text-14px">
{{ $t('login.back') }}
</div>
</div>
<div class="mt-[17px]">
<van-button v-if="code.length === 6" type="primary" block :loading="loadingRef.loading2"
:loading-text="$t('login.login')" style="height: 48px" @click="goLogin">{{
$t('login.login')
@ -179,10 +183,6 @@ const goLogin = async () => {
$t('login.login')
}}</van-button>
</div>
<div class="mt-[17px]">
<van-button type="primary" @click="goBack" block style="height: 48px">{{ $t('login.back')
}}</van-button>
</div>
</div>
</van-swipe-item>
</van-swipe>

View File

@ -2,21 +2,82 @@
import {useI18n} from "vue-i18n";
import XVanSelect from '@/components/x-van-select/index.vue'
import XVanDate from '@/components/x-van-date/index.vue'
import {codeAuthStore} from "@/stores-collect-code/auth/index.js";
import {message} from "@/components/x-message/useMessage.js";
import {fddInfo} from "~/api-collect-code/goods/index.js";
import {signOffline} from "~/api/goods/index.js";
const {formData,number}=codeAuthStore()
definePageMeta({
layout: 'default',
i18n: 'menu.profile',
})
const {t} = useI18n()
const showPicker = ref(false)
const showPicker1 = ref(false)
const onConfirm = () => {
}
const {t} = useI18n()
const router = useRouter()
const route = useRoute()
const columns = ref([
{text: t('realAuth.male'), value: 1},
{text: t('realAuth.female'), value: 2},
])
const columns1 = ref([
{text: '身份证', value: 1},
{text: '护照', value: 2},
{text: '其他', value: 3},
])
const goCountryRegion=()=>{
router.push({
path:'/countryRegion'
})
}
function isFormComplete(obj) {
for (const key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
if (!isFormComplete(obj[key])) {
return false;
}
} else if (obj[key] === "") {
return false;
}
}
return true;
}
const initData=()=>{
number.value=route.query.number
console.log('route.query',route.query)
if (route.query.zone){
formData.value.countryCode=route.query.zone
}else {
formData.value.countryCode='86'
}
}
const nextClick=async ()=>{
if (!isFormComplete(formData.value)){
message.warning('请填写完整信息')
return
}
const res=await fddInfo({
phone:formData.value.phone
})
if (res.status===0){
if (res.data.status===2){
router.push('/collectCode/signature/protocol')
}else {
const res1=await signOffline({
userInfo:formData.value,
signOrder:Number(number.value),
})
if (res1.status===0){
window.location.href=res1.data.fddVerifyUrl
}
}
}
//
/* if (formData.value.countryCode==='86'&&formData.value.cardType===1){
}*/
}
initData()
</script>
<template>
@ -26,27 +87,30 @@ const columns = ref([
请填写个人相关信息
</div>
<div class="grow-1 px-34px">
<van-field type="tel" :label-width="161" label="文本" class="mb-10px" placeholder="请输入手机号">
<van-field v-model="formData.phone" type="tel" :label-width="161" label="文本" class="mb-10px" placeholder="请输入手机号">
<template #label>
<div class="flex">
<div class="mr-41px whitespace-nowrap">手机号</div>
<div>
<span class="mr-13px">+ 86</span>
<div @click="goCountryRegion">
<span class="mr-13px">+ {{ formData.countryCode }}</span>
<van-icon name="arrow-down" class="text-#777777"/>
</div>
</div>
</template>
</van-field>
<van-field label="姓名" class="mb-10px" placeholder="请输入姓名"/>
<x-van-select label="性别" :columns="columns"/>
<x-van-date label="出生日期"/>
<van-field label="家庭住址" class="mb-10px" placeholder="请输入家庭住址"/>
<van-field label="所属银行" class="mb-10px" placeholder="请输入所属银行"/>
<van-field label="银行卡号码" class="mb-10px" placeholder="请输入银行卡号码"/>
<van-field label="姓名" v-model="formData.userName" class="mb-10px" placeholder="请输入姓名"/>
<x-van-select v-model="formData.gender" label="性别" :columns="columns"/>
<x-van-date label="出生日期" v-model="formData.birthday" />
<van-field label="家庭住址" v-model="formData.address" class="mb-10px" placeholder="请输入家庭住址"/>
<van-field label="所属银行" v-model="formData.bankName" class="mb-10px" placeholder="请输入所属银行"/>
<van-field label="银行卡号码" v-model="formData.bankNo" class="mb-10px" placeholder="请输入银行卡号码"/>
<x-van-select v-model="formData.cardType" label="证件类型" :columns="columns1"/>
<van-field label="证件号" v-model="formData.cardId" class="mb-10px" placeholder="请输入证件号"/>
</div>
<div class="h-81px bg-#fff flex justify-center pt-7px border-t">
<van-button color="#2B53AC" class="w-213px van-btn-h-38px">下一步</van-button>
<van-button color="#2B53AC" class="w-213px van-btn-h-38px" @click="nextClick">下一步</van-button>
</div>
</div>
</template>

View File

@ -1,6 +1,20 @@
<script setup>
import {codeAuthStore} from "~/stores-collect-code/auth/index.js";
import {signOffline} from "~/api/goods/index.js";
const show=ref(true)
const activeNames = ref(['1']);
const {formData,number}=codeAuthStore()
const confirm=async ()=>{
if (formData.value.countryCode==='86'&&formData.value.cardType===1){
}
const res=await signOffline({
userInfo:formData.value,
signOrder:Number(number.value),
})
if (res.status===0){
window.location.href=res.data.fddVerifyUrl
}
}
</script>
<template>
@ -27,7 +41,7 @@ const activeNames = ref(['1']);
</van-collapse-item>
</van-collapse>
<div class="h-81px bg-#fff flex justify-center pt-7px border-t">
<van-button color="#2B53AC" class="w-213px van-btn-h-38px">同意并签字</van-button>
<van-button color="#2B53AC" class="w-213px van-btn-h-38px" @click="confirm">同意并签字</van-button>
</div>
</div>
</template>

View File

@ -0,0 +1,20 @@
<script setup>
</script>
<template>
<div class="w-[100vw] h-screen-nav bg-[url('@/static/images/3532@2x.png')] bg-cover flex-grow-1 flex flex-col items-center pt-183px px-30px">
<div class="flex flex-col items-center pt-18px px-31px">
<div class="text-#000 text-16px mb-4px">签署成功</div>
<div class="text-#939393 text-12px mb-31px">&nbsp&nbsp&nbsp领取您的专属号牌&nbsp&nbsp&nbsp</div>
<div class="relative">
<img class="w-258px h-144px" src="@/static/images/zu6020@2x.png" alt="">
<div class="absolute text-#FDD68D text-68px bottom-1px left-1/2 transform translate-x--1/2">50</div>
</div>
</div>
</div>
</template>
<style scoped>
</style>

View File

@ -38,6 +38,7 @@ function groupByPinyinInitial(data) {
}
});
//
data.forEach(country => {
if (!frequentCountryCodes.includes(country.code)) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -4,7 +4,28 @@ export const codeAuthStore = createGlobalState(() => {
const RefreshToken=useLocalStorage('RefreshToken','')
const userInfo=useLocalStorage('userInfo',{})
const fingerprint=useLocalStorage('fingerprint','')
const formData=useLocalStorage('formData',{
"countryCode": "",
"phone": "", //手机号
"userName": "", //用户名 (第一次传)
"gender": 1, //性别 1男 2女 3未知 (第一次传)
"birthday": "", //生日 (第一次传)
"address": "", //家庭住址 (第一次传)
"bankName": "", //银行名字(第一次传)
"bankNo": "", //银行卡号(第一次传)
"cardId": "",
cardType:1
})
const lotNo=ref(undefined)
const price=ref(undefined)
const auctionArtworkUuid=ref(undefined)
const number=useLocalStorage('number',undefined)
return{
lotNo,
price,
auctionArtworkUuid,
number,
formData,
userInfo,
RefreshToken,
token,

View File

@ -234,7 +234,7 @@ export const liveStore = createGlobalState(() => {
})
}
const changeStatus = () => {
if (auctionData.value.artwork.isSelling&&!auctionData.value.artwork.isSoled){
if (auctionData.value.artwork?.isSelling&&!auctionData.value.artwork.isSoled){
quoteStatus.value = !quoteStatus.value
}else {
if (quoteStatus.value){

6
env/.env.test vendored
View File

@ -1,7 +1,7 @@
# 测试环境配置
NUXT_PUBLIC_API_BASE=https://auction-test.szjixun.cn
NUXT_PUBLIC_API_COLLECT_CODE=https://auction-test.szjixun.cn
NUXT_PUBLIC_API_BASE=http://auction-test.szjixun.cn
NUXT_PUBLIC_API_COLLECT_CODE=http://auction-test.szjixun.cn
NUXT_API_SECRET=test-secret
NUXT_PUBLIC_SOCKET_URL=ws://172.16.100.99:8005
NUXT_PUBLIC_SOCKET_URL=ws://auction-test.szjixun.cn
# 阿里云播放器配置
NUXT_PUBLIC_PLAYER_SOURCE=artc://live-push-sh-01.szjixun.cn/live001/86180cae-1e07-4b8d-b45e-50d8ce800110?auth_key=1739255918-0-0-5251017e725a860570a59de7e4e2fd98