diff --git a/app/bookkeeping/bookkeeping-view.tsx b/app/bookkeeping/bookkeeping-view.tsx index 82b3c04..b87b326 100644 --- a/app/bookkeeping/bookkeeping-view.tsx +++ b/app/bookkeeping/bookkeeping-view.tsx @@ -71,14 +71,12 @@ const TXN_SCENES = [ function getChannelIdentifier(channel: ChannelWithAccountNames): string { if (channel.channelType === "PAYMENT_CARD") { - let suffix = channel.cardNumberSuffix?.trim() - if ( - !suffix && - channel.cardNumberFull && - channel.cardNumberFull.length >= 4 - ) { - suffix = channel.cardNumberFull.slice(-4) - } + const digits = ( + channel.cardNumberSuffix || + channel.cardNumberFull || + "" + ).replace(/\D/g, "") + const suffix = digits.length >= 4 ? digits.slice(-4) : digits return suffix ? `•••• ${suffix}` : "" } if (channel.channelType === "E_WALLET") { diff --git a/app/channels/channel-dialog.tsx b/app/channels/channel-dialog.tsx index 6917368..2272701 100644 --- a/app/channels/channel-dialog.tsx +++ b/app/channels/channel-dialog.tsx @@ -275,11 +275,20 @@ export function ChannelDialog({ cardBrandRequest.current += 1 setCardBrand((value as CardBrand | null) || "") }} + itemToStringLabel={(brand: CardBrand) => + brand ? CARD_BRAND_LABELS[brand] || brand : "" + } + itemToStringValue={(brand: CardBrand) => + brand + ? `${brand} ${CARD_BRAND_LABELS[brand] || ""}` + : "" + } autoHighlight > diff --git a/app/channels/channels-view.tsx b/app/channels/channels-view.tsx index 4e22e65..06ff887 100644 --- a/app/channels/channels-view.tsx +++ b/app/channels/channels-view.tsx @@ -118,6 +118,15 @@ function formatCardNumber(cardNumber: string) { .trim() } +function getCardSuffix(channel: ChannelWithAccountNames) { + const digits = ( + channel.cardNumberSuffix || + channel.cardNumberFull || + "" + ).replace(/\D/g, "") + return digits.length >= 4 ? digits.slice(-4) : digits +} + export function ChannelsView({ initialChannels, initialAccounts, @@ -402,12 +411,7 @@ export function ChannelsView({ {visibleCardIds.has(channel.id) && channel.cardNumberFull ? formatCardNumber(channel.cardNumberFull) - : `•••• ${ - channel.cardNumberSuffix || - formatCardNumber( - channel.cardNumberFull || "" - ).slice(-4) - }`} + : `•••• ${getCardSuffix(channel)}`} {channel.cardNumberFull && ( <> diff --git a/lib/actions/channel.ts b/lib/actions/channel.ts index 5d23661..941c104 100644 --- a/lib/actions/channel.ts +++ b/lib/actions/channel.ts @@ -133,10 +133,16 @@ export async function createChannelAction( return { success: false, error: "关联的部分账户不存在或已被删除" } } - // 自动提取或补全卡号后4位 - let suffix = val.cardNumberSuffix?.trim() || null - if (!suffix && val.cardNumberFull && val.cardNumberFull.length >= 4) { - suffix = val.cardNumberFull.slice(-4) + // 自动提取并清洗纯数字卡号及后4位 + const cleanFull = val.cardNumberFull + ? val.cardNumberFull.replace(/\D/g, "") + : "" + const cleanSuffix = val.cardNumberSuffix + ? val.cardNumberSuffix.replace(/\D/g, "") + : "" + let suffix = cleanSuffix.slice(-4) || null + if (!suffix && cleanFull.length >= 4) { + suffix = cleanFull.slice(-4) } const [newChannel] = await db @@ -151,8 +157,9 @@ export async function createChannelAction( region: val.region ? val.region.toUpperCase().trim() : null, issuerName: val.issuerName?.trim() || null, cardType: val.cardType || null, - cardNumberFull: val.cardNumberFull?.trim() || null, - cardNumberSuffix: suffix, + cardNumberFull: + val.channelType === "PAYMENT_CARD" ? cleanFull || null : null, + cardNumberSuffix: val.channelType === "PAYMENT_CARD" ? suffix : null, cardBrand: val.cardBrand?.trim() || null, platform: val.platform?.trim() || null, platformAccountId: val.platformAccountId?.trim() || null, @@ -205,9 +212,16 @@ export async function updateChannelAction( return { success: false, error: "关联的部分账户不存在或已被删除" } } - let suffix = val.cardNumberSuffix?.trim() || null - if (!suffix && val.cardNumberFull && val.cardNumberFull.length >= 4) { - suffix = val.cardNumberFull.slice(-4) + // 自动提取并清洗纯数字卡号及后4位 + const cleanFull = val.cardNumberFull + ? val.cardNumberFull.replace(/\D/g, "") + : "" + const cleanSuffix = val.cardNumberSuffix + ? val.cardNumberSuffix.replace(/\D/g, "") + : "" + let suffix = cleanSuffix.slice(-4) || null + if (!suffix && cleanFull.length >= 4) { + suffix = cleanFull.slice(-4) } const [updated] = await db @@ -220,8 +234,9 @@ export async function updateChannelAction( region: val.region ? val.region.toUpperCase().trim() : null, issuerName: val.issuerName?.trim() || null, cardType: val.cardType || null, - cardNumberFull: val.cardNumberFull?.trim() || null, - cardNumberSuffix: suffix, + cardNumberFull: + val.channelType === "PAYMENT_CARD" ? cleanFull || null : null, + cardNumberSuffix: val.channelType === "PAYMENT_CARD" ? suffix : null, cardBrand: val.cardBrand?.trim() || null, platform: val.platform?.trim() || null, platformAccountId: val.platformAccountId?.trim() || null,