gaoluyang
昨天 b64a0deae5b5d33f9e20671a68936b27f0b9b00b
src/views/im/utils/constants.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,296 @@
/** IM å†…容类型枚举(对齐后端 ImContentTypeEnum) */
export const ImContentType = {
  // ========== ç”¨æˆ·èŠå¤©æ¶ˆæ¯ï¼ˆ101-105 ç›´æŽ¥å¤ç”¨ OpenIM æ®µä½ç¼–号) ==========
  TEXT: 101, // æ–‡æœ¬ï¼ˆå¯¹åº” OpenIM Text=101)
  IMAGE: 102, // å›¾ç‰‡ï¼ˆå¯¹åº” OpenIM Picture=102)
  VOICE: 103, // è¯­éŸ³ï¼ˆå¯¹åº” OpenIM Sound=103)
  VIDEO: 104, // è§†é¢‘(对应 OpenIM Video=104)
  FILE: 105, // æ–‡ä»¶ï¼ˆå¯¹åº” OpenIM File=105)
  MERGE: 107, // åˆå¹¶è½¬å‘(对应 OpenIM Merger=107;payload å†…嵌完整快照)
  CARD: 108, // åç‰‡ï¼ˆå¯¹åº” OpenIM Card=108)
  FACE: 115, // è¡¨æƒ…贴图(对应 OpenIM Face=115;Unicode emoji ä»èµ° TEXT)
  // ========== é¢‘道消息扩展段(125+;OpenIM 122 ä¹‹åŽæœªå ç”¨ï¼Œä½œä¸ºé¢‘道 / å…¬ä¼—号类消息扩展) ==========
  MATERIAL: 125, // é¢‘道素材(图文卡片:title + coverUrl + summary + url;详情拉 get-content)
  // ========== ä¿¡å·ç±»ï¼ˆ2101 / 2200 ç›´æŽ¥å¤ç”¨ OpenIM æ®µä½ç¼–号;2201 è‡ªæœ‰æ‰©å±•) ==========
  RECALL: 2101, // æ’¤å›žï¼ˆå¯¹åº” OpenIM RevokeNotification=2101)
  RECEIPT: 2200, // å›žæ‰§ï¼ˆå¯¹åº” OpenIM HasReadReceipt=2200)
  READ: 2201, // å·²è¯»ï¼ˆå¤šç«¯åŒæ­¥ï¼ŒOpenIM æ— å¯¹åº”;自有扩展)
  // ========== å®žæ—¶é€šè¯ä¿¡ä»¤ï¼ˆ1601-1605 æ®µä½ä¸Ž OpenIM å¯¹é½ï¼›1610+ è‡ªæœ‰æ‰©å±•) ==========
  RTC_CALL: 1601, // é€šè¯ä¿¡ä»¤ç»Ÿä¸€å…¥å£ï¼ˆå¯¹åº” OpenIM SignalingNotification=1601)
  RTC_PARTICIPANT_CONNECTED: 1602, // é€šè¯å‚与者加入(对应 OpenIM RoomParticipantsConnectedNotification=1602)
  RTC_PARTICIPANT_DISCONNECTED: 1603, // é€šè¯å‚与者离开(对应 OpenIM RoomParticipantsDisconnectedNotification=1603)
  // 1604-1609 OpenIM å·²ç”¨ / ç•™ä½œæ‰©å±•,本系统暂不使用
  RTC_CALL_START: 1610, // é€šè¯å¼€å§‹ï¼ˆè‡ªæœ‰æ‰©å±•,OpenIM æ— ï¼›ä»…群聊;与 END ä¸¤æ®µå¼é…å¯¹ï¼‰
  RTC_CALL_END: 1611, // é€šè¯ç»“束(自有扩展,OpenIM æ— ï¼›ç§èŠ / ç¾¤èŠï¼‰
  // ========== å¥½å‹é€šçŸ¥ï¼ˆ1201-1210 ç›´æŽ¥å¤ç”¨ OpenIM æ®µä½ç¼–号) ==========
  FRIEND_REQUEST_APPROVED: 1201, // å¥½å‹ç”³è¯·è¢«åŒæ„
  FRIEND_REQUEST_REJECTED: 1202, // å¥½å‹ç”³è¯·è¢«æ‹’绝
  FRIEND_REQUEST_RECEIVED: 1203, // æ”¶åˆ°æ–°çš„好友申请
  FRIEND_ADD: 1204, // æ–°å¢žå¥½å‹ï¼ˆåŒæ–¹å»ºç«‹å…³ç³»ï¼‰
  FRIEND_DELETE: 1205, // å¥½å‹è¢«åˆ é™¤
  // 1206 å¯¹åº” OpenIM FriendRemarkSetNotification;本系统并入 FRIEND_UPDATE(1210) ç»Ÿä¸€æŽ¨é€ï¼Œå•一字段变更不再独立通道
  FRIEND_BLOCK: 1207, // åŠ å…¥é»‘åå•
  FRIEND_UNBLOCK: 1208, // ç§»å‡ºé»‘名单
  FRIEND_INFO_UPDATED: 1209, // å¥½å‹èµ„料变更(昵称 / å¤´åƒï¼‰
  FRIEND_UPDATE: 1210, // å¥½å‹ä¿¡æ¯æ‰¹é‡æ›´æ–°ï¼ˆsilent / pinned)
  // ========== ç¾¤äº‹ä»¶ï¼ˆ1501-1520 ç›´æŽ¥å¤ç”¨ OpenIM æ®µä½ç¼–号;1530+ è‡ªæœ‰æ‰©å±•段) ==========
  GROUP_CREATE: 1501, // ç¾¤åˆ›å»º
  GROUP_INFO_UPDATE: 1502, // ç¾¤ä¿¡æ¯å˜æ›´ï¼ˆNAME / NOTICE ä¹‹å¤–字段兜底)
  GROUP_REQUEST_RECEIVED: 1503, // æ”¶åˆ°æ–°çš„入群申请(私聊定向推送给群主 + å…¨éƒ¨ç®¡ç†å‘˜ï¼‰
  GROUP_MEMBER_QUIT: 1504, // æˆå‘˜é€€ç¾¤
  GROUP_REQUEST_APPROVED: 1505, // å…¥ç¾¤ç”³è¯·è¢«åŒæ„ï¼ˆç§èŠæŽ¨ç»™ç”³è¯·äºº + ç¾¤ä¸» + å…¨éƒ¨ç®¡ç†å‘˜ï¼‰
  GROUP_REQUEST_REJECTED: 1506, // å…¥ç¾¤ç”³è¯·è¢«æ‹’绝(同上)
  GROUP_OWNER_TRANSFER: 1507, // ç¾¤ä¸»è½¬è®©
  GROUP_MEMBER_KICK: 1508, // æˆå‘˜è¢«ç§»å‡º
  GROUP_MEMBER_INVITE: 1509, // æˆå‘˜åŠ å…¥
  GROUP_MEMBER_ENTER: 1510, // è‡ªç”±è¿›ç¾¤ï¼ˆFREE æ¨¡å¼æˆ–申请通过后;全员广播)
  GROUP_DISSOLVE: 1511, // ç¾¤è§£æ•£
  GROUP_MEMBER_MUTED: 1512, // å•成员禁言
  GROUP_MEMBER_CANCEL_MUTED: 1513, // å•成员取消禁言
  GROUP_MUTED: 1514, // å…¨ç¾¤ç¦è¨€
  GROUP_CANCEL_MUTED: 1515, // å…¨ç¾¤å–消禁言
  GROUP_MEMBER_NICKNAME_UPDATE: 1516, // æˆå‘˜æ˜µç§°å˜æ›´ï¼ˆçª„化到 displayUserName)
  GROUP_ADMIN_ADD: 1517, // æ·»åŠ ç®¡ç†å‘˜
  GROUP_ADMIN_REMOVE: 1518, // æ’¤é”€ç®¡ç†å‘˜
  GROUP_NOTICE_UPDATE: 1519, // ç¾¤å…¬å‘Šå˜æ›´
  GROUP_NAME_UPDATE: 1520, // ç¾¤åå˜æ›´
  // ========== è‡ªæœ‰æ‰©å±•段(1530+,OpenIM 1500-1520 æ®µä½æ— å¯¹åº”物) ==========
  GROUP_MEMBER_SETTING_UPDATE: 1530, // ç¾¤æˆå‘˜ä¸ªäººè®¾ç½®å˜æ›´ï¼šsilent / groupRemark ä¸ªäººå¤šç«¯åŒæ­¥
  GROUP_MESSAGE_PIN: 1531, // ç¾¤æ¶ˆæ¯ç½®é¡¶ï¼ˆè‡ªæœ‰æ‰©å±•,OpenIM æ— ï¼‰
  GROUP_MESSAGE_UNPIN: 1532, // ç¾¤æ¶ˆæ¯å–消置顶(自有扩展,OpenIM æ— ï¼‰
  GROUP_BANNED: 1533 // ç¾¤å°ç¦å˜æ›´ï¼ˆè‡ªæœ‰æ‰©å±•,OpenIM æ— ï¼‰
} as const
/** åˆ¤æ–­æ˜¯å¦ã€Œç¾¤å¹¿æ’­äº‹ä»¶ã€ï¼š[GROUP_CREATE, GROUP_BANNED] æ®µä½éƒ½ç®—,仅 GROUP_MEMBER_SETTING_UPDATE æ˜¯ä¸ªäººä¿¡å·æŽ’除 */
export function isGroupNotification(type: number): boolean {
  return (
    type >= ImContentType.GROUP_CREATE &&
    type <= ImContentType.GROUP_BANNED &&
    type !== ImContentType.GROUP_MEMBER_SETTING_UPDATE
  )
}
/** åˆ¤æ–­æ˜¯å¦ã€Œå¥½å‹é€šçŸ¥äº‹ä»¶ã€ï¼š1201-1210 æ®µä½ */
export function isFriendNotification(type: number): boolean {
  return type >= ImContentType.FRIEND_REQUEST_APPROVED && type <= ImContentType.FRIEND_UPDATE
}
/** åˆ¤æ–­æ˜¯å¦ã€ŒåŠ ç¾¤ç”³è¯·é€šçŸ¥äº‹ä»¶ã€ï¼š1503/1505/1506 */
export function isGroupRequestNotification(type: number): boolean {
  return (
    type === ImContentType.GROUP_REQUEST_RECEIVED ||
    type === ImContentType.GROUP_REQUEST_APPROVED ||
    type === ImContentType.GROUP_REQUEST_REJECTED
  )
}
/** åˆ¤æ–­æ˜¯å¦ã€Œä¼šè¯å†…的好友事件气泡」:FRIEND_ADD / FRIEND_DELETE ç›´æŽ¥æ¸²æŸ“成灰色提示,与群事件同处理 */
export function isFriendChatTip(type: number): boolean {
  return type === ImContentType.FRIEND_ADD || type === ImContentType.FRIEND_DELETE
}
/** åˆ¤æ–­æ˜¯å¦ã€Œä¼šè¯å†…的通话事件气泡」:RTC_CALL_START / RTC_CALL_END æ¸²æŸ“成灰色提示 */
export function isRtcCallTip(type: number): boolean {
  return type === ImContentType.RTC_CALL_START || type === ImContentType.RTC_CALL_END
}
/**
 * IM æ™®é€šå†…容类型集合(normal vs event äºŒåˆ†ï¼›ä¸ŽåŽç«¯ ImContentTypeEnum.normal å­—段语义一致)
 *
 * è¿™ä¸ªé›†åˆåœ¨å¤šå¤„被复用,新增类型前先确认所有副作用都符合预期:
 * 1. åŽç«¯å‘送入口校验(Im{Private,Group}MessageSendReqVO.isNormalType)—— ç”¨æˆ·å‘送的内容类型必须 normal=true
 * 2. å‰ç«¯æŽ¥æ”¶ä¾§æœªè¯» / æç¤ºéŸ³ï¼ˆwebsocketStore)—— normal æ¶ˆæ¯è®¡å…¥ä¼šè¯æœªè¯»æ•° + è§¦å‘声音
 * 3. å‰ç«¯ä¼šè¯åˆ—表 lastType / @ æ ‡ç­¾ï¼ˆConversationItem)—— åªæœ‰ normal æ‰ç®—「最后一条聊天消息」
 * 4. å‰ç«¯ç¾¤æ¶ˆæ¯ç½®é¡¶èœå•(message-item.vue çš„ canPin)—— normal æ‰å…è®¸ç¾¤ä¸» / ç®¡ç†å‘˜ç½®é¡¶
 *
 * åç‰‡ï¼ˆCARD)/ è¡¨æƒ…(FACE)都是「用户主动发的聊天消息」,1/2/3 éƒ½ç¬¦åˆé¢„期;4 åŒæ—¶æ”¾å¼€ = ç¾¤ä¸»å¯ç½®é¡¶ï¼Œè¯­ä¹‰åˆç†
 */
