feat(hall): 支持展会活动码现场互换与榜单API对接
这个提交包含在:
@@ -7,6 +7,8 @@ import {
|
|||||||
AiChatReply,
|
AiChatReply,
|
||||||
AiChatRequest,
|
AiChatRequest,
|
||||||
CardContact,
|
CardContact,
|
||||||
|
CardEvent,
|
||||||
|
CardEventJoinResult,
|
||||||
CardProfile,
|
CardProfile,
|
||||||
CardPortalDetail,
|
CardPortalDetail,
|
||||||
LeadEntity,
|
LeadEntity,
|
||||||
@@ -17,7 +19,9 @@ import {
|
|||||||
OwnerPageData,
|
OwnerPageData,
|
||||||
OwnerPageQuery,
|
OwnerPageQuery,
|
||||||
QuotaCheckResult,
|
QuotaCheckResult,
|
||||||
|
RadarHotInbox,
|
||||||
RadarTrack,
|
RadarTrack,
|
||||||
|
TeamRankItem,
|
||||||
SubmitLeadParams,
|
SubmitLeadParams,
|
||||||
RecordRadarTrackParams,
|
RecordRadarTrackParams,
|
||||||
} from './types.uts';
|
} from './types.uts';
|
||||||
@@ -185,6 +189,41 @@ export function fetchTeamWallPage(
|
|||||||
return httpPost<OwnerPageData<CardContact>>('/admin/card/contact/teamWall', query);
|
return httpPost<OwnerPageData<CardContact>>('/admin/card/contact/teamWall', query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fetchEventFloorPage(
|
||||||
|
query: OwnerPageQuery
|
||||||
|
): Promise<OwnerPageData<CardContact>> {
|
||||||
|
return httpPost<OwnerPageData<CardContact>>('/admin/card/event/floorPage', query);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function joinHallEvent(
|
||||||
|
code: string,
|
||||||
|
cardId?: string | number
|
||||||
|
): Promise<CardEventJoinResult> {
|
||||||
|
const payload: Record<string, string | number> = { code };
|
||||||
|
if (cardId != null) {
|
||||||
|
payload.cardId = cardId;
|
||||||
|
}
|
||||||
|
return httpPost<CardEventJoinResult>('/admin/card/event/join', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchCurrentEvent(): Promise<CardEvent | null> {
|
||||||
|
return httpPost<CardEvent | null>('/admin/card/event/current', {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchRadarHotInbox(): Promise<RadarHotInbox> {
|
||||||
|
return httpPost<RadarHotInbox>('/admin/crm/radar/hotInbox', {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchTeamLiveRank(
|
||||||
|
eventId?: string
|
||||||
|
): Promise<TeamRankItem[]> {
|
||||||
|
const payload: Record<string, string> = {};
|
||||||
|
if (eventId != null && eventId !== '') {
|
||||||
|
payload.eventId = eventId;
|
||||||
|
}
|
||||||
|
return httpPost<TeamRankItem[]>('/admin/team/members/live-rank', payload);
|
||||||
|
}
|
||||||
|
|
||||||
export function fetchCardQuota(
|
export function fetchCardQuota(
|
||||||
tenantId?: string | number
|
tenantId?: string | number
|
||||||
): Promise<QuotaCheckResult> {
|
): Promise<QuotaCheckResult> {
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ import {
|
|||||||
import {
|
import {
|
||||||
collectHallContact,
|
collectHallContact,
|
||||||
confirmHallExchange,
|
confirmHallExchange,
|
||||||
|
fetchEventFloorPage,
|
||||||
fetchHallContactPage,
|
fetchHallContactPage,
|
||||||
fetchTeamWallPage,
|
fetchTeamWallPage,
|
||||||
|
joinHallEvent,
|
||||||
} from '../../../common/api.uts';
|
} from '../../../common/api.uts';
|
||||||
import { getCurrentLocale, getOmniText } from '../../../common/locale.uts';
|
import { getCurrentLocale, getOmniText } from '../../../common/locale.uts';
|
||||||
|
|
||||||
@@ -28,7 +30,11 @@ export type HallCopyKey =
|
|||||||
| 'scan'
|
| 'scan'
|
||||||
| 'tabContacts'
|
| 'tabContacts'
|
||||||
| 'tabTeam'
|
| 'tabTeam'
|
||||||
| 'teamEmpty';
|
| 'tabEvent'
|
||||||
|
| 'teamEmpty'
|
||||||
|
| 'eventEmpty'
|
||||||
|
| 'eventPlaceholder'
|
||||||
|
| 'eventJoin';
|
||||||
|
|
||||||
export type HallContactItem = {
|
export type HallContactItem = {
|
||||||
id?: string | number;
|
id?: string | number;
|
||||||
@@ -40,7 +46,7 @@ export type HallContactItem = {
|
|||||||
source?: string;
|
source?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HallTab = 'contacts' | 'team';
|
export type HallTab = 'contacts' | 'team' | 'event';
|
||||||
|
|
||||||
export type HallState = {
|
export type HallState = {
|
||||||
tab: HallTab;
|
tab: HallTab;
|
||||||
@@ -50,6 +56,7 @@ export type HallState = {
|
|||||||
total: number;
|
total: number;
|
||||||
keyWord: string;
|
keyWord: string;
|
||||||
exchangeCode: string;
|
exchangeCode: string;
|
||||||
|
eventCode: string;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
empty: boolean;
|
empty: boolean;
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
@@ -66,6 +73,12 @@ export type LoadHallApi = {
|
|||||||
exchangeCode: string
|
exchangeCode: string
|
||||||
) => Promise<{ status: string; isDualSynced: boolean }>;
|
) => Promise<{ status: string; isDualSynced: boolean }>;
|
||||||
collectHallContact?: (peerCardId: string | number) => Promise<CardContact>;
|
collectHallContact?: (peerCardId: string | number) => Promise<CardContact>;
|
||||||
|
fetchEventFloorPage?: (
|
||||||
|
query: OwnerPageQuery
|
||||||
|
) => Promise<OwnerPageData<CardContact>>;
|
||||||
|
joinHallEvent?: (
|
||||||
|
code: string
|
||||||
|
) => Promise<{ event: { code: string }; member: { cardId: number } }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
function isZhLocale(): boolean {
|
function isZhLocale(): boolean {
|
||||||
@@ -115,6 +128,18 @@ export function resolveHallText(key: HallCopyKey): string {
|
|||||||
if (key === 'teamEmpty') {
|
if (key === 'teamEmpty') {
|
||||||
return zh ? '还没有同事发布名片' : 'No published teammate cards yet';
|
return zh ? '还没有同事发布名片' : 'No published teammate cards yet';
|
||||||
}
|
}
|
||||||
|
if (key === 'tabEvent') {
|
||||||
|
return zh ? '现场' : 'Floor';
|
||||||
|
}
|
||||||
|
if (key === 'eventEmpty') {
|
||||||
|
return zh ? '输入活动码加入现场' : 'Enter an event code to join the floor';
|
||||||
|
}
|
||||||
|
if (key === 'eventPlaceholder') {
|
||||||
|
return zh ? '输入 6 位活动码' : '6-character event code';
|
||||||
|
}
|
||||||
|
if (key === 'eventJoin') {
|
||||||
|
return zh ? '加入现场' : 'Join floor';
|
||||||
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +164,7 @@ export function createHallState(): HallState {
|
|||||||
total: 0,
|
total: 0,
|
||||||
keyWord: '',
|
keyWord: '',
|
||||||
exchangeCode: '',
|
exchangeCode: '',
|
||||||
|
eventCode: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
empty: false,
|
empty: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
@@ -175,13 +201,17 @@ export async function refreshHall(
|
|||||||
state.loading = true;
|
state.loading = true;
|
||||||
state.errorMessage = '';
|
state.errorMessage = '';
|
||||||
const fetchPage =
|
const fetchPage =
|
||||||
state.tab === 'team'
|
state.tab === 'event'
|
||||||
? api != null && api.fetchTeamWallPage != null
|
? api != null && api.fetchEventFloorPage != null
|
||||||
? api.fetchTeamWallPage
|
? api.fetchEventFloorPage
|
||||||
: fetchTeamWallPage
|
: fetchEventFloorPage
|
||||||
: api != null
|
: state.tab === 'team'
|
||||||
? api.fetchHallContactPage
|
? api != null && api.fetchTeamWallPage != null
|
||||||
: fetchHallContactPage;
|
? api.fetchTeamWallPage
|
||||||
|
: fetchTeamWallPage
|
||||||
|
: api != null
|
||||||
|
? api.fetchHallContactPage
|
||||||
|
: fetchHallContactPage;
|
||||||
try {
|
try {
|
||||||
const query: OwnerPageQuery = {
|
const query: OwnerPageQuery = {
|
||||||
page: state.page,
|
page: state.page,
|
||||||
@@ -246,11 +276,40 @@ export async function collectPeerCard(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function applyHallTab(state: HallState, tab: HallTab): void {
|
export function applyHallTab(state: HallState, tab: HallTab): void {
|
||||||
state.tab = tab === 'team' ? 'team' : 'contacts';
|
if (tab === 'team') {
|
||||||
|
state.tab = 'team';
|
||||||
|
} else if (tab === 'event') {
|
||||||
|
state.tab = 'event';
|
||||||
|
} else {
|
||||||
|
state.tab = 'contacts';
|
||||||
|
}
|
||||||
state.page = 1;
|
state.page = 1;
|
||||||
state.errorMessage = '';
|
state.errorMessage = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function submitHallEventJoin(
|
||||||
|
state: HallState,
|
||||||
|
api?: LoadHallApi
|
||||||
|
): Promise<boolean> {
|
||||||
|
const code = state.eventCode.trim();
|
||||||
|
if (!/^[A-Za-z0-9]{6}$/.test(code)) {
|
||||||
|
state.errorMessage = resolveHallText('eventPlaceholder');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const join =
|
||||||
|
api != null && api.joinHallEvent != null ? api.joinHallEvent : joinHallEvent;
|
||||||
|
try {
|
||||||
|
await join(code);
|
||||||
|
state.eventCode = '';
|
||||||
|
state.tab = 'event';
|
||||||
|
await refreshHall(state, api);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
state.errorMessage = readErrorMessage(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const PENDING_COLLECT_KEY = 'omni_pending_collect_card';
|
export const PENDING_COLLECT_KEY = 'omni_pending_collect_card';
|
||||||
|
|
||||||
export function setPendingCollectCard(cardId: string | number): void {
|
export function setPendingCollectCard(cardId: string | number): void {
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户