From bbf6d337c9641c0d1bf2c57f05310e59c104990b Mon Sep 17 00:00:00 2001
From: jhzh <1628036192@qq.com>
Date: Fri, 29 May 2026 15:04:43 +0800
Subject: [PATCH] 1

---
 src/views/authentication/index.vue |  507 ++++++++++++++++++++++++++++++--------------------------
 1 files changed, 272 insertions(+), 235 deletions(-)

diff --git a/src/views/authentication/index.vue b/src/views/authentication/index.vue
index 5d7f9f7..9139f94 100644
--- a/src/views/authentication/index.vue
+++ b/src/views/authentication/index.vue
@@ -1,304 +1,341 @@
 <template>
-  <!-- 申请身份认证 -->
-  <div style="padding-bottom: 30px" class="font-26 authentication">
-    <fx-header @back="loginOut">
+  <div class="authentication">
+    <fx-header :back="false" @back="loginOut">
       <template #title>
-        <!-- {{ $t('primaryCertification') }} -->
-        {{ $t('realNameVertify') }}
+        <span>{{ $t('Primary') }}</span>
       </template>
     </fx-header>
-    <!-- <country-list /> -->
-    <div v-if="show">
-      <div class=" pt-58 pb-54 box-border border-b-color" v-if="disabled() || status === 3">
-        <div class="flex justify-between items-center px-30 textColor">
-          <div class="font-20">{{ $t('authVerify') }}</div>
-          <div class="flex items-center" v-if="resultArr[status]">
-            <!-- <img
-              :src="require(`@/assets/image/assets-center/${resultArr[status] && resultArr[status].split('_')[0]}.png`)"
-              alt="success img" class="w-36 h-36" /> -->
-            <img src="@/assets/image/assets-center/identifing.png" v-if="status == 1" class="w-20 h-20" />
-            <img src="@/assets/image/assets-center/small-success.png" v-if="status == 0 || status == 2"
-              class="w-20 h-20" />
-            <img src="@/assets/image/assets-center/icon-close.png" v-if="status == 3" class="w-20 h-20" />
-            <div class="font-10 ml-18">{{ resultArr[status] && resultArr[status].split('_')[1] }}</div>
+
+    <div class="auth-body">
+      <!-- nationality -->
+      <div class="auth-field">
+        <label class="auth-label">{{ $t('nationality') }}</label>
+        <div class="auth-input auth-input--select" @click="openNationality">
+          <span class="auth-placeholder" :class="{ 'auth-placeholder--filled': countryName && countryName !== $t('selectNation') }">{{ countryName }}</span>
+          <van-icon name="arrow" class="auth-chevron" />
+        </div>
+      </div>
+
+      <!-- document type -->
+      <div class="auth-field">
+        <label class="auth-label">{{ $t('documentType') }}</label>
+        <div class="auth-input auth-input--select" @click="showDocType = true">
+          <span class="auth-placeholder" :class="{ 'auth-placeholder--filled': idname }">{{ idname || $t('pleaseSelectDocumentType') }}</span>
+          <van-icon name="arrow" class="auth-chevron" />
+        </div>
+      </div>
+
+      <!-- last name -->
+      <div class="auth-field">
+        <label class="auth-label">{{ $t('lastName') }}</label>
+        <input v-model="name" type="text" class="auth-input auth-input--text" :placeholder="$t('pleaseEnterLastName')" />
+      </div>
+
+      <!-- first name -->
+      <div class="auth-field">
+        <label class="auth-label">{{ $t('firstName') }}</label>
+        <input v-model="firstName" type="text" class="auth-input auth-input--text" :placeholder="$t('pleaseEnterFirstName')" />
+      </div>
+
+      <!-- ID number -->
+      <div class="auth-field">
+        <label class="auth-label">{{ $t('idNumber') }}</label>
+        <input v-model="idnumber" type="text" class="auth-input auth-input--text" :placeholder="$t('pleaseEnterIdNumber')" />
+      </div>
+
+      <!-- birth -->
+      <div class="auth-field">
+        <label class="auth-label">{{ $t('birth') }}</label>
+        <input v-model="birth" type="date" class="auth-input auth-input--text auth-input--date" :placeholder="$t('pleaseSelectBirth')" />
+      </div>
+
+      <!-- 证件上传(保留接口) -->
+      <div class="auth-upload-section" v-if="!disabled()">
+        <div class="auth-label">{{ $t('uploadCredentPassport') }}</div>
+        <div class="auth-upload-row">
+          <div class="auth-upload-item">
+            <van-uploader v-model="frontFile" :max-count="1" :deletable="!disabled()" :after-read="afterRead" />
+            <div class="auth-upload-tip">{{ $t('credentFront') }}</div>
+          </div>
+          <div class="auth-upload-item">
+            <van-uploader v-model="reverseFile" :max-count="1" :deletable="!disabled()" :after-read="afterRead" />
+            <div class="auth-upload-tip">{{ $t('credentObverse') }}</div>
           </div>
         </div>
       </div>
