feat(web-admin): add mp CRM contract card query helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-10-15 17:24:09 +08:00
1 parent 8a57bbed30
commit b5b3b1f327
2 files changed
+193

No files matched your search

@@ -0,0 +1,116 @@
import assert from 'node:assert/strict'
import { describe, it } from 'node:test'
import {
MP_CONTRACT_MANAGE_TABS,
MP_CONTRACT_APPROVE_TABS,
buildContractListQuery,
buildContractCard,
formatContractMoney
} from './mp-crm-contract-card'
describe('tabs', () => {
it('manage all/approving/approved; approve submitted/approved', () => {
assert.deepEqual(
MP_CONTRACT_MANAGE_TABS.map((x) => x.value),
['all', 'approving', 'approved']
)
assert.deepEqual(
MP_CONTRACT_APPROVE_TABS.map((x) => x.value),
['submitted', 'approved']
)
})
})
describe('buildContractListQuery', () => {
it('manage all excludes invalid and trims keyword', () => {
assert.deepEqual(
buildContractListQuery({
mode: 'manage',
view: 'all',
pageNum: 1,
pageSize: 20,
keyword: ' 合同 ',
currentUserId: 'u1'
}),
{ pageNum: 1, pageSize: 20, keyword: '合同', excludeStatus: 'invalid' }
)
})
it('manage approving sets status only', () => {
const q = buildContractListQuery({
mode: 'manage',
view: 'approving',
pageNum: 1,
pageSize: 20,
keyword: '',
currentUserId: 'u1'
})
assert.equal(q.status, 'approving')
assert.equal('pendingApprovalUserId' in q, false)
})
it('manage approved sets status approved', () => {
const q = buildContractListQuery({
mode: 'manage',
view: 'approved',
pageNum: 1,
pageSize: 20,
keyword: '',
currentUserId: 'u1'
})
assert.equal(q.status, 'approved')
assert.equal('approvedByUserId' in q, false)
})
it('approve submitted uses pendingApprovalUserId', () => {
const q = buildContractListQuery({
mode: 'approve',
view: 'submitted',
pageNum: 1,
pageSize: 20,
keyword: '',
currentUserId: 'u9'
})
assert.equal(q.pendingApprovalUserId, 'u9')
})
it('approve approved uses approvedByUserId', () => {
const q = buildContractListQuery({
mode: 'approve',
view: 'approved',
pageNum: 1,
pageSize: 20,
keyword: 'x',
currentUserId: 'u9'
})
assert.equal(q.approvedByUserId, 'u9')
assert.equal(q.keyword, 'x')
})
})
describe('buildContractCard', () => {
it('maps fields', () => {
const card = buildContractCard({
id: 'c1',
contractNo: 'HT001',
contractTitle: '硫酸销售合同',
customerName: '甲公司',
amount: 1000,
freight: 50,
barrelDeposit: 20,
status: 'draft',
signDate: '2026-10-01'
})
assert.equal(card.id, 'c1')
assert.equal(card.contractNo, 'HT001')
assert.equal(card.amountText, '¥1,070.00')
assert.equal(card.status, 'draft')
})
})
describe('formatContractMoney', () => {
it('formats and handles empty', () => {
assert.equal(formatContractMoney(1000), '¥1,000.00')
assert.equal(formatContractMoney(undefined), '—')
})
})
@@ -0,0 +1,77 @@
export type MpContractMode = 'manage' | 'approve'
export type MpContractManageView = 'all' | 'approving' | 'approved'
export type MpContractApproveView = 'submitted' | 'approved'
export type MpContractView = MpContractManageView | MpContractApproveView
export const MP_CONTRACT_MANAGE_TABS: Array<{ value: MpContractManageView; label: string }> = [
{ value: 'all', label: '全部' },
{ value: 'approving', label: '待审批' },
{ value: 'approved', label: '已审批' }
]
export const MP_CONTRACT_APPROVE_TABS: Array<{ value: MpContractApproveView; label: string }> = [
{ value: 'submitted', label: '待审批' },
{ value: 'approved', label: '已审批' }
]
export function formatContractMoney(amount?: number | null): string {
if (amount === undefined || amount === null || Number.isNaN(Number(amount))) return '—'
return `¥${Number(amount).toLocaleString('zh-CN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})}`
}
export function buildContractListQuery(input: {
mode: MpContractMode
view: MpContractView
pageNum: number
pageSize: number
keyword: string
currentUserId: string
}): Record<string, unknown> {
const params: Record<string, unknown> = {
pageNum: input.pageNum,
pageSize: input.pageSize
}
const kw = String(input.keyword || '').trim()
if (kw) params.keyword = kw
if (input.mode === 'manage') {
if (input.view === 'all') params.excludeStatus = 'invalid'
else if (input.view === 'approving') params.status = 'approving'
else params.status = 'approved'
return params
}
if (input.view === 'submitted') {
params.pendingApprovalUserId = input.currentUserId
} else {
params.approvedByUserId = input.currentUserId
}
return params
}
export function buildContractCard(row: {
id: string | number
contractNo?: string
contractTitle?: string
customerName?: string
amount?: number
freight?: number
barrelDeposit?: number
status?: string
signDate?: string
}) {
const total =
(Number(row.amount) || 0) + (Number(row.freight) || 0) + (Number(row.barrelDeposit) || 0)
return {
id: String(row.id),
contractNo: row.contractNo || '—',
contractTitle: row.contractTitle || '—',
customerName: row.customerName || '—',
amountText: formatContractMoney(total),
status: row.status || '',
signDate: row.signDate || '—'
}
}