feat(card): 员工端「我的人脉」页 + 与潜在客户导航互链

- 新增 contacts.vue: 搜索/来源筛选/列表卡(来源徽标)/编辑/转潜在客户/删除
- 新增 contact-edit.vue: 新增编辑复用, 姓名红星必填, 其余(选填)
- leads.vue 顶部互链「我的人脉 ›」(导航合并第一步)
- pages.json 注册两页; PAGE_KEY_MAP 补 PAGE_CARD_CONTACTS
- card-platform.test.js 追加 4 测试(25/25)
This commit is contained in:
2026-10-12 17:35:16 +08:00
parent 0859765efb
commit b92f474ac8
6 changed files with 744 additions and 0 deletions

View File

@@ -343,3 +343,53 @@ test('选择链接: card 页面不在 TabBar(NO_TAB_PAGES 语义)不影响导航
assert.ok(tabBlock, 'TAB_BAR_KEYS 应存在');
assert.ok(!/card/.test(tabBlock[0]), 'TAB_BAR_KEYS 不应含 card 路径(card 非 tabBar 页)');
});
// ============================================================
// 2.0.0 人脉库: contacts / contact-edit 注册 + 互链 + 鸿蒙安全
// ============================================================
test('人脉库: PAGE_KEY_MAP 含 PAGE_CARD_CONTACTS', () => {
const utilSrc = fs.readFileSync(path.resolve(__dirname, '../common/js/util.js'), 'utf8');
const m = utilSrc.match(/PAGE_CARD_CONTACTS:\s*'([^']+)'/);
assert.ok(m, 'PAGE_KEY_MAP 应有 PAGE_CARD_CONTACTS');
assert.equal(m[1], '/pages_tool/card/contacts');
});
test('人脉库: contacts/contact-edit 已注册进 pages.json 且不在 TabBar', () => {
const pagesSrc = fs.readFileSync(path.resolve(__dirname, '../pages.json'), 'utf8');
const stripped = pagesSrc.replace(/^\s*\/\/.*$/gm, '').replace(/,(\s*[}\]])/g, '$1');
const pages = JSON.parse(stripped);
const sub = (pages.subPackages || []).find(sp => sp.root === 'pages_tool');
assert.ok(sub, 'pages_tool 分包应存在');
const paths = (sub.pages || []).map(p => p.path);
assert.ok(paths.includes('card/contacts'), `card/contacts 未注册: ${paths.join(',')}`);
assert.ok(paths.includes('card/contact-edit'), `card/contact-edit 未注册: ${paths.join(',')}`);
// TabBar 根页不在 pages_tool 分包, 天然不在 TabBar; 防回归: tabBar 列表不得含 card
const tabPages = (pages.tabBar && pages.tabBar.list ? pages.tabBar.list : []).map(p => p.pagePath);
assert.ok(!tabPages.some(p => /card/.test(p)), 'TabBar 不应含 card 页面');
});
test('人脉库: contacts/leads 顶部互链都走 $util.redirectTo(鸿蒙静默失败回归)', () => {
const contactsSrc = read('contacts.vue');
const leadsSrc = read('leads.vue');
// contacts → leads
assert.ok(/goLeads\(\)\s*\{[\s\S]*?\$util\.redirectTo\('\/pages_tool\/card\/leads'\)/.test(contactsSrc),
'contacts.vue 顶部「潜在客户」链接必须走 $util.redirectTo');
// leads → contacts
assert.ok(/goContacts\(\)\s*\{[\s\S]*?\$util\.redirectTo\('\/pages_tool\/card\/contacts'\)/.test(leadsSrc),
'leads.vue 顶部「我的人脉」链接必须走 $util.redirectTo');
// 两文件不得出现裸 uni.switchTab 调用
for (const [name, src] of [['contacts.vue', contactsSrc], ['leads.vue', leadsSrc]]) {
assert.ok(!/uni\.switchTab\s*\(/.test(src), `${name} 不得直接调 uni.switchTab`);
}
});
test('人脉库: contact-edit 保存成功回 contacts 走 $util.redirectTo(鸿蒙安全)', () => {
const src = read('contact-edit.vue');
assert.ok(/backToList\(\)\s*\{[\s\S]*?\$util\.redirectTo\('\/pages_tool\/card\/contacts'\)/.test(src),
'保存成功回列表必须走 $util.redirectTo');
assert.ok(!/uni\.switchTab\s*\(/.test(src), 'contact-edit.vue 不得直接调 uni.switchTab');
// 姓名必填: 模板有 req-star + 保存前有空名校验
assert.ok(/req-star/.test(src), '姓名必填应有 req-star 红星');
assert.ok(/请填写姓名/.test(src), '保存前应校验姓名非空');
});