-      <div class="pl-30 pr-30">
-        <div class="">
-          <div class=" mb-25 font-14 textColor">{{ $t('nationality') }}</div>
-          <div class="pt-28 pb-28 pl-38 pr-38 flex justify-between items-center rounded inputBackground textColor box"
-            @click="openBtn">
-            <div class="flex items-center ml-2">
-              <!-- <div class="iti-flag" :class="key" style="transform: scale(2.1)"></div> -->
-              <div class="iti-flag mr-20 " :class="countryCode" style="transform: scale(2.1)"></div>
-              <div>{{ countryName }}</div>
-            </div>
 
-            <img src="@/assets/image/down-arrow.png" class="w-20 h-10" alt="arrow" />
-          </div>
-        </div>
-        <ExInput :label="$t('realName')" :disabled="disabled()" :clearBtn="!disabled()"
-          :placeholderText="$t('entryRealName')" v-model="name" />
-        <ExInput :label="$t('credentPassport')" :disabled="disabled()" :clearBtn="!disabled()"
-          :placeholderText="$t('entryCredentPassport')" v-model="idnumber" />
-        <div>
-          <div v-if="resultArr.length > 0" class="mt-4 mb-25 textColor">{{ $t('uploadCredentPassport') }} </div>
-          <div v-else class="mt-4 mb-25 textColor">{{ $t('uploadPicCredentPassport') }}</div>
-          <div class="flex mb-80 justify-between">
-            <div class="flex-1 flex flex-col text-center justify-center items-center">
-              <div class="upload-wrap">
-                <img src="../../assets/image/kyc/0.png" alt="" class="w-full"
-                  v-if="[1, 2].includes(status) && frontFile.length === 0" />
-                <van-uploader v-model="frontFile" multiple :max-count="1" :deletable="!disabled()"
-                  :after-read="afterRead" @click-upload="onClickUpload('frontFile')" v-else />
-
-              </div>
-              <div class=" font-26 h-20 textColor1">{{ $t('credentFront') }}</div>
-            </div>
-            <div class="flex-1 flex flex-col text-center justify-center items-center">
-              <div class="upload-wrap">
-                <img src="../../assets/image/kyc/1.png" alt="" class="w-full"
-                  v-if="[1, 2].includes(status) && reverseFile.length === 0" />
-                <van-uploader v-model="reverseFile" multiple :max-count="1" :disabled="disabled()"
-                  :deletable="!disabled()" :after-read="afterRead" @click-upload="onClickUpload('reverseFile')"
-                  v-else />
-              </div>
-              <div class=" font-26 h-20 textColor1">{{ $t('credentObverse') }}</div>
-            </div>
-            <!-- <div class="flex-1 flex flex-col text-center justify-center items-center">
-              <div class="upload-wrap">
-                <img src="../../assets/image/kyc/2.png" alt="" class="w-full"
-                  v-if="[1, 2].includes(status) && fileList.length === 0" />
-                <van-uploader v-model="fileList" multiple :max-count="1" :disabled="disabled()" :deletable="!disabled()"
-                  :after-read="afterRead" @click-upload="onClickUpload('fileList')" v-else />
-              </div>
-              <div class="font-26 h-20" style="color:#868D9A;">{{ $t('handCredent') }}</div>
-            </div> -->
-          </div>
-        </div>
-        <template v-if="!disabled()">
-          <div class="font-35 mb-32 textColor">{{ $t('photoExample') }}</div>
-          <!-- <img src="@/assets/image/kyc/kyc-demo.png" alt="" style="width:100%;height:auto;" class="w-756 h-220 mb-100"> -->
-          <div class="mb-100 flex justify-center">
-            <div class="flex flex-1 justify-center">
-              <img src="../../assets/image/kyc/1.png" alt="" class="w-120 h-120" />
-            </div>
-            <div class="flex flex-1 justify-center">
-              <img src="../../assets/image/kyc/0.png" alt="" class="w-120 h-120" />
-            </div>
-          </div>
-        </template>
-        <button class="apply-btn btnMain text-white font-35 h-100 rounded" @click="onSubmit" v-if="!disabled()">{{
-          $t('Apply')
-        }}</button>
-        <div class="pt-35 pb-60 font-30" v-if="!disabled() || status === 3">
-          <span class="text-grey">{{ $t('uploadTitle1') }} {{ $t('photoExample') }}</span>
-          <span class="text-blue service-text" @click="tokefu"> {{ $t('ContactService') }}</span>
-        </div>
-        <nationality-list ref='controlChild' :title="$t('selectNation')" @getName="getName" v-if="!disabled()">
-        </nationality-list>
-      </div>
+      <button type="button" class="auth-submit" @click="onSubmit">{{ $t('Submit') }}</button>
     </div>
