Просмотр исходного кода

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>
zlwu 1 месяц назад
Родитель
Сommit
20a8bf538a

+ 12 - 0
mobile-oa-h5/src/market/form-payload.js

@@ -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 || []) {

+ 13 - 0
mobile-oa-h5/src/market/form-payload.test.js

@@ -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
mobile-oa-h5/src/market/modules/protocol.js

@@ -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' },