const ImContentTypeNormals = new Set<number>([
  ImContentType.CARD,
  ImContentType.FACE,
  ImContentType.FILE,
  ImContentType.IMAGE,
  ImContentType.MATERIAL, // é¢‘道素材计入未读数 + è¿›ä¼šè¯åˆ—表
  ImContentType.MERGE,
  ImContentType.TEXT,
  ImContentType.VIDEO,
  ImContentType.VOICE
])
/** åˆ¤æ–­æ˜¯å¦"普通消息" */
export function isNormalMessage(type: number): boolean {
  return ImContentTypeNormals.has(type)
}
/** IM åª’体内容类型集合:发送依赖本地 File ä¸Šä¼ ï¼Œåˆ·æ–°åŽ _localFile ä¸¢å¤±å³ä¸å¯æ¢å¤ */
const ImContentTypeMedia = new Set<number>([
  ImContentType.FILE,
  ImContentType.IMAGE,
  ImContentType.VIDEO,
  ImContentType.VOICE
])
/** åˆ¤æ–­æ˜¯å¦ã€Œåª’体消息」:图片 / æ–‡ä»¶ / è¯­éŸ³ / è§†é¢‘ */
export function isMediaMessageType(type: number): boolean {
  return ImContentTypeMedia.has(type)
}
/**
 * IM æ¶ˆæ¯çŠ¶æ€æžšä¸¾ï¼ˆå¯¹é½åŽç«¯ ImMessageStatusEnum,前端扩展 SENDING + FAILED)
 *
 * ç”Ÿå‘½å‘¨æœŸï¼šFAILED(-2) â†’ SENDING(-1) â†’ NORMAL(0) â†’ RECALL(2)
 */
