wupengfei
2025-09-23 22a6de40ac6693463cdbbe9ed1e3ef05fc301afc
feat: 绑定银行卡
12个文件已修改
342 ■■■■ 已修改文件
apps/cMiniApp/src/hooks/user.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/pages/mine/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/subpackages/wallet/bindBankCard/InnerPage.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/subpackages/wallet/incomeDetail/InnerPage.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/subpackages/wallet/mineWallet/InnerPage.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/subpackages/wallet/unboundBankCard/InnerPage.vue 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/constants/apiEnum.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/enterpriseWallet.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/typings.d.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/user.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/utils/common.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/utils/validator.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/hooks/user.ts
@@ -1,7 +1,11 @@
import { useUserStore } from '@/stores/modules/user';
import Taro from '@tarojs/taro';
import { object2query, LocationUtils } from '@12333/utils';
import { ParkOrHRStatus, UserCertificationFrontStatus } from '@12333/constants';
import {
  EnumUserBankCardAccess,
  ParkOrHRStatus,
  UserCertificationFrontStatus,
} from '@12333/constants';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import { MaybeRef } from 'vue';
import { useRefeshDidShow } from '@12333/hooks/infiniteLoading';
@@ -21,6 +25,10 @@
    return userDetail.value?.isReal;
  });
  const isBindBank = computed(() => {
    return userDetail.value?.bankCardAAccesses?.find(() => EnumUserBankCardAccess.Bank);
  });
  return {
    user: userInfo,
    userDetail: userDetail,
@@ -28,6 +36,7 @@
    isCertified,
    locationCity,
    userId,
    isBindBank,
  };
}
apps/cMiniApp/src/pages/mine/index.vue
@@ -58,7 +58,7 @@
    <ContentScrollView v-if="isLogin" class="mine-content-scroll-view">
      <List class="mine-list-wrapper mine-balance">
        <div class="mine-balance-title">我的余额</div>
        <div class="mine-balance-money">¥{{ toThousand(userDetail?.balance) }}</div>
        <div class="mine-balance-money">¥{{ toThousand(userDetail?.balance ?? 0) }}</div>
        <div class="mine-balance-btn" @click="goMineWallet">
          进入我的钱包
          <img :src="IconArrow" class="mine-balance-btn-icon" />
apps/cMiniApp/src/subpackages/wallet/bindBankCard/InnerPage.vue
@@ -3,8 +3,10 @@
    <div class="bind-bank-card-wrapper">
      <div class="bg-left-top"></div>
      <div class="bind-bank-card-content">
        <div class="bank-card-name">{{ '招商银行' }}</div>
        <div class="bank-card-number">{{ '**** **** **** 1234' }}</div>
        <div class="bank-card-name">{{ detail?.bank ?? '' }}</div>
        <div class="bank-card-number">
          <div class="bank-card-number-text">{{ showBankCodeForEnd4(detail?.code ?? '') }}</div>
        </div>
        <div class="bank-card-type">{{ '储蓄卡' }}</div>
      </div>
      <div class="bg-right-bottom"></div>
