|
|
@@ -7,24 +7,24 @@
|
|
|
</cwg-header>
|
|
|
|
|
|
<view class="page page-shadow">
|
|
|
- <u-form ref="formRef" class="kyc-form">
|
|
|
+ <u-form ref="formRef" :rules="rules" :model="infoForm" class="kyc-form">
|
|
|
<template v-if="type == '1'">
|
|
|
<cwg-input v-model:value="infoForm.cardNumber1" fkey="cardNumber1" :required="true"
|
|
|
- :label="`${t('card.Form.f24')}:`" :rules="rules.cardNumber1" @change="handleChange" />
|
|
|
+ :label="`${t('card.Form.f24')}:`" rulesKey="cardNumber1" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.activeCode" fkey="activeCode" :required="true"
|
|
|
- :label="`${t('card.Form.f26')}:`" :rules="rules.activeCode" @change="handleChange" />
|
|
|
+ :label="`${t('card.Form.f26')}:`" rulesKey="activeCode" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.pin" fkey="pin" :required="true" :maxlength="6" :label="t('card.Info.s26')"
|
|
|
- :rules="rules.pin" @change="handleChange" />
|
|
|
+ rulesKey="pin" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.password" fkey="password" :required="true" :maxlength="6"
|
|
|
- :label="`${t('card.Btn.Confirm')}:`" :rules="rules.password" @change="handleChange" />
|
|
|
+ :label="`${t('card.Info.s26_1')}`" rulesKey="password" @change="handleChange" />
|
|
|
<view class="pwd">
|
|
|
- <view calss="lis" v-t="'card.vaildate.v32'" :class="{ fit: rule1 }"></view>
|
|
|
- <view calss="lis" v-t="'card.vaildate.v33'" :class="{ fit: rule2 }"></view>
|
|
|
+ <view class="lis" v-t="'card.vaildate.v32'" :class="{ fit: rule1 }"></view>
|
|
|
+ <view class="lis" v-t="'card.vaildate.v33'" :class="{ fit: rule2 }"></view>
|
|
|
</view>
|
|
|
</template>
|
|
|
<template v-if="type == '2'">
|
|
|
<cwg-input v-model:value="infoForm.cardNumber1" fkey="cardNumber1" :required="true"
|
|
|
- :label="`${t('card.Form.f24')}:`" :rules="rules.cardNumber1" @change="handleChange" />
|
|
|
+ :label="`${t('card.Form.f24')}:`" rulesKey="cardNumber1" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.amount" fkey="amount" type="number" :label="`${t('card.Form.f28')}:`"
|
|
|
:required="true" :min="rechargeMinQuota" :max="rechargeMaxQuota" :placeholder="t('card.vaildate.v26')"
|
|
|
@change="handleChange">
|
|
|
@@ -49,20 +49,20 @@
|
|
|
</template>
|
|
|
<template v-if="type == '3'">
|
|
|
<cwg-input v-model:value="infoForm.cardNumber1" fkey="cardNumber1" :required="true"
|
|
|
- :label="`${t('card.Form.f24')}:`" :rules="rules.cardNumber1" @change="handleChange" />
|
|
|
+ :label="`${t('card.Form.f24')}:`" rulesKey="cardNumber1" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.pin" fkey="pin" :required="true" :label="t('card.Info.s26')" :maxlength="6"
|
|
|
- :rules="rules.pin" @change="handleChange" />
|
|
|
+ rulesKey="pin" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.password" fkey="password" :required="true" :maxlength="6"
|
|
|
- :label="`${t('card.Btn.Confirm')}:`" :rules="rules.password" @change="handleChange" />
|
|
|
+ :label="`${t('card.Info.s26_1')}`" rulesKey="password" @change="handleChange" />
|
|
|
|
|
|
<view class="pwd">
|
|
|
- <view calss="lis" v-t="'card.vaildate.v32'" :class="{ fit: rule1 }"></view>
|
|
|
- <view calss="lis" v-t="'card.vaildate.v33'" :class="{ fit: rule2 }"></view>
|
|
|
+ <view class="lis" v-t="'card.vaildate.v32'" :class="{ fit: rule1 }"></view>
|
|
|
+ <view class="lis" v-t="'card.vaildate.v33'" :class="{ fit: rule2 }"></view>
|
|
|
</view>
|
|
|
</template>
|
|
|
<template v-if="type == '4' || type == '5'">
|
|
|
<cwg-input v-model:value="infoForm.cardNumber1" fkey="cardNumber1" :required="true"
|
|
|
- :label="`${t('card.Form.f24')}:`" :rules="rules.cardNumber1" @change="handleChange" />
|
|
|
+ :label="`${t('card.Form.f24')}:`" rulesKey="cardNumber1" @change="handleChange" />
|
|
|
<cwg-input v-model:value="infoForm.clientRemark" fkey="clientRemark" :label="`${t('card.Form.f27')}:`"
|
|
|
@change="handleChange" />
|
|
|
</template>
|
|
|
@@ -70,17 +70,20 @@
|
|
|
<view v-if="infoForm.authStatus != 1" class="fixed-btn">
|
|
|
<view class="cwg-button">
|
|
|
<u-button type="primary" block @click="infoSubmit">{{
|
|
|
- t("card.Btn.Submit")
|
|
|
+ t(btn[type])
|
|
|
}}</u-button>
|
|
|
</view>
|
|
|
</view>
|
|
|
</u-form>
|
|
|
</view>
|
|
|
+ <cwg-SuccessPrompt v-model:show="showSuccessPrompt" :title="t(title[type])" :desc="t('card.Msg.m2')"
|
|
|
+ :btn-click="btnClick" />
|
|
|
</cwg-page-wrapper>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
+
|
|
|
import { ref, onMounted, watch, computed } from "vue";
|
|
|
import { showToast } from "@/utils/toast";
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
@@ -88,10 +91,11 @@ import useRouter from "@/hooks/useRouter";
|
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
|
import { ucardApi } from "@/api/ucard";
|
|
|
import config from "@/config";
|
|
|
+import { Validators } from "@/utils/validators";
|
|
|
const { t } = useI18n();
|
|
|
const router = useRouter();
|
|
|
const form = ref({});
|
|
|
-const formRef = ref();
|
|
|
+const formRef = ref(null);
|
|
|
const infoForm = ref({
|
|
|
password: undefined,
|
|
|
cardNumber1: undefined,
|
|
|
@@ -108,12 +112,23 @@ const title = ref({
|
|
|
4: t('card.Btn.b5'),
|
|
|
5: t('card.Btn.b6')
|
|
|
})
|
|
|
+const btn = ref({
|
|
|
+ 1: t('card.Btn.Activate'),
|
|
|
+ 2: t('card.Btn.Recharge'),
|
|
|
+ 3: t('card.Btn.Submit'),
|
|
|
+ 4: t('card.Btn.Freeze'),
|
|
|
+ 5: t('card.Btn.Unfreeze')
|
|
|
+})
|
|
|
const type = ref()
|
|
|
const id = ref()
|
|
|
onLoad((options) => {
|
|
|
id.value = options.id
|
|
|
type.value = options.type
|
|
|
})
|
|
|
+const showSuccessPrompt = ref(false);
|
|
|
+const btnClick = () => {
|
|
|
+ router.push('/pages/card/index');
|
|
|
+};
|
|
|
// 动态限制
|
|
|
const exchangeRate = ref(0);
|
|
|
const rechargeMinQuota = ref(0);
|
|
|
@@ -121,14 +136,62 @@ const rechargeMaxQuota = ref(0);
|
|
|
const rechargeFixedFee = ref(0);
|
|
|
const userBalance = ref(0);
|
|
|
const pictLoading = ref(false);
|
|
|
+function validatePin(s) {
|
|
|
+ if (!/^\d{6}$/.test(s)) return false;
|
|
|
+ if (/(.)\1\1/.test(s)) return false;
|
|
|
+ const isSequential = (str) => {
|
|
|
+ let inc = true;
|
|
|
+ let dec = true;
|
|
|
+ for (let i = 1; i < str.length; i++) {
|
|
|
+ if (str[i] - str[i - 1] !== 1) inc = false;
|
|
|
+ if (str[i - 1] - str[i] !== 1) dec = false;
|
|
|
+ }
|
|
|
+ return inc || dec;
|
|
|
+ };
|
|
|
+ if (isSequential(s)) return false;
|
|
|
+ if (/^(\d{2})\1\1$/.test(s)) return false;
|
|
|
+ if (/^(\d{3})\1$/.test(s)) return false;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+function validatePina(a: any, b?: any, c?: any) {
|
|
|
+ if (typeof c === "function") {
|
|
|
+ const value = b;
|
|
|
+ const callback = c;
|
|
|
+ const val = String(value ?? "").trim();
|
|
|
+ if (validatePin(val)) {
|
|
|
+ return callback();
|
|
|
+ } else {
|
|
|
+ return callback(new Error(t("card.vaildate.v23")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+function validatePassword(a: any, b?: any, c?: any) {
|
|
|
+ if (typeof c === "function") {
|
|
|
+ const value = b;
|
|
|
+ const callback = c;
|
|
|
+ const val = String(value ?? "").trim();
|
|
|
+ if (validatePin(val)) {
|
|
|
+ if (formData.value.pin != formData.value.password) {
|
|
|
+ callback(new Error(t("vaildate.password.same")));
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ return callback();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ callback(new Error(t("vaildate.password.same")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
const rules = {
|
|
|
pin: [
|
|
|
- { required: true, message: t("card.vaildate.v23") },
|
|
|
- { pattern: config.Pattern.Pin, message: t("card.vaildate.v23") },
|
|
|
+ Validators.required(t("card.vaildate.v23")),
|
|
|
+ Validators.custom(validatePina),
|
|
|
],
|
|
|
password: [
|
|
|
- { required: true, message: t("card.vaildate.v31") },
|
|
|
- { pattern: config.Pattern.Pin, message: t("card.vaildate.v31") },
|
|
|
+ Validators.required(t("card.vaildate.v31")),
|
|
|
+ Validators.custom(validatePassword)
|
|
|
],
|
|
|
cardNumber1: [
|
|
|
{
|
|
|
@@ -186,15 +249,6 @@ const fee = computed(() => {
|
|
|
function goRechargeRecord() {
|
|
|
router.push(`/pages/recharge-record/list?cardNo=${formData.value?.cardNo}`);
|
|
|
}
|
|
|
-// 根据 type 自动取标题
|
|
|
-const headerTitle = computed(() => {
|
|
|
- const key = Number(type.value);
|
|
|
- const i18nKey = headerTitleMap[key];
|
|
|
- return i18nKey ? t(i18nKey) : t("common.unknown");
|
|
|
-});
|
|
|
-const showBack = computed(() => {
|
|
|
- return ["/", "/cards", "/finance", "/mine", "/login"].includes(route.path);
|
|
|
-});
|
|
|
// 计算属性 rule1
|
|
|
const rule1 = computed(() => {
|
|
|
if (!formData.value.pin) return false;
|
|
|
@@ -211,30 +265,36 @@ async function infoSubmit() {
|
|
|
showToast(t("card.vaildate.v22"));
|
|
|
return;
|
|
|
}
|
|
|
+ if (pictLoading.value) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ pictLoading.value = true;
|
|
|
try {
|
|
|
switch (type.value) {
|
|
|
case "1":
|
|
|
- await formRef.value?.validate(["cardNumber1", "pin", "activeCode"]);
|
|
|
+ await formRef.value?.validate();
|
|
|
ucardActivate();
|
|
|
break;
|
|
|
case "2":
|
|
|
- await formRef.value?.validate(["cardNumber1", "amount"]);
|
|
|
+ await formRef.value?.validate();
|
|
|
ucardRecharge();
|
|
|
break;
|
|
|
case "3":
|
|
|
- await formRef.value?.validate(["cardNumber1", "pin"]);
|
|
|
+ await formRef.value?.validate();
|
|
|
ucardResetPassword();
|
|
|
break;
|
|
|
case "4":
|
|
|
- await formRef.value?.validate(["cardNumber1"]);
|
|
|
+ await formRef.value?.validate();
|
|
|
ucardFreeze();
|
|
|
break;
|
|
|
case "5":
|
|
|
- await formRef.value?.validate(["cardNumber1"]);
|
|
|
+ await formRef.value?.validate();
|
|
|
ucardUnfreeze();
|
|
|
break;
|
|
|
}
|
|
|
- } catch (error) { }
|
|
|
+ } catch (error) {
|
|
|
+ pictLoading.value = false;
|
|
|
+ }
|
|
|
}
|
|
|
function backActivity() {
|
|
|
setTimeout(() => {
|
|
|
@@ -253,12 +313,9 @@ async function ucardActivate() {
|
|
|
} else {
|
|
|
showToast(res.msg);
|
|
|
}
|
|
|
+ pictLoading.value = false;
|
|
|
}
|
|
|
async function ucardResetPassword() {
|
|
|
- if (formData.value.pin != formData.value.password) {
|
|
|
- showToast(t("card.Msg.m11"));
|
|
|
- return;
|
|
|
- }
|
|
|
const res = await ucardApi.ucardResetPassword(formData.value);
|
|
|
if (res.code == 200) {
|
|
|
showToast(t("card.Msg.m6"));
|
|
|
@@ -266,6 +323,7 @@ async function ucardResetPassword() {
|
|
|
} else {
|
|
|
showToast(res.msg);
|
|
|
}
|
|
|
+ pictLoading.value = false;
|
|
|
}
|
|
|
async function ucardFreeze() {
|
|
|
const res = await ucardApi.ucardFreeze(formData.value);
|
|
|
@@ -275,6 +333,7 @@ async function ucardFreeze() {
|
|
|
} else {
|
|
|
showToast(res.msg);
|
|
|
}
|
|
|
+ pictLoading.value = false;
|
|
|
}
|
|
|
async function ucardUnfreeze() {
|
|
|
const res = await ucardApi.ucardUnfreeze(formData.value);
|
|
|
@@ -284,6 +343,7 @@ async function ucardUnfreeze() {
|
|
|
} else {
|
|
|
showToast(res.msg);
|
|
|
}
|
|
|
+ pictLoading.value = false;
|
|
|
}
|
|
|
async function getCardInfo() {
|
|
|
try {
|
|
|
@@ -341,20 +401,15 @@ async function walletBalance() {
|
|
|
async function ucardRecharge() {
|
|
|
const amount = Number(formData.value.amount);
|
|
|
const cardNo = formData.value.cardNo;
|
|
|
-
|
|
|
if (validateAmount(amount) !== true) {
|
|
|
showToast(validateAmount(amount));
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- pictLoading.value = true;
|
|
|
try {
|
|
|
const res = await ucardApi.ucardRecharge({ amount, cardNo });
|
|
|
if (res.code === 200) {
|
|
|
- showToast(t("card.Msg.m2"));
|
|
|
- setTimeout(() => {
|
|
|
- router.push(`/cards`);
|
|
|
- }, 1000);
|
|
|
+ // showToast(t("card.Msg.m2"));
|
|
|
+ showSuccessPrompt.value = true;
|
|
|
} else {
|
|
|
showToast(res.msg);
|
|
|
}
|
|
|
@@ -401,15 +456,31 @@ function handleChange(value: any) {
|
|
|
.pwd {
|
|
|
line-height: px2rpx(20);
|
|
|
|
|
|
- li {
|
|
|
+ .lis {
|
|
|
list-style-type: disc;
|
|
|
line-height: 1.2;
|
|
|
- margin: px2rpx(4) 0 px2rpx(4) px2rpx(20);
|
|
|
+ margin: px2rpx(4) 0 px2rpx(4) px2rpx(10);
|
|
|
color: #c0c4cc;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: px2rpx(-6);
|
|
|
+ top: px2rpx(6);
|
|
|
+ width: px2rpx(4);
|
|
|
+ height: px2rpx(4);
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #c0c4cc;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.fit {
|
|
|
- color: #009deb;
|
|
|
+ color: var(--main-yellow);
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ background: var(--main-yellow);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|