fix(channels): sanitize card data and format suffixes
This commit is contained in:
@@ -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") {
|
||||
|
||||
@@ -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
|
||||
>
|
||||
<ComboboxInput
|
||||
id="cardBrand"
|
||||
placeholder="选择卡组织"
|
||||
className="w-full"
|
||||
disabled={isPending}
|
||||
/>
|
||||
<ComboboxContent>
|
||||
|
||||
@@ -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)}`}
|
||||
</span>
|
||||
{channel.cardNumberFull && (
|
||||
<>
|
||||
|
||||
+26
-11
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user