export const ImMessageStatus = {
  FAILED: -2, // å‘送失败(前端独有)
  SENDING: -1, // å‘送中(前端独有)
  NORMAL: 0, // æ­£å¸¸
  RECALL: 2 // å·²æ’¤å›ž
} as const
/** IM ä¼šè¯ç±»åž‹æžšä¸¾ */
export const ImConversationType = {
  NONE: 0, // æ— ä¼šè¯
  PRIVATE: 1, // ç§èŠ
  GROUP: 2, // ç¾¤èŠ
  CHANNEL: 3 // é¢‘道 / å…¬ä¼—号
} as const
/** ImConversationType å–值(用于消息 payload å­—段类型收窄) */
export type ImConversationTypeValue = (typeof ImConversationType)[keyof typeof ImConversationType]
/** æ˜¯å¦ç§èŠä¼šè¯ï¼›åŒæ—¶æ”¶çª„类型 */
export function isPrivateConversation(type: number | undefined): boolean {
  return type === ImConversationType.PRIVATE
}
/** æ˜¯å¦ç¾¤èŠä¼šè¯ï¼›åŒæ—¶æ”¶çª„类型 */
export function isGroupConversation(type: number | undefined): boolean {
  return type === ImConversationType.GROUP
}
/** æ˜¯å¦é¢‘道会话;同时收窄类型 */
export function isChannelConversation(type: number | undefined): boolean {
  return type === ImConversationType.CHANNEL
}
/** IM é€šè¯åª’体类型(对齐后端 ImRtcCallMediaTypeEnum) */
export const ImRtcCallMediaType = {
  VOICE: 1,
  VIDEO: 2
} as const
/** IM é€šè¯çŠ¶æ€ï¼ˆå¯¹é½åŽç«¯ ImRtcCallStatusEnum) */
export const ImRtcCallStatus = {
  CREATED: 10, // åˆ›å»ºï¼šç§èŠç­‰è¢«å«æŽ¥å¬ï¼›ç¾¤èŠå‘起人已进房等其他人加入
  RUNNING: 20, // è¿›è¡Œä¸­ï¼šç¬¬ä¸€ä¸ªéžå‘起人接通后进入
  ENDED: 30 // å·²ç»“束
} as const
/** IM é€šè¯ç»“束原因(对齐后端 ImRtcCallEndReasonEnum) */
export const ImRtcCallEndReason = {
  HANGUP: 1, // æŽ¥é€šåŽä»»ä¸€æ–¹ä¸»åŠ¨æŒ‚æ–­
  REJECT: 2, // è¢«å«æŽ¥é€šå‰ç‚¹æ‹’接
  CANCEL: 3, // ä¸»å«æŽ¥é€šå‰ä¸»åŠ¨å–æ¶ˆ
  NO_ANSWER: 4, // æŒ¯é“ƒè¶…时未接通
  BUSY: 5, // ç§èŠå‘¼å«æ—¶å¯¹æ–¹æ­£å¿™
  ERROR: 9 // ç½‘络中断 / è®¾å¤‡å¤±è´¥
} as const
/** ImRtcCallEndReason å–值类型 */
export type ImRtcCallEndReasonValue = (typeof ImRtcCallEndReason)[keyof typeof ImRtcCallEndReason]
/** IM é€šè¯å‚与者状态(对齐后端 ImRtcParticipantStatusEnum);同时作为 RTC_CALL ä¿¡ä»¤ status å­—段取值 */
export const ImRtcParticipantStatus = {
  INVITING: 10, // æ¥ç”µé‚€è¯·
  JOINED: 20, // æŽ¥å¬ / å·²åŠ å…¥
  REJECTED: 30, // æ‹’接
  NO_ANSWER: 40, // ä¸»å«å–消,被邀请方未应答
  LEFT: 50 // æŒ‚断离开
} as const
/** ImRtcParticipantStatus å–值类型 */
export type ImRtcParticipantStatusValue =
  (typeof ImRtcParticipantStatus)[keyof typeof ImRtcParticipantStatus]
