fix(mobile-oa-h5): align payment list/detail tags with registry mirror
Prefer progressStatus codes and explicit tagType over Chinese heuristics. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
87f1e9a4eb
commit
79f9c8785b
5 files changed
+107
-40
No files matched your search
@@ -28,7 +28,7 @@
|
||||
:class="{ 'is-wide': field.wide }"
|
||||
>
|
||||
<span>{{ field.label }}</span>
|
||||
<van-tag v-if="field.tag" class="market-tag" :type="resolveStatusTone(field.value)" size="medium" round :title="field.value">{{ field.value }}</van-tag>
|
||||
<van-tag v-if="field.tag" class="market-tag" :type="field.tagType || resolveStatusTone(field.value)" size="medium" round :title="field.value">{{ field.value }}</van-tag>
|
||||
<b v-else :class="{ 'is-money': field.money }">{{ field.value }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -82,7 +82,7 @@
|
||||
:class="{ 'is-wide': field.wide }"
|
||||
>
|
||||
<span>{{ field.label }}</span>
|
||||
<van-tag v-if="field.tag" class="market-tag" :type="resolveStatusTone(field.value)" size="medium" round :title="field.value">{{ field.value }}</van-tag>
|
||||
<van-tag v-if="field.tag" class="market-tag" :type="field.tagType || resolveStatusTone(field.value)" size="medium" round :title="field.value">{{ field.value }}</van-tag>
|
||||
<b v-else :class="{ 'is-money': field.money }">{{ field.value }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -181,7 +181,7 @@ const props = defineProps({
|
||||
defineEmits(['action', 'toggle-select'])
|
||||
|
||||
const card = computed(() => buildMarketCard(props.module, props.role, props.item))
|
||||
const statusTone = computed(() => resolveStatusTone(card.value.status))
|
||||
const statusTone = computed(() => card.value.statusTone || resolveStatusTone(card.value.status))
|
||||
const samplesOpen = ref(false)
|
||||
const periodOpenKeys = ref({})
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { formatMoney } from './money.js'
|
||||
import { resolveStatusTag, samplePaymentProgress, payMode } from './status-tag-registry.js'
|
||||
|
||||
const SEARCH_PLACEHOLDERS = Object.freeze({
|
||||
protocol: '搜索姓名 / 身份证号 / 电话',
|
||||
@@ -215,18 +216,29 @@ function paymentPeriodBlock(period, index) {
|
||||
}
|
||||
}
|
||||
|
||||
function paymentProgressTag(item) {
|
||||
const raw = item?.progressStatus || item?.paymentProgress || item?.progress
|
||||
if (raw != null && String(raw).trim()) {
|
||||
return resolveStatusTag(samplePaymentProgress, raw)
|
||||
}
|
||||
const fallback = Number(item?.paidAmount || 0) > 0 ? '部分已缴' : '待缴费'
|
||||
return resolveStatusTag(samplePaymentProgress, fallback)
|
||||
}
|
||||
|
||||
function paymentCard(item) {
|
||||
const progress = label({}, item.paymentProgress || item.progress || (Number(item.paidAmount || 0) > 0 ? '部分已缴' : '待缴清'))
|
||||
const progress = paymentProgressTag(item)
|
||||
const mode = resolveStatusTag(payMode, item.payMode)
|
||||
const periods = (Array.isArray(item.periods) ? item.periods : []).filter(isPaymentPeriodPresent)
|
||||
return {
|
||||
title: text(item.motherName),
|
||||
subtitle: text(item.sampleCode),
|
||||
status: progress,
|
||||
status: progress.label,
|
||||
statusTone: progress.tagType,
|
||||
fields: [
|
||||
field('姓名', item.motherName), field('手机号', item.motherPhone),
|
||||
field('样本编码', item.sampleCode), field('签署日期', item.signDate),
|
||||
field('存储项目', item.sampleTypeName), field('合同总额', money(item.contractAmount), { money: true }),
|
||||
field('缴费方式', label(PAY_MODE_LABELS, item.payMode), { tag: true }),
|
||||
field('缴费方式', mode.label, { tag: true, tagType: mode.tagType }),
|
||||
field('应收总额', money(item.receivableAmount), { money: true })
|
||||
],
|
||||
periodBlocks: periods.map(paymentPeriodBlock),
|
||||
|
||||
@@ -132,6 +132,25 @@ test('payment card formats summary totals and progress', () => {
|
||||
allowedActions: ['register-transfer']
|
||||
})
|
||||
assert.equal(card.status, '部分已缴')
|
||||
|
||||
assert.equal(
|
||||
buildMarketCard('payment', 'specialist', {
|
||||
motherName: '待缴', sampleCode: 'S-dfj', progressStatus: 'dfj', paidAmount: '0'
|
||||
}).status,
|
||||
'待缴费'
|
||||
)
|
||||
assert.equal(
|
||||
buildMarketCard('payment', 'specialist', {
|
||||
motherName: '待缴', sampleCode: 'S-dfj', progressStatus: 'dfj', paidAmount: '0'
|
||||
}).statusTone,
|
||||
'info'
|
||||
)
|
||||
assert.equal(
|
||||
buildMarketCard('payment', 'manager', {
|
||||
motherName: '旧文案', sampleCode: 'S-legacy', paymentProgress: '待缴清', paidAmount: '0'
|
||||
}).status,
|
||||
'待缴费'
|
||||
)
|
||||
assert.equal(card.subtitle, 'S-1')
|
||||
assert.ok(card.fields.some((field) => field.label === '样本编码' && field.value === 'S-1'))
|
||||
assert.ok(card.fields.some((field) => field.label === '签署日期' && field.value === '2026-10-01'))
|
||||
|
||||
@@ -235,6 +235,23 @@ test('payment detail presents real backend progress, schedule statuses, and comb
|
||||
assert.equal(schedules.find((card) => card.key === 'void').statusText, '已作废')
|
||||
})
|
||||
|
||||
test('payment progress dfj aligns with web-admin samplePaymentProgress 待缴费', () => {
|
||||
const payment = getMarketModule('payment')
|
||||
const byCode = payment.detailSections({ progressStatus: 'dfj' })
|
||||
const progressField = byCode[0].fields.find((field) => field.label === '缴费进度')
|
||||
assert.equal(progressField.value, '待缴费')
|
||||
assert.equal(progressField.tagType, 'info')
|
||||
const filter = payment.inlineDropdownFilters.find((row) => row.key === 'progressStatus')
|
||||
assert.deepEqual(
|
||||
filter.options.map((row) => [row.value, row.text]),
|
||||
[
|
||||
['dfj', '待缴费'],
|
||||
['bfyj', '部分已缴'],
|
||||
['yjq', '已缴清']
|
||||
]
|
||||
)
|
||||
})
|
||||
|
||||
test('protocol detail recognizes the combined lump-sum and installment pay mode', () => {
|
||||
const sections = getMarketModule('protocol').detailSections({
|
||||
source: 'cell_storage',
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import { formatMoney } from '../money.js'
|
||||
import {
|
||||
resolveStatusTag,
|
||||
samplePaymentProgress,
|
||||
paymentScheduleStatus,
|
||||
payStatus,
|
||||
payMode,
|
||||
protocolStatus,
|
||||
donationStatus
|
||||
} from '../status-tag-registry.js'
|
||||
|
||||
const PAY_MODE = Object.freeze({ dj: '趸交', fq: '分期', fgd: '分改趸', djfq: '趸交+分期' })
|
||||
const PROTOCOL_STATUS = Object.freeze({
|
||||
dsx: '待生效', dqr: '待确认', sxz: '生效中', ygq: '已过期',
|
||||
yzf: '已作废', sdfq: '属地废弃', zckc: '转细胞存储', zky: '转科研'
|
||||
})
|
||||
const PAYMENT_PROGRESS = Object.freeze({
|
||||
dfj: '待缴清', bfyj: '部分已缴', yjq: '已缴清',
|
||||
待缴清: '待缴清', 待缴费: '待缴清', 部分已缴: '部分已缴', 部分缴费: '部分已缴', 已缴清: '已缴清'
|
||||
})
|
||||
const SCHEDULE_STATUS = Object.freeze({
|
||||
open: '待缴清', cleared: '已缴清', void: '已作废',
|
||||
pending: '待缴清', partial: '部分到账', paid: '已缴清', closed: '已关闭'
|
||||
})
|
||||
const PAY_STATUS = Object.freeze({
|
||||
dfj: '已付款', jfqrz: '付款确认中', yjf: '付款完成', tfqrz: '退费确认中', ytf: '已退费'
|
||||
})
|
||||
const TRANSFER_TYPE = Object.freeze({
|
||||
wxzz: '微信转账', wx: '微信转账', wechat: '微信转账',
|
||||
zzbzz: '支付宝转账', zfb: '支付宝转账', alipay: '支付宝转账',
|
||||
@@ -39,8 +32,33 @@ function displayDate(value) {
|
||||
: text || '—'
|
||||
}
|
||||
|
||||
function progressTag(code) {
|
||||
return resolveStatusTag(samplePaymentProgress, code)
|
||||
}
|
||||
|
||||
function scheduleTag(code) {
|
||||
return resolveStatusTag(paymentScheduleStatus, code)
|
||||
}
|
||||
|
||||
function transferPayTag(code) {
|
||||
return resolveStatusTag(payStatus, code)
|
||||
}
|
||||
|
||||
function payModeTag(code) {
|
||||
return resolveStatusTag(payMode, code)
|
||||
}
|
||||
|
||||
/** 缴费详情协议状态:细胞存储走 protocolStatus,捐赠侧码(如 zckc)走 donationStatus */
|
||||
function protocolStatusTag(code) {
|
||||
const key = String(code || '').trim()
|
||||
if (!key) return { label: '—', tagType: 'info' }
|
||||
if (protocolStatus[key]) return resolveStatusTag(protocolStatus, key)
|
||||
if (donationStatus[key]) return resolveStatusTag(donationStatus, key)
|
||||
return resolveStatusTag(protocolStatus, key)
|
||||
}
|
||||
|
||||
function transferCard(transfer, index) {
|
||||
const statusText = label(PAY_STATUS, transfer?.payStatus)
|
||||
const pay = transferPayTag(transfer?.payStatus)
|
||||
const transferType = label(TRANSFER_TYPE, transfer?.transferType)
|
||||
const transferTime = transfer?.transferTime || '—'
|
||||
return {
|
||||
@@ -50,8 +68,8 @@ function transferCard(transfer, index) {
|
||||
transferIndex: index + 1,
|
||||
amount: money(transfer?.transferAmount),
|
||||
meta: `${transferType} · ${transferTime}`,
|
||||
statusText,
|
||||
statusTone: statusText.includes('确认中') ? 'warning' : statusText === '付款完成' ? 'success' : 'info',
|
||||
statusText: pay.label,
|
||||
statusTone: pay.tagType,
|
||||
fields: [
|
||||
{ label: '备注', value: transfer?.remark || '—' },
|
||||
{ label: '财务备注', value: transfer?.financeRemark || '—' },
|
||||
@@ -61,15 +79,15 @@ function transferCard(transfer, index) {
|
||||
}
|
||||
|
||||
function scheduleCard(schedule, index) {
|
||||
const statusText = label(SCHEDULE_STATUS, schedule?.scheduleStatus)
|
||||
const status = scheduleTag(schedule?.scheduleStatus)
|
||||
const transfers = schedule?.transfers || []
|
||||
return {
|
||||
key: String(schedule?.id || `schedule-${index}`),
|
||||
title: `第 ${schedule?.scheduleNo || index + 1} 期`,
|
||||
variant: 'schedule',
|
||||
cardsLabel: '转账记录',
|
||||
statusText,
|
||||
statusTone: statusText === '已缴清' ? 'success' : statusText === '部分到账' ? 'primary' : 'warning',
|
||||
statusText: status.label,
|
||||
statusTone: status.tagType,
|
||||
fields: [
|
||||
{ label: '应缴金额', value: money(schedule?.dueAmount), money: true },
|
||||
{ label: '应缴日', value: displayDate(schedule?.dueDate) },
|
||||
@@ -96,25 +114,26 @@ export default {
|
||||
key: 'payMode',
|
||||
allText: '全部缴费方式',
|
||||
options: [
|
||||
{ text: '趸交', value: 'dj' },
|
||||
{ text: '分期', value: 'fq' },
|
||||
{ text: '分改趸', value: 'fgd' },
|
||||
{ text: '趸交+分期', value: 'djfq' }
|
||||
{ text: payMode.dj.label, value: 'dj' },
|
||||
{ text: payMode.fq.label, value: 'fq' },
|
||||
{ text: payMode.fgd.label, value: 'fgd' },
|
||||
{ text: payMode.djfq.label, value: 'djfq' }
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'progressStatus',
|
||||
allText: '全部缴费进度',
|
||||
options: [
|
||||
{ text: '待缴清', value: 'dfj' },
|
||||
{ text: '部分已缴', value: 'bfyj' },
|
||||
{ text: '已缴清', value: 'yjq' }
|
||||
{ text: samplePaymentProgress.dfj.label, value: 'dfj' },
|
||||
{ text: samplePaymentProgress.bfyj.label, value: 'bfyj' },
|
||||
{ text: samplePaymentProgress.yjq.label, value: 'yjq' }
|
||||
]
|
||||
}
|
||||
],
|
||||
detailSections(detail) {
|
||||
const progress = label(PAYMENT_PROGRESS, detail?.progressStatus || detail?.paymentProgress)
|
||||
const protocolStatus = label(PROTOCOL_STATUS, detail?.protocolStatus)
|
||||
const progress = progressTag(detail?.progressStatus || detail?.paymentProgress)
|
||||
const protocol = protocolStatusTag(detail?.protocolStatus)
|
||||
const mode = payModeTag(detail?.payMode)
|
||||
return [
|
||||
{
|
||||
key: 'summary',
|
||||
@@ -124,12 +143,12 @@ export default {
|
||||
{ label: '客户', value: detail?.motherName || '—' },
|
||||
{ label: '联系电话', value: detail?.motherPhone || '—' },
|
||||
{ label: '样本编码', value: detail?.sampleCode || '—' },
|
||||
{ label: '缴费方式', value: label(PAY_MODE, detail?.payMode), tag: true, tagType: 'primary' },
|
||||
{ label: '缴费方式', value: mode.label, tag: true, tagType: mode.tagType },
|
||||
{ label: '合同额', value: money(detail?.contractAmount) },
|
||||
{ label: '已缴 / 待缴', value: `${money(detail?.paidAmount)} / ${money(detail?.dueRemainAmount ?? detail?.remainAmount)}` },
|
||||
{ label: '整体进度', value: `已缴清 ${Number(detail?.clearedScheduleCount || 0)}/${Number(detail?.activeScheduleCount || 0)} 期` },
|
||||
{ label: '协议状态', value: protocolStatus, tag: true },
|
||||
{ label: '缴费进度', value: progress, tag: true }
|
||||
{ label: '协议状态', value: protocol.label, tag: true, tagType: protocol.tagType },
|
||||
{ label: '缴费进度', value: progress.label, tag: true, tagType: progress.tagType }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user