125 lines
3.6 KiB
TypeScript
125 lines
3.6 KiB
TypeScript
export type ReceiveAccountType = 'alipay' | 'personal' | 'corporate'
|
|
|
|
export type ReceiveAccountSnapshot = {
|
|
id: string
|
|
accountType: ReceiveAccountType
|
|
accountName: string
|
|
accountNo: string
|
|
bankName: string
|
|
bankProvince: string
|
|
bankCity: string
|
|
bankBranch: string
|
|
remark: string
|
|
}
|
|
|
|
export const ACCOUNT_TYPE_LABEL: Record<ReceiveAccountType, string> = {
|
|
alipay: '支付宝',
|
|
personal: '个人银行卡',
|
|
corporate: '对公银行账户'
|
|
}
|
|
|
|
const SNAPSHOT_FIELDS: (keyof ReceiveAccountSnapshot)[] = [
|
|
'id',
|
|
'accountType',
|
|
'accountName',
|
|
'accountNo',
|
|
'bankName',
|
|
'bankProvince',
|
|
'bankCity',
|
|
'bankBranch',
|
|
'remark'
|
|
]
|
|
|
|
function isReceiveAccountType(v: unknown): v is ReceiveAccountType {
|
|
return v === 'alipay' || v === 'personal' || v === 'corporate'
|
|
}
|
|
|
|
export function isReceiveAccountSnapshot(v: unknown): v is ReceiveAccountSnapshot {
|
|
if (!v || typeof v !== 'object') return false
|
|
const o = v as Record<string, unknown>
|
|
if (!isReceiveAccountType(o.accountType)) return false
|
|
for (const key of SNAPSHOT_FIELDS) {
|
|
if (typeof o[key] !== 'string') return false
|
|
}
|
|
return String(o.id || '').trim() !== ''
|
|
}
|
|
|
|
function trimSnapshot(v: ReceiveAccountSnapshot): ReceiveAccountSnapshot {
|
|
return {
|
|
id: String(v.id).trim(),
|
|
accountType: v.accountType,
|
|
accountName: String(v.accountName).trim(),
|
|
accountNo: String(v.accountNo).trim(),
|
|
bankName: String(v.bankName).trim(),
|
|
bankProvince: String(v.bankProvince).trim(),
|
|
bankCity: String(v.bankCity).trim(),
|
|
bankBranch: String(v.bankBranch).trim(),
|
|
remark: String(v.remark).trim()
|
|
}
|
|
}
|
|
|
|
export function normalizeReceiveAccountModelValue(
|
|
raw: unknown
|
|
): ReceiveAccountSnapshot[] {
|
|
if (Array.isArray(raw)) {
|
|
return raw.filter(isReceiveAccountSnapshot).map(trimSnapshot)
|
|
}
|
|
if (isReceiveAccountSnapshot(raw)) {
|
|
return [trimSnapshot(raw)]
|
|
}
|
|
return []
|
|
}
|
|
|
|
export function formatReceiveAccountLine(item: ReceiveAccountSnapshot): string {
|
|
const parts: string[] = [
|
|
ACCOUNT_TYPE_LABEL[item.accountType],
|
|
item.accountName,
|
|
item.accountNo
|
|
]
|
|
if (item.accountType === 'personal' || item.accountType === 'corporate') {
|
|
if (item.bankName) parts.push(item.bankName)
|
|
const { bankProvince, bankCity } = item
|
|
if (bankProvince && bankCity) {
|
|
parts.push(`${bankProvince} / ${bankCity}`)
|
|
} else if (bankProvince || bankCity) {
|
|
parts.push(bankProvince || bankCity)
|
|
}
|
|
if (item.bankBranch) parts.push(item.bankBranch)
|
|
}
|
|
if (item.remark) parts.push(item.remark)
|
|
return parts.filter(Boolean).join(' · ')
|
|
}
|
|
|
|
export function formatReceiveAccountDisplay(raw: unknown): string {
|
|
return normalizeReceiveAccountModelValue(raw)
|
|
.map(formatReceiveAccountLine)
|
|
.join('\n')
|
|
}
|
|
|
|
export function optionLabelFromRow(row: {
|
|
accountType: ReceiveAccountType | string
|
|
accountName: string
|
|
accountNo: string
|
|
}): string {
|
|
const typeLabel =
|
|
(isReceiveAccountType(row.accountType)
|
|
? ACCOUNT_TYPE_LABEL[row.accountType]
|
|
: undefined) || row.accountType
|
|
return [typeLabel, row.accountName, row.accountNo].filter(Boolean).join(' · ')
|
|
}
|
|
|
|
export function snapshotFromRow(row: any): ReceiveAccountSnapshot {
|
|
const accountType = row?.accountType
|
|
return {
|
|
id: String(row?.id ?? '').trim(),
|
|
accountType: isReceiveAccountType(accountType) ? accountType : 'personal',
|
|
accountName: String(row?.accountName ?? '').trim(),
|
|
accountNo: String(row?.accountNo ?? '').trim(),
|
|
bankName: String(row?.bankName ?? '').trim(),
|
|
bankProvince: String(row?.bankProvince ?? '').trim(),
|
|
bankCity: String(row?.bankCity ?? '').trim(),
|
|
bankBranch: String(row?.bankBranch ?? '').trim(),
|
|
remark: String(row?.remark ?? '').trim()
|
|
}
|
|
}
|