@@ -18,15 +20,59 @@
<script setup lang="ts">
import { useUserStore } from '@/stores/modules/user';
import { useQuery } from '@tanstack/vue-query';
import { Message, showBankCodeForEnd4 } from '@12333/utils';
import * as userServices from '@12333/services/apiV2/user';
import Taro from '@tarojs/taro';
import { EnumUserBankCardAccess } from '@12333/constants';
defineOptions({
  name: 'InnerPage',
});
const userStore = useUserStore();
const {} = useUser();
const switchTab = useSwitchTab();
function goUserCenter() {
  switchTab({
    url: RouterPath.mine,
  });
}
function handleUnbind() {}
const {
  isLoading,
  isError,
  data: detail,
  refetch,
} = useQuery({
  queryKey: ['userServices/getPersonalUserBankCard'],
  queryFn: async () => {
    return await userServices.getPersonalUserBankCard(
      { access: EnumUserBankCardAccess.Bank },
      {
        showLoading: false,
      }
    );
  },
  placeholderData: () => ({} as API.GetPersonalUserBankCardQueryResult),
  onSuccess(data) {},
});
async function handleUnbind() {
  try {
    await Message.confirm({ message: '确定要解绑银行卡吗?' });
    let params: API.DeletePersonalUserBankCardCommand = {
      access: EnumUserBankCardAccess.Bank,
    };
    let res = await userServices.deletePersonalUserBankCard(params);
    if (res) {
      Message.success('解绑成功', {
        onClosed() {
          goUserCenter();
        },
      });
    }
  } catch (error) {}
}
</script>
<style lang="scss">
@@ -34,7 +80,7 @@
.bindBankCard-page-wrapper {
  .bind-bank-card-wrapper {
    margin: 20px auto 0;
    margin: 0 auto;
    width: 660px;
    height: 360px;
    padding: 60px 72px;
apps/cMiniApp/src/subpackages/wallet/incomeDetail/InnerPage.vue
@@ -1,5 +1,5 @@
<template>
  <ProTabs
  <!-- <ProTabs
    v-model="queryState.type"
    name="home-tab"
    :showPaneContent="false"
@@ -11,7 +11,7 @@
    <ProTabPane :title="`全部`" :pane-key="0"></ProTabPane>
    <ProTabPane :title="`收入`" :pane-key="EnumUserWalletTransactionType.Income"></ProTabPane>
    <ProTabPane :title="`提现`" :pane-key="EnumUserWalletTransactionType.Withdraw"></ProTabPane>
  </ProTabs>
  </ProTabs> -->
  <List>
    <IncomeDetailListItem :item="`收入:¥${toThousand(sumIncome)} `">
      <template #title>
@@ -87,10 +87,11 @@
        page: pageParam,
        orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
      },
      type: EnumUserWalletTransactionType.Income,
    };
    if (Number(queryState.type)) {
      params.type = queryState.type;
    }
    // if (Number(queryState.type)) {
    //   params.type = queryState.type;
    // }
    if (queryState.month) {
      params.createdTimeStart = dayjs(queryState.month).startOf('month').format('YYYY-MM-DD');
      params.createdTimeEnd = dayjs(queryState.month).endOf('month').format('YYYY-MM-DD');
@@ -105,16 +106,19 @@
);
function goIncomeDetailInfo(row: API.GetPersonalUserTransactionsQueryResultItem) {
  if (row.type === EnumUserWalletTransactionType.Income) {
    Taro.navigateTo({
      url: `${RouterPath.incomeDetailInfo}?id=${row.id}`,
    });
  }
  if (row.type === EnumUserWalletTransactionType.Withdraw) {
    Taro.navigateTo({
      url: `${RouterPath.withdrawDetailInfo}?id=${row.id}`,
    });
  }
  Taro.navigateTo({
    url: `${RouterPath.incomeDetailInfo}?id=${row.id}`,
  });
  // if (row.type === EnumUserWalletTransactionType.Income) {
  //   Taro.navigateTo({
  //     url: `${RouterPath.incomeDetailInfo}?id=${row.id}`,
  //   });
  // }
  // if (row.type === EnumUserWalletTransactionType.Withdraw) {
  //   Taro.navigateTo({
  //     url: `${RouterPath.withdrawDetailInfo}?id=${row.id}`,
  //   });
  // }
}
</script>
apps/cMiniApp/src/subpackages/wallet/mineWallet/InnerPage.vue
@@ -1,14 +1,14 @@
<template>
  <div class="mine-wallet-balance">
  <!-- <div class="mine-wallet-balance">
    <WithdrawMoneyCard :money="userDetail.balance" title="账户余额(元)"></WithdrawMoneyCard>
    <nut-button type="primary" class="mine-wallet-balance-btn" @click="goWithdraw">提现</nut-button>
  </div>
  </div> -->
  <List>
    <ListItem title="收入明细" @click="goIncomeDetail"> </ListItem>
    <ListItem title="银行卡" @click="goBankBind">
      <template #extra>
        <div class="bind-bank-card">
          {{ isBinding ? '已绑定' : '未绑定、立即绑定' }}
          {{ isBindBank ? '已绑定' : '未绑定、立即绑定' }}
        </div>
      </template>
    </ListItem>