/**
 * IM é€šè¯ UI é˜¶æ®µï¼›å‰ç«¯ç‹¬æœ‰ï¼Œç”¨äºŽé©±åЍ inviting / incoming / running ä¸‰ç§å¼¹çª—切换;
 * è·ŸåŽç«¯ ImRtcCallStatus ä¸æ˜¯ 1:1 æ˜ å°„,stage å¤šäº†ã€Œè‡ªå·±æ˜¯ä¸»å«è¿˜æ˜¯è¢«å«ã€çš„角色维度
 */
export const ImRtcCallStage = {
  IDLE: 'idle', // ç©ºé—²ï¼›åŽç«¯æ— å¯¹åº”(本端无活跃通话)
  INVITING: 'inviting', // ä¸»å«ç­‰å¾…对方接受;对应后端 ImRtcCallStatus.CREATED(自己是主叫)
  INCOMING: 'incoming', // è¢«å«æ¥ç”µå“é“ƒï¼›å¯¹åº”后端 ImRtcCallStatus.CREATED(自己是被叫)
  RUNNING: 'running' // é€šè¯ä¸­ï¼›å¯¹åº”后端 ImRtcCallStatus.RUNNING
} as const
/** ImRtcCallStage å–值类型 */
export type ImRtcCallStageValue = (typeof ImRtcCallStage)[keyof typeof ImRtcCallStage]
/** IM WebSocket å¤–层帧类型 */
export const ImWebSocketMessageType = {
  NOTIFICATION: 'im-notification' // IM é€šçŸ¥
} as const
/** IM æ¶ˆæ¯å›žæ‰§çŠ¶æ€æžšä¸¾ï¼ˆå¯¹é½åŽç«¯ ImMessageReceiptStatusEnum) */
export const ImMessageReceiptStatus = {
  NO_RECEIPT: 0, // ä¸éœ€è¦å›žæ‰§
  PENDING: 1, // å¾…完成
  DONE: 2 // å·²å®Œæˆ
} as const
/** ç¾¤æˆå‘˜è§’色(对齐后端 ImGroupMemberRoleEnum) */
export const ImGroupMemberRole = {
  OWNER: 1, // ç¾¤ä¸»
  ADMIN: 2, // ç®¡ç†å‘˜
  NORMAL: 3 // æ™®é€šæˆå‘˜
} as const
/** åŠ ç¾¤æ¥æºï¼ˆå¯¹é½åŽç«¯ ImGroupAddSourceEnum) */
export const ImGroupAddSource = {
  SEARCH: 1, // æœç´¢
  INVITE: 2, // é‚€è¯·
  QR_CODE: 3, // æ‰«ç 
  SHARE_LINK: 4 // åˆ†äº«é“¾æŽ¥
} as const
/** åŠ ç¾¤ç”³è¯·å¤„ç†ç»“æžœï¼ˆå¯¹é½åŽç«¯ ImGroupRequestHandleResultEnum) */
export const ImGroupRequestHandleResult = {
  UNHANDLED: 0, // æœªå¤„理
  AGREED: 1, // åŒæ„
  REFUSED: 2 // æ‹’绝
} as const
/** å¥½å‹æ·»åŠ æ¥æºï¼ˆå¯¹é½åŽç«¯ ImFriendAddSourceEnum) */
export const ImFriendAddSource = {
  SEARCH: 1, // æœç´¢
  GROUP: 2, // ç¾¤èŠ
  QR_CODE: 3, // æ‰«ç 
  CARD: 4 // åç‰‡
} as const
/** å¥½å‹ç”³è¯·å¤„理结果(对齐后端 ImFriendRequestHandleResultEnum) */
export const ImFriendRequestHandleResult = {
  UNHANDLED: 0, // æœªå¤„理
  AGREED: 1, // åŒæ„
  REFUSED: 2 // æ‹’绝
} as const
/**
 * @全体成员 çš„特殊 userId æ ‡è¯†ï¼šatUserIds ä¸­åŒ…含 -1 è¡¨ç¤º @ å…¨ä½“成员
 *
 * ä¸ŽåŽç«¯çº¦å®šï¼šç¾¤æ¶ˆæ¯ atUserIds æ•°ç»„里出现 -1 æ—¶ï¼Œæ‰€æœ‰æˆå‘˜éƒ½æ”¶åˆ°æé†’
 * MentionPicker æ¸²æŸ“虚拟项 + conversationStore.applyAt åˆ¤å®š atAll éƒ½é è¿™ä¸ªå€¼
 */
export const IM_AT_ALL_USER_ID = -1
/** @全体成员 çš„展示名(对齐微信 PC) */
export const IM_AT_ALL_NICKNAME = '所有人'
/** è½¬å‘模式:SINGLE é€æ¡åŽŸæ ·è½¬ / MERGE æ‰“包成 MergeMessage */
export const ImForwardMode = {
  SINGLE: 'single',
  MERGE: 'merge'
} as const
/** ImForwardMode å–值类型 */
export type ImForwardModeValue = (typeof ImForwardMode)[keyof typeof ImForwardMode]