+
+    <nationality-list ref="controlChild" :title="$t('selectNation')" @getName="getName" />
+    <van-action-sheet v-model:show="showDocType" :actions="docTypeActions" @select="onSelectDocType" />
   </div>
 </template>
 
 <script setup>
-import { _getIdentify, _info, _applyIdentify } from "@/service/user.api.js";
+import { _getIdentify, _applyIdentify } from "@/service/user.api.js";
 import { _uploadImage } from "@/service/upload.api.js";
 import { onMounted, ref } from 'vue';
-import nationalityList from './components/nationalityList.vue'
+import nationalityList from './components/nationalityList.vue';
 import { useRouter } from "vue-router";
-import { showToast, Uploader } from "vant"
-// import ExInput from "@/components/ex-input";
+import { showToast } from "vant";
 import countries from "./components/countryList";
-import { getCurrentInstance } from 'vue';
 import { useI18n } from "vue-i18n";
-import { customerServiceUrl } from '@/config'
-const { t } = useI18n()
-const router = useRouter()
-const countryName = ref(t('selectNation'))
-const countryCode = ref('af')
-const idnumber = ref('')
-const name = ref('')
-const frontFile = ref([])
-const reverseFile = ref([])
-const fileList = ref([])
-const curFile = ref('frontFile')
-const status = ref('')
-const imgs = ref([])
-const idcard_path_front_path = ref('')
-const idcard_path_back_path = ref('')
-const idcard_path_hold_path = ref('')
-const resultArr = ref(['small-success_' + t('applynoView'), 'identifing_' + t('reviewing'), 'small-success_' + t('passView'), 'icon-close_' + t('noPassView')])
-const show = ref(false)
-const language = ref('en')
-const controlChild = ref(null)
-const { proxy } = getCurrentInstance();
+
+const { t } = useI18n();
+const router = useRouter();
+
+const countryName = ref(t('selectNation'));
+const countryCode = ref('af');
+const idname = ref('');
+const idnumber = ref('');
+const name = ref('');
+const firstName = ref('');
+const birth = ref('');
+const frontFile = ref([]);
+const reverseFile = ref([]);
+const status = ref('');
+const show = ref(false);
+const showDocType = ref(false);
+const controlChild = ref(null);
+
+const docTypeActions = [
+  { name: 'ID Card', value: 'id/passport' },
+  { name: 'Passport', value: 'passport' }
+];
+
+const disabled = () => ![0, 3, ''].includes(status.value);
 
 onMounted(() => {
   fetchInfo();
-  language.value = (localStorage.getItem('lang')).substring(0, 2)
-})
+});
+
 const loginOut = () => {
-  router.push('/certificationCenter')
-}
-const fetchInfo = () => {   // 获取状态
-  _getIdentify().then(data => {
-
-    show.value = true
-    status.value = data.status
-    if (data.id != null) {
-      countryName.value = countries[data.nationality.toLowerCase()].name
-      countryCode.value = data.nationality.toLowerCase()
-
-      idnumber.value = data.idnumber
-      name.value = data.name
-      frontFile.value = data.idimg_1 ? [{ url: data.idimg_1_path, resURL: data.idimg_1 }] : []
-      reverseFile.value = data.idimg_2 ? [{ url: data.idimg_2_path, resURL: data.idimg_2 }] : []
-      fileList.value = data.idimg_3 ? [{ url: data.idimg_3_path, resURL: data.idimg_3 }] : []
-    }
-  })
-}
-const onClickUpload = (type) => {
-  console.log(type)
-  curFile.value = type
-}
-const disabled = () => { // 是否禁用按钮
-  return ![0, 3, ''].includes(status.value)
-}
-const afterRead = (file) => {
-  file.status = 'uploading'
-  file.message = t('uploading')
-
-  _uploadImage(file).then(data => {
-    file.status = 'success'
-    file.message = t('uploadSuccess')
-    file.resURL = data
-  }).catch(err => {
-    file.status = 'failed'
-    file.message = t('uploadFailed')
-  })
+  router.push('/certificationCenter');
 };
 
