From faec53d49763d84bb0adc45df07c19e9cede81a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Sun, 25 May 2025 16:09:06 +0800 Subject: [PATCH] feat: #1031 --- src/core/apis/group.ts | 53 ++++ src/core/data/group.ts | 245 +++++++++++++++++ src/core/data/index.ts | 1 + src/core/services/NodeIKernelGroupService.ts | 15 + src/core/types/group.ts | 272 +++++++++++++++++++ 5 files changed, 586 insertions(+) create mode 100644 src/core/data/group.ts create mode 100644 src/core/data/index.ts diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index 248ef54a..6476add2 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -17,6 +17,7 @@ import { isNumeric, solveAsyncProblem } from '@/common/helper'; import { LimitedHashTable } from '@/common/message-unique'; import { NTEventWrapper } from '@/common/event'; import { CancelableTask, TaskExecutor } from '@/common/cancel-task'; +import { createGroupDetailInfoV2Param, createGroupExtFilter, createGroupExtInfo } from '../data'; export class NTQQGroupApi { context: InstanceContext; @@ -113,6 +114,58 @@ export class NTQQGroupApi { return this.context.session.getGroupService().setHeader(groupCode, filePath); } + // 0 0 无需管理员审核 + // 0 2 需要管理员审核 + // 1 2 禁止Bot入群( 最好只传一个1 ?) + async setGroupRobotAddOption(groupCode: string, robotMemberSwitch?: number, robotMemberExamine?: number) { + let extInfo = createGroupExtInfo(groupCode); + let groupExtFilter = createGroupExtFilter(); + if (robotMemberSwitch !== undefined) { + extInfo.extInfo.inviteRobotMemberSwitch = robotMemberSwitch; + groupExtFilter.inviteRobotMemberSwitch = 1; + } + if (robotMemberExamine !== undefined) { + extInfo.extInfo.inviteRobotMemberExamine = robotMemberExamine; + groupExtFilter.inviteRobotMemberExamine = 1; + } + this.context.session.getGroupService().modifyGroupExtInfoV2(extInfo, groupExtFilter); + } + + async setGroupAddOption(groupCode: string, option: { + addOption: number; + groupQuestion?: string; + groupAnswer?: string; + }) { + let param = createGroupDetailInfoV2Param(groupCode); + // 设置要修改的目标 + param.filter.addOption = 1; + if (option.addOption == 4 || option.addOption == 5) { + // 4 问题进入答案 5 问题管理员批准 + param.filter.groupQuestion = 1; + param.filter.groupAnswer = option.addOption == 4 ? 1 : 0; + param.modifyInfo.groupQuestion = option.groupQuestion || ''; + param.modifyInfo.groupAnswer = option.addOption == 4 ? option.groupAnswer || '' : ''; + } + param.modifyInfo.addOption = option.addOption; + this.context.session.getGroupService().modifyGroupDetailInfoV2(param, 0); + } + + async setGroupSearch(groupCode: string, option: { + noCodeFingerOpenFlag?: number; + noFingerOpenFlag?: number; + }) { + let param = createGroupDetailInfoV2Param(groupCode); + if (option.noCodeFingerOpenFlag) { + param.filter.noCodeFingerOpenFlag = 1; + param.modifyInfo.noCodeFingerOpenFlag = option.noCodeFingerOpenFlag; + } + if (option.noFingerOpenFlag) { + param.filter.noFingerOpenFlag = 1; + param.modifyInfo.noFingerOpenFlag = option.noFingerOpenFlag; + } + this.context.session.getGroupService().modifyGroupDetailInfoV2(param, 0); + } + async getGroups(forced: boolean = false) { const [, , groupList] = await this.core.eventWrapper.callNormalEventV2( 'NodeIKernelGroupService/getGroupList', diff --git a/src/core/data/group.ts b/src/core/data/group.ts new file mode 100644 index 00000000..2b9636e7 --- /dev/null +++ b/src/core/data/group.ts @@ -0,0 +1,245 @@ +import { GroupDetailInfoV2Param, GroupExtInfo, GroupExtFilter } from "../types"; + +export function createGroupDetailInfoV2Param(group_code: string): GroupDetailInfoV2Param { + return { + groupCode: group_code, + filter: + { + noCodeFingerOpenFlag: 0, + noFingerOpenFlag: 0, + groupName: 0, + classExt: 0, + classText: 0, + fingerMemo: 0, + richFingerMemo: 0, + tagRecord: 0, + groupGeoInfo: + { + ownerUid: 0, + setTime: 0, + cityId: 0, + longitude: 0, + latitude: 0, + geoContent: 0, + poiId: 0 + }, + groupExtAdminNum: 0, + flag: 0, + groupMemo: 0, + groupAioSkinUrl: 0, + groupBoardSkinUrl: 0, + groupCoverSkinUrl: 0, + groupGrade: 0, + activeMemberNum: 0, + certificationType: 0, + certificationText: 0, + groupNewGuideLines: + { + enabled: 0, + content: 0 + }, + groupFace: 0, + addOption: 0, + shutUpTime: 0, + groupTypeFlag: 0, + appPrivilegeFlag: 0, + appPrivilegeMask: 0, + groupExtOnly: + { + tribeId: 0, + moneyForAddGroup: 0 + }, groupSecLevel: 0, + groupSecLevelInfo: 0, + subscriptionUin: 0, + subscriptionUid: "", + allowMemberInvite: 0, + groupQuestion: 0, + groupAnswer: 0, + groupFlagExt3: 0, + groupFlagExt3Mask: 0, + groupOpenAppid: 0, + rootId: 0, + msgLimitFrequency: 0, + hlGuildAppid: 0, + hlGuildSubType: 0, + hlGuildOrgId: 0, + groupFlagExt4: 0, + groupFlagExt4Mask: 0, + groupSchoolInfo: { + location: 0, + grade: 0, + school: 0 + }, + groupCardPrefix: + { + introduction: 0, + rptPrefix: 0 + }, allianceId: 0, + groupFlagPro1: 0, + groupFlagPro1Mask: 0 + }, + modifyInfo: { + noCodeFingerOpenFlag: 0, + noFingerOpenFlag: 0, + groupName: "", + classExt: 0, + classText: "", + fingerMemo: "", + richFingerMemo: "", + tagRecord: [], + groupGeoInfo: { + ownerUid: "", + SetTime: 0, + CityId: 0, + Longitude: "", + Latitude: "", + GeoContent: "", + poiId: "" + }, + groupExtAdminNum: 0, + flag: 0, + groupMemo: "", + groupAioSkinUrl: "", + groupBoardSkinUrl: "", + groupCoverSkinUrl: "", + groupGrade: 0, + activeMemberNum: 0, + certificationType: 0, + certificationText: "", + groupNewGuideLines: { + enabled: false, + content: "" + }, groupFace: 0, + addOption: 0, + shutUpTime: 0, + groupTypeFlag: 0, + appPrivilegeFlag: 0, + appPrivilegeMask: 0, + groupExtOnly: { + tribeId: 0, + moneyForAddGroup: 0 + }, + groupSecLevel: 0, + groupSecLevelInfo: 0, + subscriptionUin: "", + subscriptionUid: "", + allowMemberInvite: 0, + groupQuestion: "", + groupAnswer: "", + groupFlagExt3: 0, + groupFlagExt3Mask: 0, + groupOpenAppid: 0, + rootId: "", + msgLimitFrequency: 0, + hlGuildAppid: 0, + hlGuildSubType: 0, + hlGuildOrgId: 0, + groupFlagExt4: 0, + groupFlagExt4Mask: 0, + groupSchoolInfo: { + location: "", + grade: 0, + school: "" + }, + groupCardPrefix: + { + introduction: "", + rptPrefix: [] + }, + allianceId: "", + groupFlagPro1: 0, + groupFlagPro1Mask: 0 + } + } +} +export function createGroupExtInfo(group_code: string): GroupExtInfo { + return { + groupCode: group_code, + resultCode: 0, + extInfo: { + groupInfoExtSeq: 0, + reserve: 0, + luckyWordId: '', + lightCharNum: 0, + luckyWord: '', + starId: 0, + essentialMsgSwitch: 0, + todoSeq: 0, + blacklistExpireTime: 0, + isLimitGroupRtc: 0, + companyId: 0, + hasGroupCustomPortrait: 0, + bindGuildId: '', + groupOwnerId: { + memberUin: '', + memberUid: '', + memberQid: '', + }, + essentialMsgPrivilege: 0, + msgEventSeq: '', + inviteRobotSwitch: 0, + gangUpId: '', + qqMusicMedalSwitch: 0, + showPlayTogetherSwitch: 0, + groupFlagPro1: '', + groupBindGuildIds: { + guildIds: [], + }, + viewedMsgDisappearTime: '', + groupExtFlameData: { + switchState: 0, + state: 0, + dayNums: [], + version: 0, + updateTime: '', + isDisplayDayNum: false, + }, + groupBindGuildSwitch: 0, + groupAioBindGuildId: '', + groupExcludeGuildIds: { + guildIds: [], + }, + fullGroupExpansionSwitch: 0, + fullGroupExpansionSeq: '', + inviteRobotMemberSwitch: 0, + inviteRobotMemberExamine: 0, + groupSquareSwitch: 0, + } + } +} +export function createGroupExtFilter(): GroupExtFilter { + return { + groupInfoExtSeq: 0, + reserve: 0, + luckyWordId: 0, + lightCharNum: 0, + luckyWord: 0, + starId: 0, + essentialMsgSwitch: 0, + todoSeq: 0, + blacklistExpireTime: 0, + isLimitGroupRtc: 0, + companyId: 0, + hasGroupCustomPortrait: 0, + bindGuildId: 0, + groupOwnerId: 0, + essentialMsgPrivilege: 0, + msgEventSeq: 0, + inviteRobotSwitch: 0, + gangUpId: 0, + qqMusicMedalSwitch: 0, + showPlayTogetherSwitch: 0, + groupFlagPro1: 0, + groupBindGuildIds: 0, + viewedMsgDisappearTime: 0, + groupExtFlameData: 0, + groupBindGuildSwitch: 0, + groupAioBindGuildId: 0, + groupExcludeGuildIds: 0, + fullGroupExpansionSwitch: 0, + fullGroupExpansionSeq: 0, + inviteRobotMemberSwitch: 0, + inviteRobotMemberExamine: 0, + groupSquareSwitch: 0, + } +}; \ No newline at end of file diff --git a/src/core/data/index.ts b/src/core/data/index.ts new file mode 100644 index 00000000..7cd52db8 --- /dev/null +++ b/src/core/data/index.ts @@ -0,0 +1 @@ +export * from "./group"; diff --git a/src/core/services/NodeIKernelGroupService.ts b/src/core/services/NodeIKernelGroupService.ts index d072b394..47be9c07 100644 --- a/src/core/services/NodeIKernelGroupService.ts +++ b/src/core/services/NodeIKernelGroupService.ts @@ -8,10 +8,22 @@ import { GroupNotifyMsgType, NTGroupRequestOperateTypes, KickMemberV2Req, + GroupDetailInfoV2Param, + GroupExtInfo, + GroupExtFilter, } from '@/core/types'; import { GeneralCallResult } from '@/core/services/common'; export interface NodeIKernelGroupService { + + modifyGroupExtInfoV2(groupExtInfo: GroupExtInfo, groupExtFilter: GroupExtFilter): Promise; + // ---> // 待启用 For Next Version 3.2.0 // isTroopMember ? 0 : 111 @@ -169,6 +181,9 @@ export interface NodeIKernelGroupService { modifyGroupDetailInfo(groupCode: string, arg: unknown): void; + // 第二个参数在大多数情况为0 设置群成员权限 例如上传群文件权限和群成员付费/加入邀请加入时为8 + modifyGroupDetailInfoV2(param: GroupDetailInfoV2Param, arg: number): Promise; + setGroupMsgMask(groupCode: string, arg: unknown): void; changeGroupShieldSettingTemp(groupCode: string, arg: unknown): void; diff --git a/src/core/types/group.ts b/src/core/types/group.ts index c8ec6f9a..3418d24f 100644 --- a/src/core/types/group.ts +++ b/src/core/types/group.ts @@ -1,4 +1,97 @@ import { QQLevel, NTSex } from './user'; +export interface GroupExtInfo { + groupCode: string; + resultCode: number; + extInfo: EXTInfo; +} +export interface GroupExtFilter { + groupInfoExtSeq: number; + reserve: number; + luckyWordId: number; + lightCharNum: number; + luckyWord: number; + starId: number; + essentialMsgSwitch: number; + todoSeq: number; + blacklistExpireTime: number; + isLimitGroupRtc: number; + companyId: number; + hasGroupCustomPortrait: number; + bindGuildId: number; + groupOwnerId: number; + essentialMsgPrivilege: number; + msgEventSeq: number; + inviteRobotSwitch: number; + gangUpId: number; + qqMusicMedalSwitch: number; + showPlayTogetherSwitch: number; + groupFlagPro1: number; + groupBindGuildIds: number; + viewedMsgDisappearTime: number; + groupExtFlameData: number; + groupBindGuildSwitch: number; + groupAioBindGuildId: number; + groupExcludeGuildIds: number; + fullGroupExpansionSwitch: number; + fullGroupExpansionSeq: number; + inviteRobotMemberSwitch: number; + inviteRobotMemberExamine: number; + groupSquareSwitch: number; +}; + +export interface EXTInfo { + groupInfoExtSeq: number; + reserve: number; + luckyWordId: string; + lightCharNum: number; + luckyWord: string; + starId: number; + essentialMsgSwitch: number; + todoSeq: number; + blacklistExpireTime: number; + isLimitGroupRtc: number; + companyId: number; + hasGroupCustomPortrait: number; + bindGuildId: string; + groupOwnerId: GroupOwnerID; + essentialMsgPrivilege: number; + msgEventSeq: string; + inviteRobotSwitch: number; + gangUpId: string; + qqMusicMedalSwitch: number; + showPlayTogetherSwitch: number; + groupFlagPro1: string; + groupBindGuildIds: GroupGuildIDS; + viewedMsgDisappearTime: string; + groupExtFlameData: GroupEXTFlameData; + groupBindGuildSwitch: number; + groupAioBindGuildId: string; + groupExcludeGuildIds: GroupGuildIDS; + fullGroupExpansionSwitch: number; + fullGroupExpansionSeq: string; + inviteRobotMemberSwitch: number; + inviteRobotMemberExamine: number; + groupSquareSwitch: number; +} + +export interface GroupGuildIDS { + guildIds: any[]; +} + +export interface GroupEXTFlameData { + switchState: number; + state: number; + dayNums: any[]; + version: number; + updateTime: string; + isDisplayDayNum: boolean; +} + +export interface GroupOwnerID { + memberUin: string; + memberUid: string; + memberQid: string; +} export interface KickMemberInfo { optFlag: number; @@ -7,6 +100,185 @@ export interface KickMemberInfo { optBytesMsg: string; } + +export interface GroupDetailInfoV2Param { + groupCode: string; + filter: Filter; + modifyInfo: ModifyInfo; +} + +export interface Filter { + noCodeFingerOpenFlag: number; + noFingerOpenFlag: number; + groupName: number; + classExt: number; + classText: number; + fingerMemo: number; + richFingerMemo: number; + tagRecord: number; + groupGeoInfo: FilterGroupGeoInfo; + groupExtAdminNum: number; + flag: number; + groupMemo: number; + groupAioSkinUrl: number; + groupBoardSkinUrl: number; + groupCoverSkinUrl: number; + groupGrade: number; + activeMemberNum: number; + certificationType: number; + certificationText: number; + groupNewGuideLines: FilterGroupNewGuideLines; + groupFace: number; + addOption: number; + shutUpTime: number; + groupTypeFlag: number; + appPrivilegeFlag: number; + appPrivilegeMask: number; + groupExtOnly: GroupEXTOnly; + groupSecLevel: number; + groupSecLevelInfo: number; + subscriptionUin: number; + subscriptionUid: string; + allowMemberInvite: number; + groupQuestion: number; + groupAnswer: number; + groupFlagExt3: number; + groupFlagExt3Mask: number; + groupOpenAppid: number; + rootId: number; + msgLimitFrequency: number; + hlGuildAppid: number; + hlGuildSubType: number; + hlGuildOrgId: number; + groupFlagExt4: number; + groupFlagExt4Mask: number; + groupSchoolInfo: FilterGroupSchoolInfo; + groupCardPrefix: FilterGroupCardPrefix; + allianceId: number; + groupFlagPro1: number; + groupFlagPro1Mask: number; +} + +export interface FilterGroupCardPrefix { + introduction: number; + rptPrefix: number; +} + +export interface GroupEXTOnly { + tribeId: number; + moneyForAddGroup: number; +} + +export interface FilterGroupGeoInfo { + ownerUid: number; + setTime: number; + cityId: number; + longitude: number; + latitude: number; + geoContent: number; + poiId: number; +} + +export interface FilterGroupNewGuideLines { + enabled: number; + content: number; +} + +export interface FilterGroupSchoolInfo { + location: number; + grade: number; + school: number; +} + +export interface ModifyInfo { + noCodeFingerOpenFlag: number; + noFingerOpenFlag: number; + groupName: string; + classExt: number; + classText: string; + fingerMemo: string; + richFingerMemo: string; + tagRecord: any[]; + groupGeoInfo: ModifyInfoGroupGeoInfo; + groupExtAdminNum: number; + flag: number; + groupMemo: string; + groupAioSkinUrl: string; + groupBoardSkinUrl: string; + groupCoverSkinUrl: string; + groupGrade: number; + activeMemberNum: number; + certificationType: number; + certificationText: string; + groupNewGuideLines: ModifyInfoGroupNewGuideLines; + groupFace: number; + addOption: number;// 0 空设置 1 任何人都可以进入 2 需要管理员批准 3 不允许任何人入群 4 问题进入答案 5 问题管理员批准 + shutUpTime: number; + groupTypeFlag: number; + appPrivilegeFlag: number; + // 需要管理员审核 + // 0000 0000 0000 0000 0000 0000 0000 + // 无需审核入群 + // 0000 0001 0000 0000 0000 0000 0000 + // 成员数100内无审核 + // 0100 0000 0000 0000 0000 0000 0000 + // 禁用 群成员邀请好友 + // 0100 0000 0000 0000 0000 0000 0000 + + appPrivilegeMask: number; + // 0110 0001 0000 0000 0000 0000 0000 + // 101711872 + groupExtOnly: GroupEXTOnly; + groupSecLevel: number; + groupSecLevelInfo: number; + subscriptionUin: string; + subscriptionUid: string; + allowMemberInvite: number; + groupQuestion: string; + groupAnswer: string; + groupFlagExt3: number; + groupFlagExt3Mask: number; + groupOpenAppid: number; + rootId: string; + msgLimitFrequency: number; + hlGuildAppid: number; + hlGuildSubType: number; + hlGuildOrgId: number; + groupFlagExt4: number; + groupFlagExt4Mask: number; + groupSchoolInfo: ModifyInfoGroupSchoolInfo; + groupCardPrefix: ModifyInfoGroupCardPrefix; + allianceId: string; + groupFlagPro1: number; + groupFlagPro1Mask: number; +} + +export interface ModifyInfoGroupCardPrefix { + introduction: string; + rptPrefix: any[]; +} + +export interface ModifyInfoGroupGeoInfo { + ownerUid: string; + SetTime: number; + CityId: number; + Longitude: string; + Latitude: string; + GeoContent: string; + poiId: string; +} + +export interface ModifyInfoGroupNewGuideLines { + enabled: boolean; + content: string; +} + +export interface ModifyInfoGroupSchoolInfo { + location: string; + grade: number; + school: string; +} + // 获取群详细信息的来源类型 export enum GroupInfoSource { KUNSPECIFIED,