| | |
| | | <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('email') }} |
| | | <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('phoneNum') |
| | | }}</div> |
| | | </div> |
| | | <ExInput :label="getRegType(activeIndex, true)" :placeholderText="getRegType(activeIndex, false)" |
| | | v-model="username" :area="isArea" :dialCode="dialCode" @selectArea="onSelectArea" :icon="icon" /> |
| | | |
| | | <ExInput :label="$t('设置登录密码')" :placeholderText="$t('passwordTips')" 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>{{ $t('验证码') }}</p> |
| | | <div class="iptbox inputBackground"> |
| | | <input class="inputBackground textColor" type="text" :placeholder="$t('entryVerifyCode')" |
| | | v-model="verifyCode"> |
| | | <span v-if="type !== 3" @click="senCode">{{ $t('sendVerifyCode') }} |
| | | <template v-if="time">({{ time }})s</template> |
| | | <div class="reg-logo-wrap"> |
| | | <img :src="LOGO" alt="" class="reg-logo" /> |
| | | </div> |
| | | <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> |
| | | |
| | | <!-- 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 (optional) --> |
| | | <div class="reg-field"> |
| | | <input |
| | | v-model="invitCode" |
| | | type="text" |
| | | class="reg-input" |
| | | :placeholder="`${$t('entryInvitCode')} (optional)`" |
| | | /> |
| | | </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('email') : t('entryEmail'); |
| | | case 2: |
| | | return bFlag ? t('phoneNum') : t('entryPhone'); |
| | | } |
| | | } |
| | | 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 (!validatePassword(password.value)) { |
| | | showToast(t('passwordTips')); |
| | | return; |
| | | } |
| | | if (repassword.value !== password.value) { |
| | | showToast(t('noSamePassword')); |
| | | if (!agree.value) { |
| | | showToast(t('agreeServiceCond')); |
| | | return; |
| | | } |
| | | 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?.msg || t('register')); |
| | | }); |
| | | }; |
| | | |
| | | 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 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 (password.value.length < 6) { |
| | | showToast(t('passwordTips')); |
| | | return |
| | | } |
| | | if (repassword.value !== password.value) { |
| | | showToast(t('noSamePassword')); |
| | | 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; |
| | | } |
| | | .reg-inner { |
| | | max-width: 400px; |
| | | margin: 0 auto; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | .top { |
| | | padding-left: 9px; |
| | | padding-top: 9px; |
| | | |
| | | img { |
| | | width: 18px; |
| | | height: 18px; |
| | | } |
| | | .reg-back { |
| | | position: absolute; |
| | | left: 24px; |
| | | top: 24px; |
| | | color: #000; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .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-logo-wrap { |
| | | width: 72px; |
| | | height: 72px; |
| | | border-radius: 18px; |
| | | background: linear-gradient(135deg, #2c1a5c 0%, #5a37a5 100%); |
| | | display: flex; |
| | | align-items: center; |
| | | height: 15px; |
| | | |
| | | i { |
| | | width: 15px; |
| | | height: 15px; |
| | | margin-right: 9px; |
| | | |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | justify-content: center; |
| | | margin-bottom: 24px; |
| | | } |
| | | |
| | | .iptbox { |
| | | .reg-logo { |
| | | width: 44px; |
| | | height: 44px; |
| | | margin-top: 8px; |
| | | margin-bottom: 18px; |
| | | padding: 0 20px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | object-fit: contain; |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | |
| | | /* 输入框:与登录页一致 */ |
| | | .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; |
| | | } |
| | | |
| | | input { |
| | | flex: 1; |
| | | height: 100%; |
| | | border: none; |
| | | } |
| | | cursor: pointer; |
| | | } |
| | | |
| | | span { |
| | | color: $color_main; |
| | | } |
| | | .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> |