mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-05 21:05:39 +08:00
feat: map transfer/hb status labels into export and chat cards
This commit is contained in:
@@ -457,6 +457,74 @@ describe('export media', () => {
|
||||
expect(html).toContain("if (event.key === 'Escape')")
|
||||
expect(html).toContain('closeLightbox()')
|
||||
})
|
||||
|
||||
it('always surfaces transfer and red-packet amount, memo and status wording', () => {
|
||||
const html = renderExportPage('支付可读导出')
|
||||
const dom = new JSDOM(html, { runScripts: 'outside-only' })
|
||||
const messages: Message[] = [
|
||||
{
|
||||
...messageForArchive('transfer-paid', 'fixture', '支付可读导出', '收到转账2900.00元。', 1),
|
||||
type: '转账',
|
||||
contentData: {
|
||||
type: 'share',
|
||||
typeVal: '2000',
|
||||
title: '微信转账',
|
||||
des: '收到转账2900.00元。',
|
||||
url: '',
|
||||
transfer: {
|
||||
amountText: '¥2900.00',
|
||||
payMemo: '房租',
|
||||
transferStatus: '2',
|
||||
transferStatusText: '已收款',
|
||||
transferId: '1000050001202609130232821248942',
|
||||
paySubtype: '3'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
...messageForArchive('hb-claimed', 'fixture', '支付可读导出', '我给你发了一个红包,赶紧去拆!', 2),
|
||||
type: '微信红包',
|
||||
contentData: {
|
||||
type: 'redPacket',
|
||||
title: '中秋快乐',
|
||||
description: '我给你发了一个红包,赶紧去拆!',
|
||||
pay: {
|
||||
sendTitle: '中秋快乐',
|
||||
sceneText: '微信红包',
|
||||
hbStatus: '1',
|
||||
redPacketStatusText: '已领取',
|
||||
sendId: '1000039801202609247176036834007',
|
||||
hbType: '1'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
Object.assign(dom.window, {
|
||||
__WECHAT_EXPORT__: {
|
||||
version: 1,
|
||||
sourceId: 'fixture',
|
||||
name: '支付可读导出',
|
||||
exportedAt: '2026-09-24T12:00:00.000Z',
|
||||
messages
|
||||
}
|
||||
})
|
||||
|
||||
dom.window.eval(inlineScriptOf(html))
|
||||
|
||||
const cards = [...dom.window.document.querySelectorAll('.payment-content')]
|
||||
expect(cards).toHaveLength(2)
|
||||
const transfer = cards.find((node) => node.classList.contains('transfer'))!
|
||||
const redPacket = cards.find((node) => node.classList.contains('red-packet'))!
|
||||
// 即使消息带 des,金额/备注/状态也不能被盖住。
|
||||
expect(transfer.textContent).toContain('¥2900.00')
|
||||
expect(transfer.textContent).toContain('备注:房租')
|
||||
expect(transfer.textContent).toContain('已收款')
|
||||
expect(transfer.textContent).toContain('收到转账2900.00元。')
|
||||
expect(transfer.textContent).toContain('单号 1000050001202609130232821248942')
|
||||
expect(redPacket.textContent).toContain('已领取')
|
||||
expect(redPacket.textContent).toContain('我给你发了一个红包,赶紧去拆!')
|
||||
dom.window.close()
|
||||
})
|
||||
})
|
||||
|
||||
function messageForArchive(
|
||||
|
||||
@@ -206,4 +206,88 @@ describe('message parser', () => {
|
||||
messageType: 999
|
||||
})
|
||||
})
|
||||
|
||||
it('parses transfer wcpayinfo fields (type 2000)', () => {
|
||||
// 2026-09 真机转账采样字段名(含微信原文 transcationid 拼写)
|
||||
const xml = [
|
||||
'<msg><appmsg appid="" sdkver="">',
|
||||
'<title><![CDATA[微信转账]]></title>',
|
||||
'<des><![CDATA[收到转账2900.00元。]]></des>',
|
||||
'<type>2000</type>',
|
||||
'<url><![CDATA[https://support.weixin.qq.com/upgrade]]></url>',
|
||||
'<wcpayinfo>',
|
||||
'<paysubtype>3</paysubtype>',
|
||||
'<feedesc><![CDATA[¥2900.00]]></feedesc>',
|
||||
'<transcationid><![CDATA[53010003370089202609134087894875]]></transcationid>',
|
||||
'<transferid><![CDATA[1000050001202609130232821248942]]></transferid>',
|
||||
'<invalidtime><![CDATA[1789348128]]></invalidtime>',
|
||||
'<begintransfertime><![CDATA[1789261728]]></begintransfertime>',
|
||||
'<effectivedate><![CDATA[1]]></effectivedate>',
|
||||
'<pay_memo><![CDATA[房租]]></pay_memo>',
|
||||
'<receiver_username><![CDATA[wxid_receiver]]></receiver_username>',
|
||||
'<payer_username><![CDATA[]]></payer_username>',
|
||||
'<transfer_status>2</transfer_status>',
|
||||
'</wcpayinfo></appmsg></msg>'
|
||||
].join('')
|
||||
const parsed = parseMessageContent(xml, 49)
|
||||
expect(parsed).toMatchObject({
|
||||
type: 'share',
|
||||
typeVal: '2000',
|
||||
title: '微信转账',
|
||||
transfer: {
|
||||
paySubtype: '3',
|
||||
amountText: '¥2900.00',
|
||||
transcationId: '53010003370089202609134087894875',
|
||||
transferId: '1000050001202609130232821248942',
|
||||
invalidTime: '1789348128',
|
||||
beginTransferTime: '1789261728',
|
||||
effectiveDate: '1',
|
||||
payMemo: '房租',
|
||||
receiverUsername: 'wxid_receiver',
|
||||
transferStatus: '2',
|
||||
transferStatusText: '已收款'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('parses red packet wcpayinfo fields (type 2001 / mmpayhb)', () => {
|
||||
const xml = [
|
||||
'<msg><appmsg appid="" sdkver="">',
|
||||
'<title><![CDATA[中秋快乐]]></title>',
|
||||
'<des><![CDATA[我给你发了一个红包,赶紧去拆!]]></des>',
|
||||
'<type>2001</type>',
|
||||
'<wcpayinfo>',
|
||||
'<templateid><![CDATA[7a2a165d31da7fce6dd77e05c300028a]]></templateid>',
|
||||
'<url><![CDATA[https://wxapp.tenpay.com/mmpayhb/wxhb_personalreceive?msgtype=1&sendid=1000039801202609247176036834007&sign=abc]]></url>',
|
||||
'<iconurl><![CDATA[https://wx.gtimg.com/hongbao/1800/hb.png]]></iconurl>',
|
||||
'<receivertitle><![CDATA[恭喜发财,大吉大利]]></receivertitle>',
|
||||
'<sendertitle><![CDATA[中秋快乐,望重置]]></sendertitle>',
|
||||
'<scenetext><![CDATA[微信红包]]></scenetext>',
|
||||
'<senderdes><![CDATA[查看红包]]></senderdes>',
|
||||
'<receiverdes><![CDATA[领取红包]]></receiverdes>',
|
||||
'<nativeurl><![CDATA[wxpay://c2cbizmessagehandler/hongbao/receivehongbao?sendid=1]]></nativeurl>',
|
||||
'<hb_type>1</hb_type>',
|
||||
'<hb_status>1</hb_status>',
|
||||
'<receive_status>2</receive_status>',
|
||||
'</wcpayinfo></appmsg></msg>'
|
||||
].join('')
|
||||
const parsed = parseMessageContent(xml, 49)
|
||||
expect(parsed).toMatchObject({
|
||||
type: 'redPacket',
|
||||
title: '中秋快乐,望重置',
|
||||
pay: {
|
||||
templateId: '7a2a165d31da7fce6dd77e05c300028a',
|
||||
receiveTitle: '恭喜发财,大吉大利',
|
||||
sendTitle: '中秋快乐,望重置',
|
||||
sceneText: '微信红包',
|
||||
senderDes: '查看红包',
|
||||
receiverDes: '领取红包',
|
||||
sendId: '1000039801202609247176036834007',
|
||||
hbType: '1',
|
||||
hbStatus: '1',
|
||||
receiveStatus: '2',
|
||||
redPacketStatusText: '已领取'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
describePaySubtype,
|
||||
describeRedPacketStatus,
|
||||
describeTransferStatus
|
||||
} from '../../src/shared/payment-status'
|
||||
|
||||
describe('payment status labels', () => {
|
||||
it('maps transfer_status numbers and keywords to UI wording', () => {
|
||||
expect(describeTransferStatus(2)).toBe('已收款')
|
||||
expect(describeTransferStatus('3')).toBe('已退还')
|
||||
expect(describeTransferStatus('paid')).toBe('已收款')
|
||||
expect(describeTransferStatus('收款方过期未收款,已退还')).toBe('过期未收款,已退还')
|
||||
expect(describeTransferStatus(undefined)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('maps red packet hb_status / receive_status', () => {
|
||||
expect(describeRedPacketStatus('0', undefined)).toBe('待领取')
|
||||
expect(describeRedPacketStatus('1', undefined)).toBe('已领取')
|
||||
expect(describeRedPacketStatus(undefined, '2')).toBe('已被领完')
|
||||
expect(describeRedPacketStatus('已被领取', undefined)).toBe('已领取')
|
||||
expect(describeRedPacketStatus(undefined, undefined)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('passes through unknown status values', () => {
|
||||
expect(describeTransferStatus('99-custom')).toBe('99-custom')
|
||||
expect(describeRedPacketStatus('99', '98')).toBe('99')
|
||||
expect(describePaySubtype('3')).toBe('收款')
|
||||
expect(describePaySubtype('9')).toBe('9')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user