+const fetchInfo = () => {
+  _getIdentify().then(data => {
+    show.value = true;
+    status.value = data.status ?? '';
+    if (data.id != null || data.nationality) {
+      const code = (data.nationality || 'af').toLowerCase();
+      countryName.value = countries[code] ? countries[code].name : t('selectNation');
+      countryCode.value = code;
+      idnumber.value = data.idnumber || data.idNumber || '';
+      name.value = data.name || '';
+      firstName.value = data.firstName || data.firstname || '';
+      birth.value = data.birth || '';
+      frontFile.value = data.idimg_1 || data.idFrontImg ? [{ url: data.idimg_1_path || data.idFrontImg, resURL: data.idimg_1 || data.idFrontImg }] : [];
+      reverseFile.value = data.idimg_2 || data.idBackImg ? [{ url: data.idimg_2_path || data.idBackImg, resURL: data.idimg_2 || data.idBackImg }] : [];
+    }
+  }).catch(() => {});
+};
 
+const openNationality = () => {
+  if (!disabled() && controlChild.value) controlChild.value.open();
+};
 
-//打开国家列表底部弹窗
-const openBtn = () => {
-  if (!disabled()) {
-    proxy.$refs.controlChild.open()
-  }
-}
-//获取到当前选中国家的code值
 const getName = (params) => {
   countryName.value = params.name;
   countryCode.value = params.code;
-}
+};
+
+const onSelectDocType = (item) => {
+  idname.value = item.value || item.name;
+  showDocType.value = false;
+};
+
+const afterRead = (file) => {
+  file.status = 'uploading';
+  file.message = t('uploading');
+  _uploadImage(file).then(data => {
+    file.status = 'success';
+    file.message = t('uploadSuccess');
+    file.resURL = data;
+  }).catch(() => {
+    file.status = 'failed';
+    file.message = t('uploadFailed');
+  });
+};
 
 const onSubmit = () => {
-  if (!countryName.value) {
-    showToast(t('selectNation'))
-    return
+  if (!countryName.value || countryName.value === t('selectNation')) {
+    showToast(t('selectNation'));
+    return;
   }
   if (!name.value) {
-    showToast(t('entryName'))
-    return
+    showToast(t('pleaseEnterLastName'));
+    return;
+  }
+  if (!firstName.value) {
+    showToast(t('pleaseEnterFirstName'));
+    return;
   }
   if (!idnumber.value) {
-    showToast(t('entryCredent'))
-    return
+    showToast(t('pleaseEnterIdNumber'));
+    return;
+  }
+  if (!birth.value) {
+    showToast(t('pleaseSelectBirth'));
+    return;
+  }
+  if (!frontFile.value.length || !frontFile.value[0]?.resURL) {
+    showToast(frontFile.value[0]?.status === 'uploading' ? t('uploading') : t('uploadComplete'));
+    return;
+  }
+  if (!reverseFile.value.length || !reverseFile.value[0]?.resURL) {
+    showToast(reverseFile.value[0]?.status === 'uploading' ? t('uploading') : t('uploadComplete'));
+    return;
   }
 
-  // if (frontFile.value.length == 0 || reverseFile.value.length == 0 || fileList.value.length == 0) { // 需要手持身份证
-  if (frontFile.value.length == 0 || reverseFile.value.length == 0) { // 不需要手持身份证
-    showToast(t('uploadComplete'))
-    return
-  }
-  
   _applyIdentify({
+    countryName: countryCode.value,
+    idname: idname.value || 'id/passport',
     name: name.value,
+    firstName: firstName.value,
     idnumber: idnumber.value,
+    birth: birth.value,
     frontFile: frontFile.value,
     reverseFile: reverseFile.value,
-    // fileList: fileList.value,
-    countryName: countryCode.value // this.countryName 存储的 code, 回来再遍历
   }).then(() => {
-    showToast(t('submitSuccess'))
-    router.push('/verified')
-    // this.fetchInfo()
+    showToast(t('submitSuccess'));
+    router.push('/certificationCenter');
   }).catch(err => {
-    if (err.code === 'ECONNABORTED') { showToast('网络超时!'); }
-    else if (err.msg !== undefined) { showToast(err.msg); }
-  })
-}
-const tokefu = () => {
-  if (customerServiceUrl()) {
-    window.location.href = customerServiceUrl();
-  } else {
-    router.push('/customerService')
-  }
-}
-
+    if (err.code === 'ECONNABORTED') showToast(t('networkTimeout'));
+    else if (err.msg) showToast(err.msg);
+  });
+};
 </script>
