| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- <template>
- <cwg-page-wrapper>
- <view class="page page-shadow">
- <u-form ref="formRef" :rules="rules" :model="formData" class="kyc-form">
- <cwg-input v-model:value="infoForm.lastName" fkey="lastName" :required="true" :label="t('card.Form.f4')"
- rulesKey="lastName" :readonly="true" :disabled="true" @change="handleChange" />
- <cwg-input v-model:value="infoForm.firstName" fkey="firstName" :required="true"
- :label="t('card.Form.f5')" rulesKey="firstName" :readonly="true" :disabled="true"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.email" fkey="email" :label="t('card.Form.f3')" :required="true"
- rulesKey="email" :readonly="true" :disabled="true" @change="handleChange" />
- <cwg-input v-model:value="infoForm.birthday" :required="true" type="date" fkey="birthday"
- :label="t('card.Form.f6')" rulesKey="birthday" :readonly="true" :disabled="true"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.gender" fkey="gender" type="select" :required="true"
- :columns="sexOptions" :label="t('card.Form.f8')" rulesKey="gender" :readonly="true" :disabled="true"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.mailingAreaCode" fkey="mailingAreaCode" type="select"
- :required="true" :columns="phoneCodes" :label="t('card.Form.f1')" rulesKey="mailingAreaCode"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.mailingMobile" fkey="mailingMobile" :required="true"
- :label="t('card.Form.f2')" rulesKey="mailingMobile" :readonly="isReadonly" :disabled="isReadonly"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.mailingCountry" fkey="mailingCountry" type="select" :required="true"
- :columns="countryOptions" :label="t('card.New1.d8')" rulesKey="mailingCountry"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.mailingTown" fkey="mailingTown" type="select" :required="true"
- :columns="cityOptions" :label="t('card.New1.d9')" rulesKey="mailingTown" @change="handleChange" />
- <cwg-input v-model:value="infoForm.addressCn" fkey="addressCn" :required="true"
- :label="t('card.New1.d10')" rulesKey="addressCn" :readonly="isReadonly" :disabled="isReadonly"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.address" fkey="address" :required="true" :label="t('card.New1.d11')"
- rulesKey="address" :readonly="isReadonly" :disabled="isReadonly" @change="handleChange" />
- <cwg-input v-model:value="infoForm.mailingPostCode" fkey="mailingPostCode" :required="true"
- :label="t('card.New1.d12')" rulesKey="mailingPostCode" :readonly="isReadonly" :disabled="isReadonly"
- @change="handleChange" />
- <cwg-input v-model:value="infoForm.login" fkey="login" type="select" :required="true"
- :columns="typesOptions" :label="t('card.New.n10')" rulesKey="login" @change="handleChange" />
- <view class="fixed-btn">
- <view class="cwg-button">
- <u-button type="primary" block @click="infoSubmit">{{ t('card.Btn.Submit') }}</u-button>
- </view>
- </view>
- </u-form>
- <card-websdk-link ref="cardWebsdkLinkRef" />
- </view>
- </cwg-page-wrapper>
- </template>
- <script setup lang="ts">
- import { ref, computed, onMounted } from 'vue'
- import { pinyin } from 'pinyin-pro'
- import { useI18n } from 'vue-i18n'
- import { onLoad } from '@dcloudio/uni-app'
- import useRouter from '@/hooks/useRouter'
- import useRoute from '@/hooks/useRoute'
- import { ucardApi } from '@/api/ucard'
- import { userApi } from '@/api/user'
- import useUserStore from '@/stores/use-user-store'
- import { Patterns, Validators } from '@/utils/validators'
- import CardWebsdkLink from '@/components/card-websdkLink.vue'
- const cardWebsdkLinkRef = ref<InstanceType<typeof CardWebsdkLink> | null>(null)
- const userStore = useUserStore()
- const userInfo = computed(() => userStore.userInfo)
- const { t } = useI18n()
- const router = useRouter()
- const route = useRoute()
- const formRef = ref()
- const reductionData = ref(0)
- const isViews = ref(false)
- // 路由参数
- const type = ref<string>('')
- const cardTypeId = ref<string>('')
- onLoad((options) => {
- type.value = options?.type || ''
- cardTypeId.value = options?.cardTypeId || ''
- })
- // 国家选项
- const countryOptions = ref<Array<{ text: string, value: string }>>([])
- const cityOptions = ref<Array<{ text: string, value: string }>>([])
- const phoneCodes = ref<Array<{ text: string, value: string }>>([])
- const isReadonly = computed(() => infoForm.value?.authStatus == 1)
- const sexOptions = ref([
- { text: t('card.Form.v1'), value: 'M' },
- { text: t('card.Form.v2'), value: 'F' },
- ])
- const typesOptions = ref<Array<any>>([])
- const idTypeOptions = ref([
- { text: t('card.Form.v3'), value: 'EUROPEAN_ID' },
- { text: t('card.Form.v4'), value: 'PASSPORT' },
- ])
- // 表单验证规则
- const rules = {
- mailingAreaCode: [Validators.required(t('card.vaildate.v1'))],
- mailingMobile: [Validators.required(t('card.vaildate.v2')), Validators.pattern(Patterns.mobile, t('card.vaildate.v44'))],
- mailingCountry: [Validators.required(t('card.vaildate.v6'), 'change')],
- mailingTown: [Validators.required(t('card.vaildate.v7'), 'change')],
- login: [Validators.required(t('vaildate.select.empty') + t('card.New.n10'), 'change')],
- address: [
- Validators.required(t('card.vaildate.v27')),
- Validators.custom((val: any) => {
- const v = String(val ?? '').trim()
- if (v.length < 2 || v.length > 40)
- return t('card.New.n1')
- return Patterns.address.test(v) ? true : t('card.New.n1')
- }),
- ],
- addressCn: [Validators.required(t('card.vaildate.v27')), Validators.pattern(Patterns.addressCn, t('card.vaildate.v27'))],
- mailingPostCode: [Validators.required(t('card.vaildate.v8')), Validators.pattern(Patterns.postcode, t('card.New.n2'))],
- }
- const infoForm = ref({
- gender: undefined,
- mailingMobile: undefined,
- mailingAreaCode: undefined,
- mailingCountry: undefined,
- mailingTown: undefined,
- addressCn: undefined,
- address: undefined,
- mailingPostCode: undefined,
- login: undefined,
- email: undefined,
- lastName: undefined,
- firstName: undefined,
- birthday: undefined,
- })
- const formData = ref<typeof infoForm.value>({} as any)
- const formDatas = ref<typeof infoForm.value>({} as any)
- const isShow = ref(false)
- async function infoSubmit() {
- try {
- const requiredFields = [
- 'mailingMobile',
- 'mailingAreaCode',
- 'mailingCountry',
- 'mailingTown',
- 'addressCn',
- 'address',
- 'mailingPostCode',
- 'login',
- ] as const
- await formRef.value?.validate(requiredFields)
- }
- catch (error: any) {
- if (Array.isArray(error) && error.length > 0) {
- uni.showToast({
- title: error[0].message,
- icon: 'none'
- })
- }
- else {
- uni.showToast({
- title: t('card.New.errer'),
- icon: 'none'
- })
- }
- return
- }
- const res = await ucardApi.ucardApply({ ...formData.value, cardTypeId: cardTypeId.value })
- if (res.code === 200) {
- uni.showToast({
- title: t('card.Msg.m1'),
- icon: 'success'
- })
- // 成功后打开 WebSDK 弹窗
- if (cardWebsdkLinkRef.value) {
- cardWebsdkLinkRef.value.getWebsdkLink(
- (res.data as any)?.cardId ||
- (formData.value as any)?.cId ||
- cardTypeId.value
- )
- }
- goCardPage()
- }
- else {
- uni.showToast({
- title: res.msg || t('common.error'),
- icon: 'none'
- })
- }
- }
- async function handleChange(value: any) {
- formData.value = { ...formData.value, [value.key]: value.value }
- if (value.key === 'login') {
- if (value.value == -1) {
- formData.value.discountType = 2
- }
- else {
- const res = typesOptions.value.find((item: any) => item.login == value.value)
- formData.value.discountType = 1
- formData.value.platform = res?.platform
- }
- }
- if (value.key === 'addressCn') {
- const containsChinese = (str: string) => /[\u4E00-\u9FA5]/.test(str)
- if (containsChinese(value.value)) {
- formData.value.address = await formatText(value.value)
- infoForm.value.address = await formatText(value.value)
- }
- else {
- formData.value.address = value.value
- infoForm.value.address = value.value
- }
- }
- if (value.key === 'mailingCountry') {
- formData.value.mailingCountry = value.value
- await getCityListForSelect(value.value)
- formData.value.mailingTown = ''
- infoForm.value.mailingTown = ''
- }
- }
- function formatText(input: string) {
- const chinesePattern = /[\u4E00-\u9FA5]+/g
- const formattedText = input.replace(chinesePattern, (match) => {
- return ` ${pinyin(match, { toneType: 'none', type: 'capitalize' })} `
- })
- return formattedText
- }
- async function reductionNum() {
- const { cId } = formData.value
- if (!cId) return
- const res = await ucardApi.reductionNum({ cId })
- if (res.code === 200) {
- reductionData.value = res.data
- }
- }
- async function accountDropdown() {
- const res = await userApi.accountDropdown()
- if (res.code === 200) {
- const data = flatData(res.data)
- const loginOptions = data.map((item: any) => {
- item.discountType = 1
- item.text
- = `${item.login} - ${groupTypeName(item.type)} - ${t('kyc.AvailableBalance')}${groupCurrency(item.currency)}${item.balance}`
- item.value = item.login
- item.disabled = item.closeFunctions?.includes('1')
- if (item.balance == 0) {
- item.disabled = true
- }
- return item
- })
- loginOptions.push({
- discountType: 2,
- text: t('kyc.AvailableBalance1') + reductionData.value,
- login: -1,
- value: -1,
- disabled: reductionData.value == 0,
- })
- typesOptions.value = loginOptions
- }
- }
- function groupTypeName(type: string) {
- if (type == '1') {
- return t('AccountType.ClassicAccount')
- }
- else if (type == '2') {
- return t('AccountType.SeniorAccount')
- }
- else if (type == '5') {
- return t('AccountType.SpeedAccount')
- }
- else if (type == '6') {
- return t('AccountType.SpeedAccount')
- }
- else if (type == '7') {
- return t('AccountType.StandardAccount')
- }
- else if (type == '8') {
- return t('AccountType.CentAccount')
- }
- else if (type == '3') {
- return t('AccountType.AgencyAccount')
- }
- return ''
- }
- function groupCurrency(type: string) {
- if (type == 'GBP') {
- return ': £'
- }
- else if (type == 'USD') {
- return ': $'
- }
- else if (type == 'EUR') {
- return ': €'
- }
- else if (type == 'USC') {
- return ': ¢'
- }
- else {
- return ': $'
- }
- }
- function flatData(data: any[]) {
- return data.flatMap((card) => {
- if (!card.rechargeCurrencyInfoList || card.rechargeCurrencyInfoList.length === 0) {
- return [
- {
- ...card,
- currency: null,
- rechargeFeeRate: null,
- rechargeFixedFee: null,
- rechargeMaxQuota: null,
- rechargeMinQuota: null,
- },
- ]
- }
- return card.rechargeCurrencyInfoList.map((recharge: any) => ({
- ...card,
- ...recharge,
- }))
- })
- }
- // 获取国家列表
- async function getCountryListForSelect() {
- try {
- const res = await ucardApi.ucardCountryCity({})
- if (res.code === 200 || res.code === 0) {
- countryOptions.value = res.data.map((item: any) => ({
- text: item.enName,
- value: item.code,
- }))
- phoneCodes.value = res.data
- .map((item: any) => ({
- text: `${item.enName} ${item.areaCode}`,
- value: item.areaCode,
- }))
- .filter((item: any) => item.value !== null && item.value !== '-')
- }
- }
- catch (error) {
- console.error('获取国家列表失败:', error)
- countryOptions.value = []
- }
- }
- // 获取城市列表
- async function getCityListForSelect(countryCode: string) {
- try {
- const res = await ucardApi.ucardCountryCity({ code: countryCode })
- if (res.code === 200 || res.code === 0) {
- const cityList = res.data.map((item: any) => ({
- text: item.enName,
- value: item.code,
- }))
- cityOptions.value = cityList
- }
- }
- catch (error) {
- console.error('获取城市列表失败:', error)
- cityOptions.value = []
- }
- }
- function goCardPage() {
- router.push({
- path: '/pages/card/index',
- })
- }
- onMounted(async () => {
- console.log(userInfo.value, 1988)
- // 第一步:先回显基本信息(不依赖下拉数据的字段)
- const userData = userInfo.value as any
- infoForm.value = {
- lastName: userData.lastName,
- firstName: userData.firstName,
- email: userData.email,
- birthday: userData.birthday,
- gender: userData.gender,
- }
- formData.value = {
- lastName: userData.lastName,
- firstName: userData.firstName,
- email: userData.email,
- birthday: userData.birthday,
- gender: userData.gender,
- }
- // 第二步:加载下拉数据
- await getCountryListForSelect()
- // 第三步:等待下拉数据加载完成后,再回显国家和城市等字段
- if (userData.mailingCountry) {
- await getCityListForSelect(userData.mailingCountry)
- // 城市列表加载完成后再回显
- infoForm.value.mailingCountry = userData.mailingCountry
- infoForm.value.mailingTown = userData.mailingTown
- formData.value.mailingCountry = userData.mailingCountry
- formData.value.mailingTown = userData.mailingTown
- }
- // 回显其他地址相关字段
- infoForm.value.mailingAreaCode = userData.mailingAreaCode
- infoForm.value.mailingMobile = userData.mailingMobile
- infoForm.value.addressCn = userData.addressCn
- infoForm.value.address = userData.address
- infoForm.value.mailingPostCode = userData.mailingPostCode
- formData.value.mailingAreaCode = userData.mailingAreaCode
- formData.value.mailingMobile = userData.mailingMobile
- formData.value.addressCn = userData.addressCn
- formData.value.address = userData.address
- formData.value.mailingPostCode = userData.mailingPostCode
- // 加载其他数据
- await reductionNum()
- await accountDropdown()
- // 最后回显登录账户字段(需要等待 accountDropdown 完成)
- if (userData.login) {
- infoForm.value.login = userData.login
- formData.value.login = userData.login
- }
- })
- </script>
- <style scoped lang="scss">
- @import "@/uni.scss";
- .page {
- // padding: px2rpx(12) px2rpx(16);
- padding-bottom: px2rpx(100);
- }
- .pointer-none {
- pointer-events: none;
- }
- .f {
- display: flex;
- align-items: flex-end;
- gap: px2rpx(12);
- .l {
- flex: 1;
- }
- .r {
- width: px2rpx(273);
- }
- }
- .fixed-btn {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- padding: px2rpx(16);
- background: #fff;
- box-shadow: 0 px2rpx(-2) px2rpx(10) rgba(0, 0, 0, 0.1);
- z-index: 100;
- }
- </style>
|