| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- import { Injectable, inject } from '@angular/core';
- import { ApiClientService } from './api-client.service';
- import type { Group } from '../../models';
- import type { LifecyclePhase, HealthGrade } from '../../models';
- export interface GroupChatDto {
- id: string;
- roomId: string;
- roomName: string;
- ownerId: string;
- ownerName: string;
- memberCount: number;
- avatarUrl: string;
- status: string;
- guid: string;
- storeId: string;
- storeName: string;
- communityId: string;
- communityName: string;
- activityLevel: string;
- healthScore: number;
- healthStatus: string;
- healthGrade: HealthGrade;
- opsActivityScore: number;
- customerActivityScore: number;
- lifecyclePhase: LifecyclePhase;
- hasDocument: boolean;
- documentPinned: boolean;
- documentInNotice: boolean;
- messageCountToday: number;
- messageCountTotal: number;
- memberChange24h: number;
- updatedAt: string;
- }
- export interface StoreDto {
- id: string;
- code: string;
- name: string;
- region: string;
- }
- export interface CommunityDto {
- id: string;
- name: string;
- address: string;
- deliveryDate: string;
- lifecyclePhase: LifecyclePhase;
- totalHouseholds: number;
- avgPrice: number;
- storeId: string;
- storeName: string;
- groupCount: number;
- status: string;
- }
- export interface LifecycleSummaryDto {
- phase: LifecyclePhase;
- label: string;
- count: number;
- communities: CommunityDto[];
- }
- export interface GroupListFilters {
- storeId?: string;
- activityLevel?: string;
- healthStatus?: string;
- healthGrade?: string;
- lifecyclePhase?: string;
- hasDocument?: string;
- q?: string;
- }
- export interface SyncGroupsResult {
- sync: { created: number; updated: number; errors: string[] };
- catalog?: {
- rooms: { created: number; updated: number; errors: string[] };
- sessions: { created: number; updated: number; skipped: number };
- fromMessages: number;
- };
- database: {
- connected: boolean;
- counts?: { groupChat: number; groupMember: number; message: number };
- };
- }
- export interface MessageSyncResult {
- guid: string;
- startSeq: number;
- endSeq: number;
- pages: number;
- created: number;
- skipped: number;
- hasMore: boolean;
- groupsBackfilled?: number;
- errors: string[];
- }
- export interface MessageDto {
- id: string;
- msgUniqueIdentifier: string;
- roomId: string | null;
- senderId: string;
- senderName: string;
- content: string;
- msgType: number;
- timestamp: string;
- guid: string;
- seq?: number;
- }
- export interface SyncMessagesResult {
- sync: MessageSyncResult;
- database: SyncGroupsResult['database'];
- }
- @Injectable({ providedIn: 'root' })
- export class QiweApiService {
- private readonly api = inject(ApiClientService);
- listGroups(filters: GroupListFilters = {}) {
- const params = new URLSearchParams();
- if (filters.storeId) params.set('storeId', filters.storeId);
- if (filters.activityLevel) params.set('activityLevel', filters.activityLevel);
- if (filters.healthStatus) params.set('healthStatus', filters.healthStatus);
- if (filters.healthGrade) params.set('healthGrade', filters.healthGrade);
- if (filters.lifecyclePhase) params.set('lifecyclePhase', filters.lifecyclePhase);
- if (filters.hasDocument) params.set('hasDocument', filters.hasDocument);
- if (filters.q) params.set('q', filters.q);
- const query = params.toString();
- const path = query ? `/qiwe/groups?${query}` : '/qiwe/groups';
- return this.api.getResult<{ groups: GroupChatDto[]; total: number; stores: StoreDto[] }>(path);
- }
- listCommunities(lifecyclePhase?: string) {
- const params = new URLSearchParams();
- if (lifecyclePhase) params.set('lifecyclePhase', lifecyclePhase);
- const query = params.toString();
- const path = query ? `/qiwe/communities?${query}` : '/qiwe/communities';
- return this.api.getResult<{
- communities: CommunityDto[];
- grouped: LifecycleSummaryDto[];
- total: number;
- }>(path);
- }
- listStores() {
- return this.api.getResult<{ stores: StoreDto[] }>('/qiwe/stores');
- }
- syncOrg() {
- return this.api.postResult<{ departments: number; members: number; source: string; errors: string[] }>(
- '/qiwe/org/sync',
- {},
- );
- }
- getOrgTree() {
- return this.api.getResult<{ tree: unknown[] }>('/qiwe/org/tree');
- }
- getGroup(roomId: string) {
- return this.api.getResult<{ group: GroupChatDto }>(`/qiwe/groups/${encodeURIComponent(roomId)}`);
- }
- syncGroups() {
- return this.api.postResult<SyncGroupsResult>('/qiwe/sync-groups', {});
- }
- syncMessages(options: { msgSeq?: number; limit?: number; maxPages?: number; resetCursor?: boolean } = {}) {
- return this.api.postResult<SyncMessagesResult>('/qiwe/sync-messages', options);
- }
- listMessages(roomId: string, limit = 50, skip = 0, chatOnly = true) {
- const params = new URLSearchParams({
- roomId,
- limit: String(limit),
- skip: String(skip),
- chatOnly: chatOnly ? 'true' : 'false',
- });
- return this.api.getResult<{ messages: MessageDto[]; total: number; chatTotal: number }>(
- `/qiwe/messages?${params.toString()}`,
- );
- }
- testWebhook(payload: unknown) {
- return this.api.postResult<null>('/qiwe/webhook', payload);
- }
- mapToGroup(dto: GroupChatDto): Group {
- return {
- id: dto.roomId,
- name: dto.roomName,
- memberCount: dto.memberCount,
- communityId: dto.communityId,
- communityName: dto.communityName || '—',
- storeId: dto.storeId,
- storeName: dto.storeName || '—',
- ownerId: dto.ownerId,
- ownerName: dto.ownerName || '—',
- ownerRole: '—',
- createdAt: new Date(dto.updatedAt),
- healthScore: dto.healthScore,
- healthStatus: dto.healthStatus as Group['healthStatus'],
- healthGrade: dto.healthGrade || 'C',
- opsActivityScore: dto.opsActivityScore ?? 0,
- customerActivityScore: dto.customerActivityScore ?? 0,
- lifecyclePhase: dto.lifecyclePhase || 'pre_handover',
- hasDocument: dto.hasDocument,
- documentPinned: dto.documentPinned,
- documentInNotice: dto.documentInNotice,
- activityLevel: dto.activityLevel as Group['activityLevel'],
- messageCountToday: dto.messageCountToday,
- messageCountTotal: dto.messageCountTotal ?? 0,
- memberChange24h: dto.memberChange24h,
- tags: dto.status === 'active' ? ['企微同步'] : ['已解散'],
- };
- }
- }
|