import assert from 'node:assert/strict' import test from 'node:test' import { readFileSync } from 'node:fs' import { parse } from '@vue/compiler-sfc' import { compile, computed, createSSRApp, ref } from 'vue' import { renderToString } from 'vue/server-renderer' import ts from 'typescript' import { resolveOpportunityStageLabel, resolveOpportunityTagType } from '../src/utils/crm-opportunity-labels' function source(file: string) { return parse(readFileSync(new URL(`../src/views/m/crm/customer/${file}.vue`, import.meta.url), 'utf8')).descriptor } test('跟进联系人选项和选中回显保留姓名职位及主要标识,值仍是联系人ID', () => { const code = source('FollowPanel').scriptSetup!.content const ast = ts.createSourceFile('follow.ts', code, ts.ScriptTarget.Latest, true) const fields = ast.statements.filter(ts.isVariableStatement).flatMap((n) => n.declarationList.declarations).find((n) => n.name.getText(ast) === 'fields')! const contacts = ref([ { id: 1, contactName: '张甲', position: '采购', isPrimary: 1 }, { id: 2, contactName: '李乙', position: '经理', isPrimary: 0 } ]) const result = new Function('computed', 'contacts', ts.transpile(`return ${fields.initializer!.getText(ast)}`))(computed, contacts) const field = result.value.find((f: any) => f.key === 'contactId') assert.deepEqual(field.options, [ { value: '1', label: '张甲 · 采购 · 主要' }, { value: '2', label: '李乙 · 经理' } ]) const selectorCode = source('CustomerFields').scriptSetup!.content const selectorAst = ts.createSourceFile('fields.ts', selectorCode, ts.ScriptTarget.Latest, true) const functions = selectorAst.statements.filter((n) => ts.isFunctionDeclaration(n) && ['hasValue', 'options', 'selectLabel'].includes(n.name?.text || '')).map((n) => n.getText(selectorAst)).join('\n') const label = new Function('props', 'dict', `${ts.transpile(functions)};return selectLabel`)( { modelValue: { contactId: '1' } }, {} ) assert.equal(label(field), '张甲 · 采购 · 主要') }) test('阶段记录用Web语义Tag,名称快照优先,未知阶段保留编码且空起点显示横线', async () => { const template = source('RelatedPanel').template!.content.split('