From 304f819d3e9b2498ebdb70b99b632cda67725a52 Mon Sep 17 00:00:00 2001
From: 李 <344137771@qq.com>
Date: Sun, 31 May 2026 17:57:32 +0800
Subject: [PATCH] 1
---
src/views/register/index.vue | 747 +++++++++++++++++++++++++++-----------------------------
1 files changed, 361 insertions(+), 386 deletions(-)
diff --git a/src/views/register/index.vue b/src/views/register/index.vue
index de0ff1c..7857eaf 100644
--- a/src/views/register/index.vue
+++ b/src/views/register/index.vue
@@ -1,439 +1,414 @@
<template>
<div class="register">
- <div class="top flex justify-between items-center">
- <img src="../../assets/image/icon-close.png" alt="" @click="router.go(-1)">
- <div @click="onRoute('/customerService')">{{ $t('onLineService') }}</div>
- </div>
- <!-- <Step :step="1"></Step> -->
- <div class="title textColor">{{ $t('register') }}</div>
- <div class="flex re-tab">
- <!-- <div class="textColor1" :class="activeIndex == 0 ? 'active' : ''" @click="changeIndex(0)">{{
- $t('account')
- }}</div> -->
- <div class="textColor1" :class="activeIndex == 1 ? 'active' : ''" @click="changeIndex(1)">
- {{ $t('电子邮箱') }}
+ <div class="reg-inner">
+ <div class="reg-back" @click="router.go(-1)">
+ <van-icon name="arrow-left" size="22" />
</div>
- <div class="textColor1" :class="activeIndex == 2 ? 'active' : ''" @click="changeIndex(2)">
- {{ $t('手机号码') }}
+
+ <div class="reg-logo-wrap">
+ <img :src="LOGO" alt="" class="reg-logo" />
</div>
- </div>
- <ExInput :label="getRegType(activeIndex, true)" :placeholderText="getRegType(activeIndex, false)"
- v-model="username" :area="isArea" :dialCode="dialCode" @selectArea="onSelectArea" :icon="icon" />
+ <h1 class="reg-title">{{ $t('register') }}</h1>
+ <p class="reg-login">
+ {{ $t('hasAccount') }}
+ <span class="reg-login-link" @click="router.push('/login')">{{ $t('goLogin') }}</span>
+ </p>
+ <p class="reg-lang" @click="onRoute('/language')">{{ currentLocaleLabel }}</p>
- <ExInput :label="$t('设置登录密码')" :placeholderText="$t('请输入8-16位字符,必须包含大写字母、和特殊字符')" v-model="password"
- typeText="password" />
- <ExInput :label="$t('确认登录密码')" :placeholderText="$t('surePassword')" v-model="repassword" typeText="password" />
- <ExInput :label="$t('setSafeword')" :placeholderText="$t('请输入6位阿拉伯数字的资金密码')" v-model="safeword"
- typeText="password" v-if="activeIndex === 1 || activeIndex === 2" />
- <div class="inputCom" v-if="activeIndex === 1 || activeIndex === 2">
- <p class="label textColor" v-if="activeIndex == 1">{{ $t('邮箱验证码') }}</p>
- <p class="label textColor" v-else-if="activeIndex == 2">{{ $t('手机验证码') }}</p>
- <p class="label textColor" v-else>{{ $t('验证码') }}</p>
- <div class="iptbox inputBackground">
-
- <input class="inputBackground textColor" type="text"
- :placeholder="activeIndex == 1 ? $t('请输入邮箱验证码') : activeIndex == 2 ? $t('请输入手机验证码') : $t('entryVerifyCode')"
- v-model="verifyCode">
-
- <span v-if="type !== 3" @click="senCode">
- <span v-if="activeIndex == 1">{{ $t('发送邮箱验证码') }}</span>
- <span v-else-if="activeIndex == 2">{{ $t('发送手机验证码') }}</span>
- <span v-else>{{ $t('sendVerifyCode') }}</span>
- <template v-if="time">({{ time }})s</template>
+ <!-- Email -->
+ <div class="reg-field">
+ <input
+ v-model="username"
+ type="text"
+ class="reg-input"
+ :placeholder="$t('entryEmail')"
+ autocomplete="email"
+ />
+ </div>
+ <!-- Verification Code -->
+ <div class="reg-field reg-field-code">
+ <input
+ v-model="verifyCode"
+ type="text"
+ class="reg-input"
+ :placeholder="$t('entryVerifyCode')"
+ maxlength="6"
+ />
+ <span class="reg-send-code" @click="senCode">
+ {{ time > 0 ? `(${time})s` : $t('sendVerifyCode') }}
</span>
</div>
- </div>
- <ExInput :label="$t('金融机构代码')" :placeholderText="$t('请输入金融机构识别码')" v-model="invitCode" :clearBtn="false" />
- <div class="protocol textColor">
- <i @click="agreeProt">
- <img v-show="agree" src="../../assets/image/login/prot2.png" alt="" />
- <img v-show="!agree" src="../../assets/image/login/prot1.png" alt="" />
- </i>
- <!-- {{ $t('readAgree') }}<span class="colorMain" @click="router.push('/TermsOfService')">{{
- $t('serviceConf')
- }}</span> -->
- {{ $t('readAgree') }}<span class="colorMain" @click="router.push('/aboutUs?serviceTerm=23')">{{
- $t('serviceConf')
- }}</span>
- </div>
- <van-button class="w-full" style="margin-top:10px;" type="primary" @click="register">{{ $t('register') }}
- </van-button>
- <div class="noTips textColor">{{ $t('hasAccount') }}<span class="colorMain" @click="router.push('/login')">
- {{ $t('goLogin') }}</span>
- </div>
- <nationality-list ref='controlChildRef' :title="$t('selectArea')" @getName="getName"></nationality-list>
+ <!-- Password -->
+ <div class="reg-field reg-field-pwd">
+ <input
+ v-model="password"
+ :type="pwdVisible ? 'text' : 'password'"
+ class="reg-input"
+ :placeholder="$t('entryPassword')"
+ autocomplete="new-password"
+ />
+ <span class="reg-eye" @click="pwdVisible = !pwdVisible">
+ <van-icon :name="pwdVisible ? 'eye-o' : 'closed-eye'" size="20" />
+ </span>
+ </div>
+ <!-- Confirm Password -->
+ <div class="reg-field reg-field-pwd">
+ <input
+ v-model="repassword"
+ :type="repwdVisible ? 'text' : 'password'"
+ class="reg-input"
+ :placeholder="$t('surePassword')"
+ autocomplete="new-password"
+ />
+ <span class="reg-eye" @click="repwdVisible = !repwdVisible">
+ <van-icon :name="repwdVisible ? 'eye-o' : 'closed-eye'" size="20" />
+ </span>
+ </div>
+ <!-- Referral Code -->
+ <div class="reg-field">
+ <input
+ v-model="invitCode"
+ type="text"
+ class="reg-input"
+ :placeholder="$t('entryInvitCode')"
+ />
+ </div>
- <Vcode :imgs="[img1, img2]" :show="show" @success="onSuccess" :canvasHeight="200" @fail="onFail"
- @close="show = false;" sliderText='' :successText="$t('vertifyPass')" :failText="$t('vertifuFail')" />
+ <div class="reg-protocol">
+ <span class="reg-protocol-check" :class="{ checked: agree }" @click="agree = !agree"></span>
+ <span>{{ $t('readAgree') }}</span>
+ <span class="reg-protocol-link" @click.stop="router.push('/aboutUs?serviceTerm=23')">{{ $t('serviceConf') }}</span>
+ </div>
- <div>{{ msg }}</div>
+ <button class="reg-btn reg-btn-primary" @click="register">{{ $t('register') }}</button>
+ </div>
+
+ <nationality-list ref="controlChildRef" :title="$t('selectArea')" @getName="getName" />
</div>
</template>
<script setup>
-import ExInput from "@/components/ex-input/index.vue";
-import Step from "./step.vue";
-import { _registerUser, _sendVerifyCode } from "@/service/login.api";
+import { _sendVerifyCode } from "@/service/login.api";
import { _bindEmailRegister } from "@/service/user.api.js";
import { useUserStore } from '@/store/user';
-import { GET_USERINFO } from '@/store/types.store'
-import nationalityList from '../authentication/components/nationalityList.vue'
-import Vcode from "vue3-puzzle-vcode";
-import img1 from "../../assets/image/slider/1.png";
-import img2 from "../../assets/image/slider/2.png";
-import { getStorage } from '@/utils/index'
-import { useI18n } from 'vue-i18n'
-import { customerServiceUrl } from "@/config";
+import { GET_USERINFO } from '@/store/types.store';
+import nationalityList from '../authentication/components/nationalityList.vue';
+import { getStorage } from '@/utils/index';
+import { useI18n } from 'vue-i18n';
+import { LOGO } from "@/config";
import { useRouter } from 'vue-router';
-import { ref, onMounted, reactive, onUnmounted } from 'vue';
+import { ref, computed, onMounted, onUnmounted, reactive } from 'vue';
import { showToast } from "vant";
-import store from '@/store/store'
-const customer_service_url = ref(customerServiceUrl) // 客服链接,有值的话就会跳转到客服外链
-const { t } = useI18n()
-const router = useRouter()
-const onRoute = (path) => {
- if (path == 'back') {
- router.go(-1)
- } else {
- if (path == '/customerService') {
- if (customer_service_url.value) {
- window.location.href = customer_service_url.value;
- } else {
- router.push(path)
- }
- } else {
- router.push(path)
- }
- }
-}
+import store from '@/store/store';
+
+const { t, locale } = useI18n();
+const router = useRouter();
const userStore = useUserStore();
-let show = ref(false)
-const msg = ref('')
-const type = ref(1)
-const time = ref(0)
-let agree = ref(false)
-const username = ref('')
-const password = ref('')
-const repassword = ref('')
-const verifyCode = ref('')
-const safeword = ref('')
-const fundPassword = ref('')
-const refundPassword = ref('')
-const activeIndex = ref(1)
-const typeText = ref('password')
-let isArea = ref(false)
-let dialCode = ref(0)
-let icon = ref('')
-const state = reactive({
- timer: null
-})
+const localeLabels = { en: 'English', cn: '中文', Korean: '한국인', Japanese: 'やまと', de: 'Deutsch', French: 'Français', Italy: 'Italiano' };
+const currentLocaleLabel = computed(() => localeLabels[locale.value] || locale.value || 'English');
-let invitCode = ref('')
+const username = ref('');
+const password = ref('');
+const agree = ref(false);
+const repassword = ref('');
+const verifyCode = ref('');
+const invitCode = ref('');
+const pwdVisible = ref(false);
+const repwdVisible = ref(false);
+const time = ref(0);
+const dialCode = ref(0);
+const icon = ref('');
+const controlChildRef = ref(null);
+const state = reactive({ timer: null });
+
onMounted(() => {
- console.log(store)
- let usercode = getStorage('usercode')
- if (usercode) {
- invitCode = usercode;
- }
- clearInterval(state.timer)
- state.timer = null
-})
-
+ const usercode = getStorage('usercode');
+ if (usercode) invitCode.value = usercode;
+});
onUnmounted(() => {
- clearInterval(state.timer)
- state.timer = null
-})
+ if (state.timer) clearInterval(state.timer);
+});
-const getRegType = (activeIndex, bFlag) => {
- switch (activeIndex) {
- case 0:
- return bFlag ? t('account') : t('entryAccount');
- case 1:
- return bFlag ? t('电子邮箱') : t('entryEmail');
- case 2:
- return bFlag ? t('手机号码') : t('请输入手机号码');
- }
-}
+const onRoute = (path) => {
+ router.push(path);
+};
const senCode = () => {
- if (time.value > 0) {
- return false
+ if (time.value > 0) return;
+ const email = username.value.trim();
+ if (!email || !/@/.test(email)) {
+ showToast(t('entryCorrectEmail'));
+ return;
}
- _sendVerifyCode({
- target: activeIndex.value === 1 ? username.value : dialCode.value + username.value,
- }).then((res) => {
+ _sendVerifyCode({ target: email }).then(() => {
time.value = 30;
state.timer = setInterval(() => {
- if (time.value > 0) {
- time.value = time.value - 1
- } else {
- time.value = 0;
- clearInterval(state.timer)
- state.timer = null
+ if (time.value > 0) time.value--;
+ else {
+ clearInterval(state.timer);
+ state.timer = null;
}
}, 1000);
- }).catch((error) => {
- showToast(t(error.msg));
+ }).catch((err) => {
+ showToast(err?.msg || t('sendVerifyCode'));
});
-}
+};
-const onSuccess = () => {
- console.log('onSuccess')
+const validatePassword = (pwd) => {
+ return /^(?=.*[A-Z])(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,16}$/.test(pwd);
+};
+
+const register = () => {
+ const email = username.value.trim();
+ if (!email || !/@/.test(email)) {
+ showToast(t('entryCorrectEmail'));
+ return;
+ }
+ if (!verifyCode.value || verifyCode.value.length < 6) {
+ showToast(t('entryVerifyTips'));
+ return;
+ }
+ if (!password.value) {
+ showToast(t('entryPassword'));
+ return;
+ }
+ if (!password.value || password.value.length < 6 || password.value.length > 16) {
+ showToast(t('passwordTips'));
+ return;
+ }
+ if (repassword.value !== password.value) {
+ showToast(t('noSamePassword'));
+ return;
+ }
+ if (!invitCode.value.trim()) {
+ showToast(t('请输入邀请码'));
+ return;
+ }
+ if (!agree.value) {
+ showToast(t('agreeServiceCond'));
+ return;
+ }
registerApi();
- show.value = false;
-}
-const onFail = () => {
- msg.value = ''
-}
-const onRefresh = () => {
- msg.value = ''
-}
+};
-const controlChildRef = ref(null)
-const onSelectArea = () => {
- controlChildRef.value.open();
-}
+const registerApi = () => {
+ _bindEmailRegister({
+ username: username.value.trim(),
+ password: password.value,
+ type: '2',
+ verifcode: verifyCode.value,
+ usercode: invitCode.value.trim(),
+ safeword: password.value
+ }).then((res) => {
+ userStore[GET_USERINFO](res);
+ store.state.user.userInfo = res;
+ router.push('/login');
+ }).catch((err) => {
+ showToast(err);
+ });
+};
+
+const onDownloadApp = () => {
+ // 可配置 APP 下载链接
+ const url = 'https://your-app-download-url.com';
+ if (url && (url.startsWith('http://') || url.startsWith('https://'))) {
+ window.open(url, '_blank');
+ } else {
+ showToast(t('downloadAPP'));
+ }
+};
const getName = (params) => {
icon.value = params.code;
dialCode.value = params.dialCode;
-}
-const agreeProt = () => {
- agree.value = !agree.value
-}
-
-// 密码验证
-const validatePassword = (password) => {
- const passwordRegex = /^(?=.*[A-Z])(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,16}$/;
- return passwordRegex.test(password);
-}
-
-const register = () => {
- console.log(activeIndex.value, 'activeIndex.value')
- if (activeIndex.value == 0) {
- if (username.value == '') {
- showToast(t('entryAccount'));
- return
- }
- if (username.value.length < 6 || username.value.length > 30) {
- showToast(t('accountLength'));
- return
- }
- } else if (activeIndex.value == 1) {
- let match = username.value.search(/@/);
- if (username.value == '' || match.value == -1) {
- showToast(t('entryCorrectEmail'));
- return
- }
- if (safeword.value == '') {
- showToast(t('safewordTips'));
- return
- }
- if (verifyCode.value.length < 6) {
- showToast(t('entryVerifyTips'));
- return
- }
- } else if (activeIndex.value == 2) {
- if (!(/(^[1-9]\d*$)/.test(username.value))) {
- showToast(t('entryPhone'));
- return
- }
- if (username.value == '') {
- showToast(t('entryPhone'));
- return
- }
- }
- if (password.value == '') {
- showToast(t('entryPassword'));
- return
- }
-
- if (!validatePassword(password.value)) {
- showToast(t('passwordTips'));
- return
- }
- if (repassword.value !== password.value) {
- showToast(t('noSamePassword'));
- return
- }
- if (invitCode.value.length == '') {
- showToast(t('请输入金融机构代码'));
- return
- }
- if (!agree.value) {
- showToast(t('agreeServiceCond'));
- return
- }
- show.value = true
-}
-const changeIndex = (index) => {
- activeIndex.value = index;
- if (index == 0 || index == 1) {
- isArea.value = false
- } else {
- isArea.value = true
- }
-}
-const registerApi = () => {
- switch (activeIndex.value) {
- case 0:
- {
- type.value = 3;
- break;
- }
- case 1:
- {
- type.value = 2;
- break;
- }
- case 2:
- {
- type.value = 1;
- break;
- }
- }
-
- if (activeIndex.value === 1 || activeIndex.value === 2) {
- _bindEmailRegister({
- username: activeIndex.value === 1 ? username.value : dialCode.value + username.value,
- password: password.value,
- type: activeIndex.value === 1 ? '2' : '1', // 2邮箱,1手机
- verifcode: verifyCode.value,
- usercode: invitCode.value,
- safeword: safeword.value
- }).then((res) => {
- userStore[GET_USERINFO](res)
- store.state.user.userInfo = res
- // 其他操作??
- // router.push('/identity')
- router.push('/login')
- })
- } else {
- _registerUser({
- userName: (activeIndex.value === 0 || activeIndex.value === 1) ? username.value : `${dialCode.value}${username.value}`,
- password: password.value,
- // re_password: repassword.value,
- type: type.value,
- userCode: invitCode.value,
- }).then((res) => {
- userStore[GET_USERINFO](res)
- store.state.user.userInfo = res
- if (activeIndex.value == 0) {
- router.push('/setFond')
- } else {
- router.push({ name: 'verify', query: { type: activeIndex.value, account: activeIndex.value == 1 ? username.value : `${dialCode.value}${username.value}` } })
- }
- });
- }
-}
+};
</script>
<style lang="scss" scoped>
-.activeBKClick {
- &:active {
- background: $tab_background;
- opacity: 0.5;
- }
-}
-
-.activeClick {
- &:active {
- background: $mainbgWhiteColor;
- opacity: 0.5;
- }
-}
-
.register {
- width: 100%;
+ position: relative;
+ min-height: 100vh;
+ background: #fff;
+ padding: 56px 24px 48px;
box-sizing: border-box;
- padding: 16px;
- font-size: 13px;
- background-color: $mainbgWhiteColor;
}
-
-.top {
- padding-left: 9px;
- padding-top: 9px;
-
- img {
- width: 18px;
- height: 18px;
- }
-}
-
-.title {
- font-weight: 700;
- font-size: 26px;
- margin-top: 27px;
- margin-bottom: 33px;
-}
-
-.re-tab {
- margin-bottom: 22px;
-
- div {
- padding: 0 18px;
- height: 34px;
- line-height: 34px;
- text-align: center;
- border-radius: 4px;
- margin-right: 10px;
- }
-
- .active {
- // background: $US_tabActice_background;
- background: $bg_yellow;
- // color: $color_main;
- color: $text_color4;
- }
-}
-
-.forget {
- color: $color_main;
- font-size: 12px;
- line-height: 14px;
-}
-
-.noTips {
- margin-top: 24px;
-}
-
-.protocol {
+.reg-inner {
+ max-width: 400px;
+ margin: 0 auto;
display: flex;
+ flex-direction: column;
align-items: center;
- height: 15px;
-
- i {
- width: 15px;
- height: 15px;
- margin-right: 9px;
-
- img {
- width: 100%;
- height: 100%;
- }
- }
}
-.iptbox {
- height: 44px;
- margin-top: 8px;
- margin-bottom: 18px;
- padding: 0 20px;
- display: flex;
- justify-content: space-between;
- align-items: center;
+.reg-back {
+ position: absolute;
+ left: 24px;
+ top: 24px;
+ color: #000;
+ cursor: pointer;
+}
+
+.reg-logo-wrap {
+ width: 100px;
+ height: 100%;
border-radius: 6px;
+ // background: linear-gradient(135deg, #2c1a5c 0%, #5a37a5 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 24px;
+}
+.reg-logo {
+ width: 100%;
+ height: 100%;
+ border-radius: 6px;
+ object-fit: contain;
+}
- input {
- flex: 1;
- height: 100%;
- border: none;
- }
+.reg-title {
+ font-size: 26px;
+ font-weight: 700;
+ color: #000;
+ margin: 0 0 8px;
+}
+.reg-login {
+ font-size: 14px;
+ color: #4a4a4a;
+ margin: 0 0 6px;
+}
+.reg-login-link {
+ color: #8a2be2;
+ cursor: pointer;
+}
+.reg-lang {
+ font-size: 13px;
+ color: #9b9b9b;
+ margin: 0 0 28px;
+ cursor: pointer;
+}
- span {
- color: $color_main;
- }
+/* 输入框:与登录页一致 */
+.reg-field {
+ width: 100%;
+ margin-bottom: 16px;
+ position: relative;
+}
+.reg-field-code {
+ .reg-input { padding-right: 90px; }
+}
+.reg-field-pwd {
+ .reg-input { padding-right: 44px; }
+}
+.reg-input {
+ width: 100%;
+ height: 48px;
+ padding: 0 16px;
+ box-sizing: border-box;
+ font-size: 15px;
+ color: #333;
+ background: #f6f5fa;
+ border: none;
+ border-radius: 6px;
+ outline: none;
+}
+.reg-input::placeholder {
+ color: #9b9b9b;
+}
+.reg-send-code {
+ position: absolute;
+ right: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-size: 14px;
+ color: #8a2be2;
+ cursor: pointer;
+}
+.reg-eye {
+ position: absolute;
+ right: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: #6e6e6e;
+.reg-protocol {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 24px;
+ font-size: 13px;
+ color: #4a4a4a;
+}
+.reg-protocol-check {
+ width: 16px;
+ height: 16px;
+ flex-shrink: 0;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ cursor: pointer;
+ background: #fff;
+ display: inline-block;
+}
+.reg-protocol-check.checked {
+ background: #8a2be2;
+ border-color: #8a2be2;
+}
+.reg-protocol-link {
+ color: #8a2be2;
+ cursor: pointer;
+}
+
+ cursor: pointer;
+}
+
+.reg-protocol {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 24px;
+ font-size: 13px;
+ color: #4a4a4a;
+}
+.reg-protocol-check {
+ width: 16px;
+ height: 16px;
+ flex-shrink: 0;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ cursor: pointer;
+ background: #fff;
+ display: inline-block;
+}
+.reg-protocol-check.checked {
+ background: #8a2be2;
+ border-color: #8a2be2;
+}
+.reg-protocol-link {
+ color: #8a2be2;
+ cursor: pointer;
+}
+
+/* 主按钮:渐变,圆角 6px */
+.reg-btn {
+ width: 100%;
+ height: 48px;
+ border: none;
+ border-radius: 6px;
+ font-size: 16px;
+ font-weight: 700;
+ cursor: pointer;
+}
+.reg-btn-primary {
+ background: linear-gradient(90deg, #a443cf, #5e2bc8);
+ color: #fff;
+ margin-bottom: 12px;
+}
+.reg-btn-outline {
+ background: #fff;
+ border: 1px solid #8a2be2;
+ color: #8a2be2;
}
</style>
--
Gitblit v1.9.3