| 1 | /* |
| 2 | * @Author: nevin |
| 3 | * @Date: 2025-01-20 22:02:54 |
| 4 | * @LastEditTime: 2025-04-27 09:51:25 |
| 5 | * @LastEditors: nevin |
| 6 | * @Description: interaction Interaction 互动 |
| 7 | */ |
| 8 | import windowOperate from '../../util/windowOperate'; |
| 9 | import { AutoRunModel, AutoRunType } from '../../db/models/autoRun'; |
| 10 | import { AccountService } from '../account/service'; |
| 11 | import { AutoRunService } from '../autoRun/service'; |
| 12 | import { Controller, Et, Icp, Inject, Scheduled } from '../core/decorators'; |
| 13 | import { InteractionService } from './service'; |
| 14 | import { SendChannelEnum } from '../../../commont/UtilsEnum'; |
| 15 | import type { WorkData } from '../plat/plat.type'; |
| 16 | import { AutorWorksInteractionScheduleEvent } from '../../../commont/types/interaction'; |
| 17 | import { AutoInteractionCache } from './cacheData'; |
| 18 | import { getUserInfo } from '../user/comment'; |
| 19 | import type { CorrectQuery } from '../../global/table'; |
| 20 | import { PlatType } from '../../../commont/AccountEnum'; |
| 21 | import { taskApi } from '../api/taskApi'; |
| 22 | import platController from '../plat'; |
| 23 | |
| 24 | @Controller() |
| 25 | export class InteractionController { |
| 26 | @Inject(InteractionService) |
| 27 | private readonly interactionService!: InteractionService; |
| 28 | |
| 29 | @Inject(AccountService) |
| 30 | private readonly accountService!: AccountService; |
| 31 | |
| 32 | @Inject(AutoRunService) |
| 33 | private readonly autoRunService!: AutoRunService; |
| 34 | |
| 35 | /** |
| 36 | * 一键AI互动 |
| 37 | */ |
| 38 | @Icp('ICP_INTERACTION_ONE_DATA') |
| 39 | async interactionOneData( |
| 40 | event: Electron.IpcMainInvokeEvent, |
| 41 | accountId: number, |
| 42 | works: WorkData, |
| 43 | option: { |
| 44 | commentContent: string; // 评论内容 |
| 45 | }, |
| 46 | ): Promise<any> { |
| 47 | const account = await this.accountService.getAccountById(accountId); |
| 48 | if (!account) return null; |
| 49 | |
| 50 | const res = await this.interactionService.autorInteraction( |
| 51 | account, |
| 52 | [works], |
| 53 | option as any, |
| 54 | (e: { |
| 55 | tag: AutorWorksInteractionScheduleEvent; |
| 56 | status: -1 | 0 | 1; |
| 57 | data?: any; |
| 58 | error?: any; |
| 59 | }) => { |
| 60 | windowOperate.sendRenderMsg(SendChannelEnum.CommentRelyProgress, e); |
| 61 | }, |
| 62 | ); |
| 63 | |
| 64 | return res; |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * 一键AI互动 |
| 69 | */ |
| 70 | @Icp('ICP_INTERACTION_ONE_KEY') |
| 71 | async interactionOneKey( |
| 72 | event: Electron.IpcMainInvokeEvent, |
| 73 | accountId: number, |
| 74 | worksList: WorkData[], |
| 75 | option: { |
| 76 | commentContent: string; // 评论内容 |
| 77 | taskId?: string; // 任务ID |
| 78 | platform?: string; // 平台ID |
| 79 | likeProb?: any; // 点赞概率 |
| 80 | collectProb?: any; // 收藏概率 |
| 81 | commentProb?: any; // 评论概率 |
| 82 | commentType: any; // 评论类型 |
| 83 | }, |
| 84 | ): Promise<any> { |
| 85 | const account = await this.accountService.getAccountById(accountId); |
| 86 | if (!account) return null; |
| 87 | |
| 88 | const res = await this.interactionService.autorInteraction( |
| 89 | account, |
| 90 | worksList, |
| 91 | option, |
| 92 | (e: { |
| 93 | tag: AutorWorksInteractionScheduleEvent; |
| 94 | status: -1 | 0 | 1; |
| 95 | data?: any; |
| 96 | error?: any; |
| 97 | }) => { |
| 98 | windowOperate.sendRenderMsg(SendChannelEnum.InteractionProgress, e); |
| 99 | }, |
| 100 | ); |
| 101 | |
| 102 | return res; |
| 103 | } |
| 104 | |
| 105 | /** |
| 106 | * 创建自动AI评论截流任务 |
| 107 | */ |
| 108 | @Icp('ICP_AUTO_RUN_INTERACTION') |
| 109 | async createReplyCommentAutoRun( |
| 110 | event: Electron.IpcMainInvokeEvent, |
| 111 | accountId: number, |
| 112 | data: WorkData, |
| 113 | cycleType: string, |
| 114 | ): Promise<AutoRunModel | null> { |
| 115 | const account = await this.accountService.getAccountById(accountId); |
| 116 | if (!account) return null; |
| 117 | |
| 118 | const res = await this.autoRunService.createAutoRun( |
| 119 | { |
| 120 | accountId, |
| 121 | cycleType, |
| 122 | type: AutoRunType.ReplyComment, |
| 123 | userId: account.uid, |
| 124 | }, |
| 125 | data, |
| 126 | ); |
| 127 | |
| 128 | return res; |
| 129 | } |
| 130 | |
| 131 | // 运行自动评论任务 |
| 132 | @Et('ET_AUTO_RUN_REPLY_COMMENT') |
| 133 | async runAutoReplyComment(autoRunData: AutoRunModel): Promise<boolean> { |
| 134 | const { accountId, dataInfo } = autoRunData; |
| 135 | if (!dataInfo) return false; |
| 136 | |
| 137 | const account = await this.accountService.getAccountById(accountId); |
| 138 | if (!account) return false; |
| 139 | |
| 140 | const res = await this.interactionService.addReplyQueue( |
| 141 | account, |
| 142 | dataInfo as WorkData[], |
| 143 | { |
| 144 | commentContent: dataInfo.commentContent, |
| 145 | }, |
| 146 | autoRunData, |
| 147 | ); |
| 148 | |
| 149 | return res.status === 1; |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * 获取AI评论截流的记录列表 |
| 154 | */ |
| 155 | @Icp('ICP_GET_INTERACTION_RECORD_LIST') |
| 156 | async getInteractionRecordList( |
| 157 | event: Electron.IpcMainInvokeEvent, |
| 158 | page: CorrectQuery, |
| 159 | query: { |
| 160 | accountId?: number; |
| 161 | type?: PlatType; |
| 162 | }, |
| 163 | ): Promise<any> { |
| 164 | const userInfo = getUserInfo(); |
| 165 | |
| 166 | return this.interactionService.getInteractionRecordList( |
| 167 | userInfo.id, |
| 168 | page, |
| 169 | query, |
| 170 | ); |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * 获取AI评论截流的任务信息 |
| 175 | */ |
| 176 | @Icp('ICP_GET_AUTO_INTERACTION_INFO') |
| 177 | async getAutoInteractionInfo( |
| 178 | event: Electron.IpcMainInvokeEvent, |
| 179 | ): Promise<any | null> { |
| 180 | return AutoInteractionCache.getInfo(); |
| 181 | } |
| 182 | |
| 183 | // 自动互动, 每10秒进行 |
| 184 | @Scheduled('0 * * * * *', 'autoHudong') |
| 185 | async zidongHudong() { |
| 186 | // return; |
| 187 | console.log('自动互动 ing ...'); |
| 188 | const res = await taskApi.getActivityTask(); |
| 189 | console.log('---- getActivityTask ----', res); |
| 190 | const accountList = await this.accountService.getAccounts(); |
| 191 | // console.log('---- accountList ----', accountList); |
| 192 | if (res.items.length > 0) { |
| 193 | for (const item of res.items) { |
| 194 | for (const accountType of item.accountTypes) { |
| 195 | let myAccountTypeList = []; |
| 196 | for (const account of accountList) { |
| 197 | if (account.type === accountType && account.status === 0) { |
| 198 | myAccountTypeList.push(account); |
| 199 | // 申请任务 |
| 200 | try { |
| 201 | const applyTaskRes = await taskApi.applyTask(item.id || item._id, { |
| 202 | account: account.account, |
| 203 | uid: account.uid, |
| 204 | accountType: account.type, |
| 205 | }); |
| 206 | console.log('---- applyTaskRes ----', applyTaskRes); |
| 207 | if (applyTaskRes.data.data?.data) { |
| 208 | item.taskId = applyTaskRes.data.data?.data.id; |
| 209 | } |
| 210 | } catch (error) { |
| 211 | console.error('申请任务失败:', error); |
| 212 | } |
| 213 | } |
| 214 | } |
| 215 | // console.log('---- myAccountTypeList ----', myAccountTypeList); |
| 216 | |
| 217 | for (const account of myAccountTypeList) { |
| 218 | // console.log('---- account ----', account); |
| 219 | console.log('---- item.dataInfo?.commentContent ----', item.dataInfo?.commentContent); |
| 220 | const autorInteractionList = this.interactionService.getAutorInteractionList(account, [{ |
| 221 | author: {id: item.dataInfo?.authorId || ''} , |
| 222 | data : {id: item.dataInfo.worksId, xsec_token: item.dataInfo?.xsec_token || ''}, |
| 223 | dataId : item.dataInfo.worksId, |
| 224 | option : {xsec_token: item.dataInfo?.xsec_token || ''}, |
| 225 | title : item.title, |
| 226 | }], { |
| 227 | accountType: accountType, |
| 228 | commentContent: item.dataInfo?.commentContent, |
| 229 | }); |
| 230 | |
| 231 | // 提交完成任务 |
| 232 | console.log('---- autorInteractionList ----', autorInteractionList); |
| 233 | let submitTasStr = '作品'+ item.dataInfo.worksId + '账户'+ account.nickname + '账户ID'+ account.uid; |
| 234 | console.log('item.taskId', item.taskId) |
| 235 | if (item.taskId) { |
| 236 | const submitTaskRes = await taskApi.submitTask(item.taskId, { |
| 237 | submissionUrl: submitTasStr, |
| 238 | screenshotUrls: [], |
| 239 | qrCodeScanResult: submitTasStr, |
| 240 | }); |
| 241 | } |
| 242 | // console.log('---- submitTaskRes ----', submitTaskRes); |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 |