feat(web-admin): flatten research donation excel-parity list fields

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-10-13 13:14:09 +08:00
1 parent bee2c0d193
commit aa231ea5f8
2 files changed
+72 -6

No files matched your search

@@ -70,6 +70,38 @@ describe('flattenProtocolAuditRows', () => {
])
assert.equal(rows[0].protocolNo, 'JZ-001')
})
it('passes research donation excel-parity fields from protocol', () => {
const rows = flattenProtocolAuditRows([
{
id: 'd2',
donationNo: 'JZ-002',
monthlyVerifyNo: '202508001',
donationStatus: 'sdfq',
voidDesc: '母血乙肝阳性',
newbornDeliveryTime: '2025-08-29 12:26:00',
newbornSex: '0',
newbornWeightGram: 3000,
deliveryMode: 'sc',
birthOrder: 1,
maternalBloodCollectTime: '2025-08-29 13:30:00',
consentFormUrls: 'https://x/a.pdf',
infectiousDiseaseReportUrls: '',
attachmentUrls: 'https://x/b.pdf',
remark: '备注一',
sampleItems: [{ sampleTypeName: 'NK', sampleCode: 'D2', labStorageCode: 'A1' }]
}
])
assert.equal(rows[0].monthlyVerifyNo, '202508001')
assert.equal(rows[0].donationStatus, 'sdfq')
assert.equal(rows[0].voidDesc, '母血乙肝阳性')
assert.equal(rows[0].birthOrder, '1')
assert.equal(rows[0].newbornWeightGram, '3000')
assert.equal(rows[0].consentFormUrls, 'https://x/a.pdf')
assert.equal(rows[0].infectiousDiseaseReportUrls, '')
assert.equal(rows[0].attachmentUrls, 'https://x/b.pdf')
assert.equal(rows[0].remark, '备注一')
})
})
describe('uniqueProtocolsFromFlatRows', () => {
@@ -111,7 +143,7 @@ describe('firstPayTimeLines', () => {
})
assert.deepEqual(lines, ['2025-09-15 09:20:00'])
})
it('among period-1 transfers picks the latest transferTime', () => {
it('among period-1 transfers picks the earliest transferTime', () => {
const lines = firstPayTimeLines({
paymentDetails: [
{ installmentNo: 1, transferTime: '2025-09-15 09:20:00' },
@@ -120,7 +152,7 @@ describe('firstPayTimeLines', () => {
{ installmentNo: 2, transferTime: '2025-10-15 10:05:00' }
]
})
assert.deepEqual(lines, ['2025-09-20 14:30:00'])
assert.deepEqual(lines, ['2025-09-15 09:20:00'])
})
it('empty when period 1 has no transferTime', () => {
const lines = firstPayTimeLines({
+38 -4
View File
@@ -35,6 +35,20 @@ export type ProtocolAuditFlatRow = {
transportType: string
transportLabel: string
paymentSummary: QcProtocolPaymentSummary | null
monthlyVerifyNo: string
donationStatus: string
voidDesc: string
voidType: string
newbornDeliveryTime: string
newbornSex: string
newbornWeightGram: string
deliveryMode: string
birthOrder: string
maternalBloodCollectTime: string
consentFormUrls: string
infectiousDiseaseReportUrls: string
attachmentUrls: string
remark: string
}
function asRecord(v: unknown): Record<string, unknown> | null {
@@ -97,7 +111,27 @@ export function flattenProtocolAuditRows(
paymentSummary:
protocol.paymentSummary && typeof protocol.paymentSummary === 'object'
? (protocol.paymentSummary as QcProtocolPaymentSummary)
: null
: null,
monthlyVerifyNo: str(protocol.monthlyVerifyNo),
donationStatus: str(protocol.donationStatus),
voidDesc: str(protocol.voidDesc),
voidType: str(protocol.voidType),
newbornDeliveryTime: str(protocol.newbornDeliveryTime),
newbornSex: str(protocol.newbornSex),
newbornWeightGram:
protocol.newbornWeightGram == null || protocol.newbornWeightGram === ''
? ''
: String(protocol.newbornWeightGram),
deliveryMode: str(protocol.deliveryMode),
birthOrder:
protocol.birthOrder == null || protocol.birthOrder === ''
? ''
: String(protocol.birthOrder),
maternalBloodCollectTime: str(protocol.maternalBloodCollectTime),
consentFormUrls: str(protocol.consentFormUrls),
infectiousDiseaseReportUrls: str(protocol.infectiousDiseaseReportUrls),
attachmentUrls: str(protocol.attachmentUrls),
remark: str(protocol.remark)
})
})
}
@@ -118,8 +152,8 @@ export function uniqueProtocolsFromFlatRows(
}
/**
* 首期缴费时间:优先用后端 firstPayTransferTime(第 1 期转账最后一笔);
* 否则从 paymentDetails 中取第 1 期 transferTime 最晚的一笔。
* 首期缴费时间:优先用后端 firstPayTransferTime(第 1 期转账最早一笔);
* 否则从 paymentDetails 中取第 1 期 transferTime 最早的一笔。
* 无转账时间时返回空(不回退应缴日)。
*/
export function firstPayTimeLines(
@@ -149,5 +183,5 @@ export function firstPayTimeLines(
.filter(Boolean)
.sort()
if (!times.length) return []
return [times[times.length - 1]]
return [times[0]]
}