-<style lang="scss" scoped>
-@import '../../assets/css/copy.scss';
-@import "@/views/authentication/components/intl.css";
 
-.box {
-  padding: 1.5rem !important;
+<style lang="scss" scoped>
+.authentication {
+  min-height: 100vh;
+  background: #fff;
+  padding-bottom: 2rem;
+  font-size: 14px;
 }
 
-.authentication {
+:deep(.van-nav-bar) {
+  background: #fff !important;
+}
+:deep(.van-nav-bar__title) {
+  color: #333;
+  font-weight: 700;
+  font-size: 16px;
+}
+:deep(.van-icon) {
+  color: #333;
+}
+
+.auth-body {
+  padding: 0 1.25rem;
+}
+
+.auth-field {
+  margin-bottom: 1.25rem;
+}
+
+.auth-label {
+  display: block;
+  font-size: 14px;
+  color: #333;
+  margin-bottom: 0.5rem;
+  font-weight: 500;
+}
+
+.auth-input {
   width: 100%;
   box-sizing: border-box;
+  height: 48px;
+  line-height: 48px;
+  padding: 0 1rem;
+  background: #f8f8f8;
+  border-radius: 8px;
+  border: none;
+  font-size: 14px;
+  color: #333;
 }
 
-.upload-wrap {
-  // width: 220px;
-  // height: 220px;
+.auth-input--text {
+  display: block;
+}
+.auth-input--text::placeholder {
+  color: #999;
+}
+
+.auth-input--date {
+  color-scheme: light;
+}
+.auth-input--date::-webkit-calendar-picker-indicator {
+  opacity: 0.6;
+  cursor: pointer;
+}
+
+.auth-input--select {
   display: flex;
-  justify-content: center;
   align-items: center;
+  justify-content: space-between;
+  cursor: pointer;
 }
 
-input {
-  font-size: 35px;
+.auth-placeholder {
+  color: #999;
+  font-size: 14px;
+}
+.auth-placeholder--filled {
+  color: #333;
 }
 
-input:disabled {
-  background: $mainbgWhiteColor;
+.auth-chevron {
+  font-size: 14px;
+  color: #999;
+  flex-shrink: 0;
+  margin-left: 8px;
 }
 
-.list-view {
-  overflow-y: scroll;
-  border-bottom: 1px solid $border_color;
+.auth-upload-section {
+  margin-top: 1.5rem;
+  margin-bottom: 1.5rem;
 }
 
-.kyc-input {
+.auth-upload-row {
+  display: flex;
+  gap: 1rem;
+  margin-top: 0.5rem;
+}
+
+.auth-upload-item {
+  flex: 1;
+  text-align: center;
+  background-color: #F7F8FA;
+}
+.auth-upload-item :deep(.van-uploader__upload),
+.auth-upload-item :deep(.van-uploader__preview) {
   width: 100%;
-  border: none;
+  height: 100px;
+  margin: 0;
+}
+.auth-upload-item :deep(.van-uploader__upload-icon) {
+  font-size: 24px;
+}
+.auth-upload-tip {
+  font-size: 12px;
+  color: #999;
+  margin-top: 6px;
 }
 
-.apply-btn {
-  border: none;
-  outline: none;
+.auth-submit {
   width: 100%;
   height: 50px;
-}
-
-.service-text {
-  text-decoration: underline;
-}
-
-.rounded {
-  padding: 0.6rem;
-}
-
-.mb-32 {
-  margin-bottom: 16px;
-}
-
-.pt-35 {
-  padding-top: 16px;
+  line-height: 50px;
+  font-size: 14px;
+  font-weight: 700;
+  color: #fff;
+  background: linear-gradient(90deg, #7c3aed, #5b21b6);
+  border: none;
+  border-radius: 12px;
+  margin-top: 1rem;
+  cursor: pointer;
 }
 </style>

--
Gitblit v1.9.3