const { createRequire } = require('node:module'); const path = require('node:path'); const req = createRequire(path.resolve(__dirname, '../../server/package.json')); function syntheticReceiptText({ status = 'success', final = true, direction = 'debit', amount = '10.00', currency = '人民币', payerAccount = '000011112222', payeeAccount = '000033334444', reference = 'SYNTHETIC-REFERENCE', bookedOn = '2026-10-01' } = {}) { const words = { success: '交易成功', failed: '交易失败', pending: '处理中', booked: '' }; return [final ? '中国建设银行单位客户专用回单' : '中国建设银行网上银行电子回执', '合成公司测试回单 SYNTHETIC', `记账日期 ${bookedOn}`, direction === 'credit' ? '贷' : '借', `金额 ${amount}`, `币别 ${currency}`, `付款人账号 ${payerAccount}`, `收款人账号 ${payeeAccount}`, `凭证号码 ${reference}`, ...(words[status] ? [`单据状态 ${words[status]}`] : []), ...(!final ? ['本回执不作为收、付款方交易的最终依据,正式回单请在交易成功后另打印。'] : [])].join('\n'); } async function syntheticBankReceiptPdf({ pages = 1, tag = 'SYNTHETIC', ...options } = {}) { const { PDFDocument, PDFHexString, beginText, endText, setFontAndSize, moveText, showText } = req('pdf-lib'); const doc = await PDFDocument.create(); doc.setTitle(tag); const text = syntheticReceiptText(options); const hex = (s) => Buffer.from(s, 'utf16le').swap16().toString('hex').toUpperCase(); const codes = [...new Set([...text.replace(/\n/g, '')])].map((c) => `<${hex(c)}> <${hex(c)}>`); const cmap = `/CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Synthetic-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange ${codes.length} beginbfchar\n${codes.join('\n')}\nendbfchar endcmap CMapName currentdict /CMap defineresource pop end end`; const toUnicode = doc.context.register(doc.context.flateStream(cmap)); const cid = doc.context.register(doc.context.obj({ Type: 'Font', Subtype: 'CIDFontType0', BaseFont: 'STSong-Light', CIDSystemInfo: { Registry: PDFHexString.fromText('Adobe'), Ordering: PDFHexString.fromText('GB1'), Supplement: 4 }, DW: 1000 })); const font = doc.context.register(doc.context.obj({ Type: 'Font', Subtype: 'Type0', BaseFont: 'STSong-Light', Encoding: 'Identity-H', DescendantFonts: [cid], ToUnicode: toUnicode })); for (let n = 0; n < pages; n++) { const page = doc.addPage([595, 842]); const name = page.node.newFontDictionary('SYN', font); text.split('\n').forEach((line, index) => page.pushOperators(beginText(), setFontAndSize(name, 10), moveText(30, 790 - index * 22), showText(PDFHexString.of(hex(line))), endText())); } return Buffer.from(await doc.save()); } function syntheticDocumentEvidence(options) { return req('./src/services/paymentReceiptDocument').classifyReceiptText(syntheticReceiptText(options)); } module.exports = { syntheticReceiptText, syntheticBankReceiptPdf, syntheticDocumentEvidence };