@@ -17,6 +17,7 @@
<script setup lang="ts">
import { List, ListItem, WithdrawMoneyCard } from '@12333/components';
import { EnumUserBankCardAccess } from '@12333/constants';
import Taro from '@tarojs/taro';
defineOptions({
@@ -25,7 +26,9 @@
const { userDetail } = useUser();
const isBinding = ref(false);
const isBindBank = computed(() =>
  userDetail.value?.bankCardAAccesses?.find(() => EnumUserBankCardAccess.Bank)
);
function goIncomeDetail() {
  Taro.navigateTo({
@@ -44,7 +47,7 @@
const goBankBind = useAccessReal(
  () => {
    Taro.navigateTo({
      url: `${isBinding.value ? RouterPath.bindBankCard : RouterPath.unboundBankCard}`,
      url: `${isBindBank.value ? RouterPath.bindBankCard : RouterPath.unboundBankCard}`,
    });
  },
  { message: '完成实名认证后才可进行银行卡绑定' }
apps/cMiniApp/src/subpackages/wallet/unboundBankCard/InnerPage.vue
@@ -2,22 +2,22 @@
  <ContentScrollView :paddingH="false">
    <nut-form :model-value="form" ref="formRef" :rules="rules">
      <nut-form-item label="持卡人:" class="bole-form-item" prop="name">
        <nut-input v-model.trim="form.name" placeholder="请输入持卡人" />
        <nut-input v-model.trim="form.name" placeholder="请输入持卡人" readonly />
      </nut-form-item>
      <nut-form-item label="身份证号:" class="bole-form-item" prop="name">
        <nut-input v-model.trim="form.name" placeholder="请输入身份证号" />
      <nut-form-item label="身份证号:" class="bole-form-item" prop="identity">
        <nut-input v-model.trim="form.identity" placeholder="请输入身份证号" readonly />
      </nut-form-item>
      <nut-form-item label="银行卡号:" class="bole-form-item" prop="name">
        <nut-input v-model.trim="form.name" placeholder="请输入银行卡号" />
      <nut-form-item label="银行卡号:" class="bole-form-item" prop="code">
        <nut-input v-model.trim="form.code" placeholder="请输入银行卡号" />
      </nut-form-item>
      <nut-form-item label="开户行:" class="bole-form-item" prop="name">
        <nut-input v-model.trim="form.name" placeholder="请输入开户行" />
      <nut-form-item label="开户行:" class="bole-form-item" prop="bank">
        <nut-input v-model.trim="form.bank" placeholder="请输入开户行" />
      </nut-form-item>
      <nut-form-item label="手机号:" class="bole-form-item" prop="phoneNumber" required>
        <nut-input
          v-model.trim="form.phoneNumber"
          class="nut-input-text bole-input-text"
          placeholder="请填写经办人的手机号码"
          placeholder="请填写银行预留手机号"
          type="text"
        >
          <template #right>
@@ -29,9 +29,9 @@
          </template>
        </nut-input>
      </nut-form-item>
      <nut-form-item label="短信验证码:" class="bole-form-item" prop="verificationCode" required>
      <nut-form-item label="短信验证码:" class="bole-form-item" prop="verifyCode" required>
        <nut-input
          v-model.trim="form.verificationCode"
          v-model.trim="form.verifyCode"
          class="nut-input-text bole-input-text"
          placeholder="请输入验证码"
          type="number"
@@ -47,55 +47,45 @@
<script setup lang="ts">
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
import { ProFormCaptcha } from 'senin-mini/components';
import { Message } from '@12333/utils';
import { VerificationCodeBusinessType } from '@12333/constants';
import * as commonServices from '@12333/services/api/Common';
import { FormValidator, Message } from '@12333/utils';
import * as userServices from '@12333/services/apiV2/user';
import Taro from '@tarojs/taro';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import { useQueryClient } from '@tanstack/vue-query';
import { EnumUserBankCardAccess } from '@12333/constants';
const userResumeServices = {};
const { userDetail } = useUser();
const queryClient = useQueryClient();
defineOptions({
  name: 'InnerPage',
});
const form = reactive({
  name: '',
  name: userDetail.value?.name ?? '',
  identity: userDetail.value?.identity ?? '',
  phoneNumber: '',
  verificationCode: '',
});
const {
  isLoading,
  isError,
  data: detail,
  refetch,
} = useQuery({
  queryKey: ['userResumeServices/getUserResumeBaseInfo'],
  queryFn: async () => {
    return await userResumeServices.getUserResumeBaseInfo({
      showLoading: false,
    });
  },
  placeholderData: () => ({} as API.UserResumeBaseInfoOutput),
  onSuccess(data) {
    form.name = data.name;
    form.phoneNumber = data.phoneNumber;
  },
  code: '',
  bank: '',
  bankBranch: '',
  verifyCode: '',
});
const rules = reactive<FormRules>({
  name: [{ required: true, message: '请输入持卡人' }],
  phoneNumber: [{ required: true, message: '请输入手机号' }],
  code: [
    { required: true, message: '请输入银行卡号' },
    { message: '请输入正确的银行卡号', validator: FormValidator.validatorBankCard },
  ],
  bank: [{ required: true, message: '请输入开户行' }],
  phoneNumber: [
    { required: true, message: '请填写手机号码' },
    { message: '请输入正确的手机号码', validator: FormValidator.validatorPhoneNumber },
  ],
  verifyCode: [{ required: true, message: '请输入验证码' }],
});
async function onGetCaptcha(phoneNumber: string) {
  await commonServices.sendPhoneCertificationVerificationCode(
  await userServices.sendSavePersonalUserBankCardVerifyCode(
    {
      name: form.name,
      identity: form.name,
      mobile: form.phoneNumber,
      businessType: VerificationCodeBusinessType.UserCertificationPhoneCertification,
      phoneNumber: form.phoneNumber,
    },
    { showLoading: false }
  );
@@ -113,20 +103,21 @@
async function confirm() {
  try {
    let params: API.SaveUserResumeBaseInfoInput = {
      name: form.name,
    let params: API.SavePersonalUserBankCardCommand = {
      code: form.code,
      bank: form.bank,
      phoneNumber: form.phoneNumber,
      verifyCode: form.verifyCode,
      access: EnumUserBankCardAccess.Bank,
    };
    let res = await userResumeServices.saveUserResumeBaseInfo(params);
    let res = await userServices.savePersonalUserBankCard(params);
    if (res) {
      Message.success('保存成功', {
      Message.success('绑定成功', {
        onClosed() {
          Taro.navigateTo({
            url: `${RouterPath.mineCurriculumVitae}`,
            url: `${RouterPath.bindBankCard}`,
          });
          queryClient.invalidateQueries([
            'taskCheckReceiveServices/getCheckReceiveTaskUserSubmits',
          ]);
          queryClient.invalidateQueries(['authServices/getPersonalLoginInfo']);
        },
      });
    }
packages/constants/apiEnum.ts
@@ -107,6 +107,8 @@
export enum EnumEnterpriseWalletAccess {
  /**支付宝 */
  Alipay = 10,
  /**平安银行 */
  PingAnPay = 20,
}
/** 企业钱包代进件单附件类型 */
@@ -473,6 +475,16 @@
  Fail = 40,
}
/** 用户银行卡通道 */
export enum EnumUserBankCardAccess {
  /**银行卡 */
  Bank = 1,
  /**支付宝 */
  AliPay = 10,
  /**微信 */
  WeChatPay = 20,
}
/** 用户性别 */
export enum EnumUserGender {
  /**男 */
packages/services/apiV2/enterpriseWallet.ts
@@ -310,3 +310,15 @@
    }
  );
}
/** 测试阿里支付 POST /api/user/enterpriseWallet/testAliPay */
export async function testAliPay(body: API.TestAliPayCommand, options?: API.RequestConfig) {
  return request<string>('/api/user/enterpriseWallet/testAliPay', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
packages/services/apiV2/typings.d.ts
@@ -156,8 +156,8 @@
  }
  interface APIgetPersonalUserBankCardParams {
    /** 查询个人用户银行卡信息 */
    request?: GetPersonalUserBankCardQuery;
    /** 通道 */
    access?: EnumUserBankCardAccess;
  }
  interface APIgetPersonalUserElectronSignParams {
@@ -209,6 +209,8 @@
  interface APIgetSettlementTaskUsersParams {
    /** 结算订单Id */
    id?: string;
    /** 任务Id */
    taskInfoId?: string;
  }
  interface APIgetTaskEnterpriseParams {
@@ -408,6 +410,10 @@
  interface DeleteMenuCommand {
    ids: string[];
  }
  interface DeletePersonalUserBankCardCommand {
    access?: EnumUserBankCardAccess;
  }
  interface DeleteRoleCommand {
@@ -616,6 +622,8 @@
  enum EnumEnterpriseWalletAccess {
    /**支付宝 */
    Alipay = 10,
    /**平安银行 */
    PingAnPay = 20,
  }
  enum EnumEnterpriseWalletExpandindirectOrderFileType {
@@ -949,6 +957,15 @@
    Success = 30,
    /**验收未通过 */
    Fail = 40,
  }
  enum EnumUserBankCardAccess {
    /**银行卡 */
    Bank = 1,
    /**支付宝 */
    AliPay = 10,
    /**微信 */
    WeChatPay = 20,
  }
  enum EnumUserGender {
@@ -3451,6 +3468,10 @@
    /** 协议失效时间 */
    invalidTime?: string;
    signStatus?: EnumEnterpriseWalletSignStatus;
    /** 所属银行 */
    bank?: string;
    /** 所属支行 */
    bankBranch?: string;
    /** 支付宝姓名 */
    name?: string;
    /** 支付宝登录账号 */
@@ -3467,6 +3488,8 @@
    /** 附件 */
    files?: GetEnterpriseWalletExpandindirectOrderQueryResultFile[];
    expandindirectOrderStatus?: EnumEnterpriseWalletExpandindirectOrderStatus;
    /** 余额 */
    balance?: number;
  }
  interface GetEnterpriseWalletTransactionQueryResult {
@@ -3870,6 +3893,8 @@
    avatar?: string;
    /** 姓名 */
    name?: string;
    /** 身份证号 */
    identity?: string;
    /** 手机号 */
    contactPhoneNumber?: string;
    /** 是否实名 */
@@ -3886,12 +3911,12 @@
    hireRefuseTaskCount?: number;
    /** 余额 */
    balance?: number;
    /** 已绑定的银行卡通道 */
    bankCardAAccesses?: EnumUserBankCardAccess[];
  }
  type GetPersonalUserBankCardQuery = Record<string, any>;
  interface GetPersonalUserBankCardQueryResult {
    access?: EnumEnterpriseWalletAccess;
    access?: EnumUserBankCardAccess;
    /** 银行卡号 */
    code?: string;
    /** 所属银行 */
@@ -4497,6 +4522,12 @@
    settlementStatus?: EnumTaskSettlementStatus;
    /** 结算时间 */
    settlementTime?: string;
    /** 结算流水号 */
    orderCode?: string;
    /** 创建时间 */
    createdTime?: string;
    /** 电子收据下载链接 */
    ereceiptDownloadOssUrl?: string;
  }
  interface GetTaskEnterpriseQueryResult {
@@ -4701,6 +4732,7 @@
    /** 推荐时间 */
    recommendTime?: string;
    hireStatus?: EnumTaskUserHireStatus;
    settlementStatus?: EnumTaskSettlementStatus;
    /** 发布时间 */
    createdTime?: string;
  }
@@ -5163,6 +5195,14 @@
    /** 企业Id */
    enterpriseId?: string;
    access?: EnumEnterpriseWalletAccess;
    /** 所属银行 */
    bank?: string;
    /** 所属支行 */
    bankBranch?: string;
    /** 姓名 */
    name?: string;
    /** 账号 */
    identity?: string;
  }
  interface OpenEnterpriseWalletCommandResult {
@@ -5578,7 +5618,7 @@
  }
  interface SavePersonalUserBankCardCommand {
    access?: EnumEnterpriseWalletAccess;
    access?: EnumUserBankCardAccess;
    /** 银行卡号 */
    code?: string;
    /** 所属银行 */
@@ -5587,6 +5627,8 @@
    bankBranch?: string;
    /** 银行预留手机号 */
    phoneNumber?: string;
    /** 验证码 */
    verifyCode?: string;
  }
  interface SaveRoleCommand {
@@ -5759,6 +5801,11 @@
    identity: string;
  }
  interface SendSavePersonalUserBankCardVerifyCodeCommand {
    /** 手机号码 */
    phoneNumber: string;
  }
  interface SetDictionaryDataIsDisabledCommand {
    ids?: string[];
    /** 是否已禁用 */
@@ -5879,6 +5926,7 @@
  interface SureTaskSettlementCommand {
    /** 任务Id */
    taskInfoId?: string;
    settlementAccess?: EnumEnterpriseWalletAccess;
  }
  type SyncDatabaseCommand = Record<string, any>;
@@ -6006,6 +6054,11 @@
    remark?: string;
  }
  interface TestAliPayCommand {
    code?: string;
    freezeNo?: string;
  }
  interface UpdatePhoneNumberVerifyCodeCommand {
    /** 手机号码 */
    phoneNumber: string;
packages/services/apiV2/user.ts
@@ -2,6 +2,21 @@
// @ts-ignore
import { request } from '@/utils/request';
/** 删除用户银行卡信息 DELETE /api/user/user/deletePersonalUserBankCard */
export async function deletePersonalUserBankCard(
  body: API.DeletePersonalUserBankCardCommand,
  options?: API.RequestConfig
) {
  return request<number>('/api/user/user/deletePersonalUserBankCard', {
    method: 'DELETE',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 查询运营端用户分页列表数据 POST /api/user/user/getOperationUserInfos */
export async function getOperationUserInfos(
  body: API.GetOperationUserInfosQuery,
@@ -30,8 +45,6 @@
    method: 'GET',
    params: {
      ...params,
      request: undefined,
      ...params['request'],
    },
    ...(options || {}),
  });
@@ -154,6 +167,21 @@
  });
}
/** 发送绑定银行卡短信 POST /api/user/user/sendSavePersonalUserBankCardVerifyCode */
export async function sendSavePersonalUserBankCardVerifyCode(
  body: API.SendSavePersonalUserBankCardVerifyCodeCommand,
  options?: API.RequestConfig
) {
  return request<string>('/api/user/user/sendSavePersonalUserBankCardVerifyCode', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 设置用户信息角色 PUT /api/user/user/setUserInfoRoles */
export async function setUserInfoRoles(
  body: API.SetUserInfoRolesCommand,
packages/utils/common.ts
@@ -136,6 +136,11 @@
  return realIDNumber.replace(/^(\d+)(.{6})$/, '$1******');
};
export const showBankCodeForEnd4 = (bankCode: string) => {
  if (!bankCode) return '';
  return '*'.repeat(Math.max(0, bankCode.length - 4)) + bankCode.slice(-4);
};
export const hiddenPhone = (phone: string) => {
  if (!phone) return '';
  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
packages/utils/validator.ts
@@ -98,6 +98,13 @@
    }
    return Promise.reject(ruleCfg.message);
  }
  static validatorBankCard(value: string, ruleCfg: FormItemRuleWithoutValidator) {
    if (!ruleCfg.required && !value) return Promise.resolve(true);
    if (BoleRegExp.RegBankCard.test(value)) {
      return Promise.resolve(true);
    }
    return Promise.reject(ruleCfg.message);
  }
}
export class BoleRegExp {