feat(mobile-oa-h5): wire samplePayments into protocol payload and detail

Drop read-only payment stubs; detail shows per-sample payment cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-10-13 15:30:22 +08:00
1 parent 66e1c8334c
commit 20a8bf538a
3 files changed
+68 -18

No files matched your search

+12
View File
@@ -68,6 +68,18 @@ export function buildMarketActionPayload(module, action, payload) {
return clean
}
/** 细胞存储协议保存时附加 samplePayments;科研捐赠忽略 */
export function mergeProtocolSamplePayments(payload, samplePayments) {
const next = { ...(payload || {}) }
if (String(next.source || '') !== 'cell_storage') {
delete next.samplePayments
return next
}
if (samplePayments == null) return next
next.samplePayments = sanitizeMarketPayload(samplePayments)
return next
}
export function validateRequiredFields(sections, formData) {
const empty = (value) => value == null || value === '' || (Array.isArray(value) && value.length === 0)
for (const section of sections || []) {
@@ -3,11 +3,24 @@ import test from 'node:test'
import {
buildMarketActionPayload,
mergeProtocolSamplePayments,
pickConfiguredPayload,
sanitizeMarketPayload,
validateRequiredFields
} from './form-payload.js'
test('mergeProtocolSamplePayments attaches only for cell_storage', () => {
const pays = [{ sampleCode: 'S1', payMode: 'dj', contractAmount: 1, schedules: [] }]
assert.equal(
mergeProtocolSamplePayments({ source: 'cell_storage', samples: [] }, pays).samplePayments.length,
1
)
assert.equal(
mergeProtocolSamplePayments({ source: 'research_donation' }, pays).samplePayments,
undefined
)
})
test('removes authorization and routing fields recursively from form payloads', () => {
assert.deepEqual(
sanitizeMarketPayload({
+43 -18
View File
@@ -139,19 +139,49 @@ export default {
}))
}
]
if (detail?.source === 'cell_storage' || detail?.payment) {
values.push({
key: 'payment',
title: '缴费信息',
fields: fields(detail?.payment, [
['payMode', '缴费模式', { map: (item) => label(PAY_MODE_LABELS, item), tag: true }],
['contractAmount', '合同金额'], ['installmentCount', '分期期数'],
['installmentIntervalMonths', '每期间隔(月)'], ['lumpSumDeadline', '趸交截止时间'],
['installmentStartDate', '分期开始时间'], ['installmentAdvanceDays', '提前催缴预警(天)'],
['remark', '缴费备注']
]),
cards: []
})
if (detail?.source === 'cell_storage' || detail?.payment || detail?.samplePayments) {
const samplePays = Array.isArray(detail?.samplePayments) ? detail.samplePayments : []
if (samplePays.length) {
values.push({
key: 'payment',
title: '缴费信息',
fields: [],
cards: samplePays.map((pay, index) => ({
key: String(pay?.id || pay?.sampleCode || `pay-${index}`),
title: pay?.sampleCode || `样本缴费 ${index + 1}`,
statusText: label(PAY_MODE_LABELS, pay?.payMode),
fields: [
{ label: '缴费模式', value: label(PAY_MODE_LABELS, pay?.payMode), tag: true },
{ label: '合同金额', value: value(pay, 'contractAmount') },
...(String(pay?.payMode || '') === 'dj'
? [{ label: '趸交截止时间', value: value(pay, 'lumpSumDeadline') }]
: [
{ label: '分期期数', value: value(pay, 'installmentCount') },
{ label: '每期间隔(月)', value: value(pay, 'installmentIntervalMonths') },
{ label: '分期开始时间', value: value(pay, 'installmentStartDate') },
{ label: '提前催缴预警(天)', value: value(pay, 'installmentAdvanceDays') }
]),
...((pay?.schedules || []).map((sch, sIdx) => ({
label: `第 ${sch?.scheduleNo || sIdx + 1} 期`,
value: `应缴 ${sch?.dueAmount ?? '—'} / ${sch?.dueDate || '—'}`
})))
]
}))
})
} else {
values.push({
key: 'payment',
title: '缴费信息',
fields: fields(detail?.payment, [
['payMode', '缴费模式', { map: (item) => label(PAY_MODE_LABELS, item), tag: true }],
['contractAmount', '合同金额'], ['installmentCount', '分期期数'],
['installmentIntervalMonths', '每期间隔(月)'], ['lumpSumDeadline', '趸交截止时间'],
['installmentStartDate', '分期开始时间'], ['installmentAdvanceDays', '提前催缴预警(天)'],
['remark', '缴费备注']
]),
cards: []
})
}
}
values.push({
key: 'attachments',
@@ -233,11 +263,6 @@ export default {
{ key: 'specialRemark', label: '特殊说明', type: 'textarea' },
{ key: 'remark', label: '备注', type: 'textarea' }
] },
{ key: 'payment', title: '缴费信息(只读)', nested: true, readOnly: true, editOnly: true, source: 'cell_storage', fields: [
{ key: 'payMode', label: '缴费模式', readOnly: true },
{ key: 'contractAmount', label: '合同金额', readOnly: true },
{ key: 'remark', label: '缴费备注', readOnly: true }
] },
{ key: 'attachments', title: '附件与确认', nested: true, fields: [
{ key: 'protocolAttachments', label: '协议附件', type: 'upload', source: 'cell_storage' },
{ key: 'consentFormUrls', label: '知情同意书', type: 'upload' },