style(ui): 统一移动端登录排版设计Token与战报榜单卡片样式
这个提交包含在:
@@ -69,6 +69,56 @@ describe('OmniCard AI 名片大厅 (useHall.uts)', () => {
|
||||
).toBe('/pages/portal/index?id=202');
|
||||
});
|
||||
|
||||
it('现场分段走 floorPage,加入活动码后刷新同场名片', async () => {
|
||||
const { createHallState, applyHallTab, refreshHall, submitHallEventJoin } =
|
||||
loadHall();
|
||||
const state = createHallState();
|
||||
applyHallTab(state, 'event');
|
||||
let usedFloor = false;
|
||||
let joined = '';
|
||||
await refreshHall(state, {
|
||||
fetchHallContactPage: async () => ({
|
||||
list: [],
|
||||
pagination: { page: 1, size: 20, total: 0 },
|
||||
}),
|
||||
fetchEventFloorPage: async () => {
|
||||
usedFloor = true;
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
ownerUserId: 11,
|
||||
peerCardId: 103,
|
||||
source: 'event',
|
||||
peerName: 'Chen Wei',
|
||||
},
|
||||
],
|
||||
pagination: { page: 1, size: 20, total: 1 },
|
||||
};
|
||||
},
|
||||
});
|
||||
expect(usedFloor).toBe(true);
|
||||
expect(state.list[0].peerName).toBe('Chen Wei');
|
||||
|
||||
state.eventCode = 'ces26a';
|
||||
const ok = await submitHallEventJoin(state, {
|
||||
fetchHallContactPage: async () => ({
|
||||
list: [],
|
||||
pagination: { page: 1, size: 20, total: 0 },
|
||||
}),
|
||||
fetchEventFloorPage: async () => ({
|
||||
list: [],
|
||||
pagination: { page: 1, size: 20, total: 0 },
|
||||
}),
|
||||
joinHallEvent: async (code: string) => {
|
||||
joined = code;
|
||||
return { event: { code }, member: { cardId: 101 } };
|
||||
},
|
||||
});
|
||||
expect(ok).toBe(true);
|
||||
expect(joined).toBe('ces26a');
|
||||
expect(state.eventCode).toBe('');
|
||||
});
|
||||
|
||||
it('团队分段走 teamWall 接口', async () => {
|
||||
const { createHallState, applyHallTab, refreshHall } = loadHall();
|
||||
const state = createHallState();
|
||||
@@ -129,6 +179,7 @@ describe('OmniCard AI 名片大厅页契约 (index.uvue)', () => {
|
||||
expect(pageSource.includes('<list-view')).toBe(true);
|
||||
expect(pageSource.includes('exchangeCode')).toBe(true);
|
||||
expect(pageSource.includes('tabTeam') || logicSource.includes('tabTeam')).toBe(true);
|
||||
expect(pageSource.includes('tabEvent') || logicSource.includes('tabEvent')).toBe(true);
|
||||
expect(pageSource.includes('var(--window-bottom')).toBe(true);
|
||||
expect(logicSource.includes('/admin/card/contact/hallPage') || logicSource.includes('fetchHallContactPage')).toBe(true);
|
||||
expect(pageSource.includes('#0B5CFF')).toBe(true);
|
||||
|
||||
@@ -70,6 +70,7 @@ type LoadLeadsResult = {
|
||||
|
||||
type UseLeadsModule = {
|
||||
parseLeadStatus: (raw: string | null | undefined) => LeadStatus | null;
|
||||
formatHotUnread: (unread: number) => string;
|
||||
loadLeads: (
|
||||
query: LoadLeadsQuery,
|
||||
api?: LoadLeadsApi
|
||||
@@ -221,6 +222,12 @@ describe('OmniCard AI 名片主移动潜客列表 (useLeads.uts)', () => {
|
||||
expect(sent.keyWord).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('formatHotUnread 有未读才显示红点文案', () => {
|
||||
const { formatHotUnread } = loadUseLeads();
|
||||
expect(formatHotUnread(0)).toBe('');
|
||||
expect(formatHotUnread(2)).toContain('2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('OmniCard AI 名片主潜客列表页契约 (leads.uvue)', () => {
|
||||
@@ -253,6 +260,7 @@ describe('OmniCard AI 名片主潜客列表页契约 (leads.uvue)', () => {
|
||||
expect(pageSource.includes('#E3E7ED')).toBe(true);
|
||||
expect(pageSource.includes('primary-cta-btn')).toBe(true);
|
||||
expect(pageSource.includes('status-chip')).toBe(true);
|
||||
expect(combined.includes('hotUnread') || combined.includes('hotInbox')).toBe(true);
|
||||
});
|
||||
|
||||
it('无 emoji、无 any,模板无硬编码中文主文案,长列表不用 view v-for', () => {
|
||||
|
||||
@@ -334,6 +334,33 @@ describe('OmniCard AI 展会团队战报 (useOverview.uts)', () => {
|
||||
expect(result.empty).toBe(false);
|
||||
expect(result.errorMessage).toBe('lead page unavailable');
|
||||
});
|
||||
|
||||
it('2.4 注入 liveRank 时写入现场排行', async () => {
|
||||
const { loadOverview } = loadUseOverview();
|
||||
const result = await loadOverview(
|
||||
{ page: 1, size: 20 },
|
||||
{
|
||||
fetchOwnerLeadPage: async () => buildPage([]),
|
||||
fetchOwnerRadarPage: async () => buildPage([]),
|
||||
fetchCurrentEvent: async () => ({ code: 'CES26A' }),
|
||||
fetchTeamLiveRank: async (eventId?: string) => {
|
||||
expect(eventId).toBe('CES26A');
|
||||
return [
|
||||
{
|
||||
memberId: 11,
|
||||
memberName: 'Alex Rivera',
|
||||
leads: 3,
|
||||
touches: 12,
|
||||
score: 42,
|
||||
rank: 1,
|
||||
},
|
||||
];
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(result.ranks).toHaveLength(1);
|
||||
expect(result.ranks[0].memberName).toBe('Alex Rivera');
|
||||
});
|
||||
});
|
||||
|
||||
describe('3. refreshOverview 触觉震动与状态刷新', () => {
|
||||
@@ -374,6 +401,9 @@ describe('OmniCard AI 展会团队战报页契约 (overview.uvue)', () => {
|
||||
expect(combined.includes('loadOverview')).toBe(true);
|
||||
expect(combined.includes('fetchOwnerLeadPage')).toBe(true);
|
||||
expect(combined.includes('fetchOwnerRadarPage')).toBe(true);
|
||||
expect(combined.includes('fetchTeamLiveRank') || combined.includes('live-rank')).toBe(
|
||||
true
|
||||
);
|
||||
expect(logicSource.includes('Promise.all')).toBe(true);
|
||||
expect(pageSource.includes('getOmniText')).toBe(true);
|
||||
expect(combined.includes('crm.leads')).toBe(true);
|
||||
|
||||
在新工单中引用
屏蔽一个用户