@@ -47,11 +47,21 @@
@click ="setComText(index)" > 发送
< / div >
< / div >
< div class = "app-button" @click ="installt(device.udid, index, false)" > 安装粘贴工具 < / div >
< div class = "app-button" @click ="mqSend()" > mq < / div >
< ! - - < div class = "app-button" @click ="installt(device.udid, index, true)" > 安装tk < / div > - - >
< ! - - < div style = "display: flex;" >
< input style = "border: 1px solid #000;margin:0px 14px;" v-model = "textContent[index]" type="text" > < / input >
< div class = "app-button" style = "margin: 0px;height: 40px;width: 60px;font-size: 14px;"
@click ="setPrivateText(index)" > 发送
< / div >
< / div >
< div style = "display: flex;" >
< input style = "border: 1px solid #000;margin:0px 14px;" v-model = "textContent[index]" type="text" > < / input >
< div class = "app-button" style = "margin: 0px;height: 40px;width: 60px;font-size: 14px;"
@click ="setHostId(index)" > 发送
< / div >
< / div > - - >
<!-- < div class = "app-button" @click ="installt(device.udid, index, false)" > 安装粘贴工具 < / div > - - >
<!-- < div class = "app-button" @click ="mqSend()" > mq < / div > - - >
< div class = "app-button" @click ="installt(device.udid, index, true)" > 安装tk < / div >
< ! - - < div class = "app-button" @click ="wsActions.isHost(device.udid, index)" > 一键养号 < / div > - - >
< / div >
< / div >
@@ -64,6 +74,46 @@
@confirm ="onDialogConfirm" @cancel ="stop" / >
< HostListManagerDialog v -model :visible = "showHostDlg" @save ="onHostSaved" / >
< / div >
<!-- 定时调度配置弹窗 -- >
< el-dialog v-model = "showScheduleDlg" title="定时调度(每小时)" width="420px" >
< div style = "display:grid;grid-template-columns: 100px 1fr; gap:12px; align-items:center;" >
< div > 片段 A < / div >
< div style = "display:flex; gap:8px; align-items:center;" >
< el-select v-model = "schedAKey" style="width:140px;" >
< el -option label = "一键关注" value = "follow" / >
< el-option label = "刷视频(养号)" value = "like" / >
< el-option label = "刷直播" value = "brushLive" / >
< el-option label = "监测消息" value = "listen" / >
< / el-select >
< el-input-number v-model = "schedAMin" :min="1" :max="59" / >
< span > 分钟 < / span >
< / div >
< div > 片段 B < / div >
< div style = "display:flex; gap:8px; align-items:center;" >
< el-select v-model = "schedBKey" style="width:140px;" >
< el -option label = "一键关注" value = "follow" / >
< el-option label = "刷视频(养号)" value = "like" / >
< el-option label = "刷直播" value = "brushLive" / >
< el-option label = "监测消息" value = "listen" / >
< / el-select >
< el-input-number v-model = "schedBMin" :min="1" :max="59" / >
< span > 分钟 < / span >
< / div >
< div > 总时长 < / div >
< div > < b > { { schedAMin + schedBMin } } < / b > 分钟 ( 必须等于 60 ) < / div >
< div > 启用调度 < / div >
< div > < el-switch v-model = "scheduleEnabled" / > < / div >
< / div >
< template # footer >
< el-button @click ="showScheduleDlg = false" > 取消 < / el -button >
< el-button type = "primary" @click ="saveSchedule" > 保存并生效 < / el -button >
< / template >
< / el-dialog >
< / template >
< script setup >
@@ -86,7 +136,7 @@ import ChatDialog from '@/components/ChatDialog.vue'
// import { splitArray } from '@/utils/arrUtil' //分割数组 分配主播 已废弃
import { chooseFile } from '@/utils/fileUtil'
import { connectSSE } from '@/utils/sseUtils'
import { prologue , comment , } from '@/api/account' ;
import { prologue , comment , logout } from '@/api/account' ;
import { createTaskQueue } from '@/composables/useTaskQueue' //创建任务
import { useCanvasPointer } from '@/composables/useCanvasPointer' //canvas 初始化 点击转换
import { attachTrimmerForIndex } from '@/composables/useVideoStream' //修剪器
@@ -168,6 +218,85 @@ let istranslate = ref(false); //是否是翻译本页
let phoneXYinfo = ref ( getphoneXYinfo ( ) == null ? [ { } , { } , { } , { } , { } , { } , { } , { } ] : getphoneXYinfo ( ) ) ;
const isMonitorOn = ref ( false ) // false 表示关闭, true 表示开启
// —— 每小时调度:前 40 分钟 follow, 后 20 分钟 like ——
// 想改配比就改这两个 duration( 毫秒)
const schedulePlan = [
{ key : 'follow' , duration : 40 * 60 * 1000 } ,
{ key : 'like' , duration : 20 * 60 * 1000 } ,
]
// 调度状态(持久化一下,避免刷新丢失)
let scheduleState = ( ( ) => {
try {
const saved = JSON . parse ( localStorage . getItem ( 'SCHEDULE_STATE' ) || '{}' )
if ( saved && typeof saved . index === 'number' && typeof saved . startTime === 'number' ) {
return saved
}
} catch { }
return { index : 0 , startTime : Date . now ( ) }
} ) ( )
let scheduleTimer = null // 轮询定时器句柄
const scheduleTickMs = 30 _000 // 每 30s 检查一次是否到切换点
let scheduleEnabled = ref ( true ) // 需要时可手动关闭调度(例如“全部停止”)
// —— 调度 UI 状态 ——
// 弹窗
const showScheduleDlg = ref ( false )
// 两个时间片(默认 A=follow 40min, B=like 20min)
const schedAKey = ref ( 'follow' )
const schedAMin = ref ( 40 )
const schedBKey = ref ( 'like' )
const schedBMin = ref ( 20 )
// 打开弹窗:把当前 schedulePlan 映射到 UI
function openScheduleDialog ( ) {
// 把当前计划读出来(只支持两个片段的简易版)
if ( Array . isArray ( schedulePlan ) && schedulePlan . length >= 2 ) {
const a = schedulePlan [ 0 ] , b = schedulePlan [ 1 ]
schedAKey . value = a ? . key || 'follow'
schedAMin . value = Math . max ( 1 , Math . round ( ( a ? . duration || 40 * 60 _000 ) / 60 _000 ) )
schedBKey . value = b ? . key || 'like'
schedBMin . value = Math . max ( 1 , Math . round ( ( b ? . duration || 20 * 60 _000 ) / 60 _000 ) )
}
showScheduleDlg . value = true
}
// 保存:校验=60 分钟 → 更新 schedulePlan → 持久化 → 重启轮询
function saveSchedule ( ) {
const total = schedAMin . value + schedBMin . value
if ( total !== 60 ) {
ElMessage . error ( '两个片段相加必须等于 60 分钟' )
return
}
schedulePlan . splice ( 0 , schedulePlan . length ,
{ key : schedAKey . value , duration : schedAMin . value * 60 _000 } ,
{ key : schedBKey . value , duration : schedBMin . value * 60 _000 } ,
)
// 存 localStorage
localStorage . setItem ( 'SCHEDULE_PLAN' , JSON . stringify ( schedulePlan ) )
localStorage . setItem ( 'SCHEDULE_ENABLED' , JSON . stringify ( ! ! scheduleEnabled . value ) )
// 重置时间片起点并立即生效
scheduleState . index = 0
scheduleState . startTime = Date . now ( )
localStorage . setItem ( 'SCHEDULE_STATE' , JSON . stringify ( scheduleState ) )
// 若启用则重启轮询
if ( scheduleEnabled . value ) startScheduleLoop ( )
showScheduleDlg . value = false
ElMessage . success ( '已保存定时调度' )
}
// 这四个互斥模式的 key, 和你的 runType 对应
const EXCLUSIVE _KEYS = [ 'brushLive' , 'like' , 'follow' , 'listen' ] ;
@@ -310,6 +439,15 @@ const buttons = [
} ,
style : ( ) => ( { backgroundColor : isActive ( { key : 'listen' } ) ? 'red' : '' } )
} ,
{
label : '定时调度' ,
onClick : ( ) => openScheduleDialog ( ) ,
show : ( ) => true ,
img : {
normal : new URL ( '@/assets/video/leftBtn1.png' , import . meta . url ) . href ,
hover : new URL ( '@/assets/video/leftBtn1-1.png' , import . meta . url ) . href
}
} ,
{
label : '全部停止' ,
onClick : ( ) => stop ( ) ,
@@ -323,6 +461,7 @@ const buttons = [
label : '登出' ,
onClick : ( ) => {
td . disposeAll ( 'logout' )
logout ( { userId : userdata . id , tenantId : userdata . tenantId } )
router . push ( '/' )
} ,
show : ( ) => true ,
@@ -458,6 +597,15 @@ const initVideoStream = async (udid, index) => {
// 发送 开启 视频流数据
setTimeout ( ( ) => {
wslist [ index ] . send ( openStr ) ;
wsActions . openClose ( udid , index )
if ( runType . value ) {
resetApp ( udid , index )
setTimeout ( ( ) => {
continueAfterReset ( udid , index )
} , 5000 ) ;
}
} , 300 ) ;
wsCache . set ( udid , { ws : wslist [ index ] , index } ) ;
} ;
@@ -490,7 +638,7 @@ const initVideoStream = async (udid, index) => {
if ( resData . message == 0 ) {
console . log ( '没有消息' )
if ( runType . value == 'follow' ) {
LikesToLikesToLikes ( deviceInformation . value [ index ] . udid, index )
LikesToLikesToLikes ( udid , index )
}
//如果检测到有新消息, 会收到两条ws回复, 一条message==1 一条message==成功
@@ -504,21 +652,21 @@ const initVideoStream = async (udid, index) => {
clickxy ( resData . x * getphoneXYinfo ( ) [ index ] . width , resData . y * getphoneXYinfo ( ) [ index ] . height , index )
setTimeout ( ( ) => {
clickxy ( resData . x * getphoneXYinfo ( ) [ index ] . width , resData . y * getphoneXYinfo ( ) [ index ] . height , index ) //index为9的时候长按
wsActions . clickSysMesage ( deviceInformation . value [ index ] . udid, index ) //点击消息进入对话框
wsActions . clickSysMesage ( udid , index ) //点击消息进入对话框
} , 100 )
} , 2000 )
}
} else if ( resData . type == 'clickMesage' ) {
//点击进入新消息页面以后,获取页面信息
wsActions . clickCopyList ( deviceInformation . value [ index ] . udid, index )
wsActions . clickCopyList ( udid , index )
} else if ( resData . type == 'clickSysMesage' ) {
setTimeout ( ( ) => {
Back ( '' , index )
setTimeout ( ( ) => {
Back ( '' , index )
if ( runType . value == 'follow' ) {
LikesToLikesToLikes ( deviceInformation . value [ index ] . udid, index )
LikesToLikesToLikes ( udid , index )
}
// 仅监听模式下恢复
if ( runType . value === 'listen' || isMonitorOn . value ) {
@@ -557,7 +705,7 @@ const initVideoStream = async (udid, index) => {
chat ( { msg : mesBox . text } ) . then ( res => {
console . log ( "ai返回" , res )
textContentpri . value [ index ] = res . result
PrivatetexToPrivatePush ( deviceInformation . value [ index ] . udid, index )
PrivatetexToPrivatePush ( udid , index )
} )
} else {
@@ -610,7 +758,7 @@ const initVideoStream = async (udid, index) => {
phoneXYinfo . value [ index ] . id = resData . device
if ( resData . type == 'Likes' ) { //判断是否是 点赞
if ( runType . value == 'follow' ) {
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
wsActions . slideDown ( udid , index ) //是否继续下一个视频
}
} else if ( resData . type == 'Comment' ) { //打开评论
} else if ( resData . type == 'CommentText' ) { //复制评论
@@ -625,22 +773,22 @@ const initVideoStream = async (udid, index) => {
} , 1000 )
} else {
setTimeout ( ( ) => {
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
wsActions . slideDown ( udid , index ) //是否继续下一个视频
setTimeout ( ( ) => {
console . log ( '观看视频中' )
randomSeeVideo ( deviceInformation . value [ index ] . udid, index ) //50秒后继续循环任务
randomSeeVideo ( udid , index ) //50秒后继续循环任务
} , 1000 ) ;
} , 1000 )
}
} , 800 )
} else if ( resData . type == 'tomy' ) { //打开主页
} else if ( resData . type == 'Attention' ) { //关注、打开私信
// LikesToCommentToComPush(deviceInformation.value[index]. udid, index) //是否继续循环任务
// LikesToCommentToComPush(udid, index) //是否继续循环任务
} else if ( resData . type == 'return' ) { //私信评论
} else if ( resData . type == 'addHost' ) { //添加关注
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
wsActions . slideDown ( udid , index ) //是否继续下一个视频
setTimeout ( ( ) => {
wsActions . isHost ( deviceInformation . value [ index ] . udid, index ) //检测
wsActions . isHost ( udid , index ) //检测
} , 1000 ) ;
} else if ( resData . type == 'Privatetex' ) { //私信评论
} else if ( resData . type == 'PrivatePush' || resData . type == 'PrivatePushFollow' ) { //私信发送
@@ -659,9 +807,9 @@ const initVideoStream = async (udid, index) => {
Back ( '' , index ) ;
if ( isMonitor . value ) {
//正常没有消息,发送完私信以后,返回六次,然后继续下一个任务
wsActions . getmesNum ( deviceInformation . value [ index ] . udid, index )
wsActions . getmesNum ( udid , index )
} else {
LikesToLikesToLikes ( deviceInformation . value [ index ] . udid, index )
LikesToLikesToLikes ( udid , index )
}
@@ -669,8 +817,8 @@ const initVideoStream = async (udid, index) => {
} , 1000 ) ;
} else if ( resData . type == 'PrivatePushFollow' ) {
//如果有新消息,回复完私信以后,返回三次,然后继续下一个任务
// wsActions.getmesNum(deviceInformation.value[index]. udid, index)
// LikesToLikesToLikes(deviceInformation.value[index]. udid, index)
// wsActions.getmesNum(udid, index)
// LikesToLikesToLikes(udid, index)
if ( runType . value === 'listen' || isMonitorOn . value ) {
resumeAndKick ( index ) ; // ← 一步到位:恢复并在 1.5s 后补一次 getmesNum
@@ -688,41 +836,41 @@ const initVideoStream = async (udid, index) => {
} else if ( resData . type == 'isHost' ) { //视频关注主播
if ( resData . message == 0 ) {
console . log ( '无关注' , index )
Back ( deviceInformation . value [ index ] . udid, index )
Back ( udid , index )
setTimeout ( ( ) => {
console . log ( '观看视频中' , index )
randomSeeVideo ( deviceInformation . value [ index ] . udid, index ) //30-50秒后继续循环任务
randomSeeVideo ( udid , index ) //30-50秒后继续循环任务
} , 1000 ) ;
} else if ( resData . message == 1 ) {
console . log ( '有关注' , index )
const randomNum = Math . random ( ) ; // 生成一个0到1之间的随机数
//是否点赞评论的概率
if ( randomNum < 0.07 ) {
if ( randomNum < 0.2 0 ) {
console . log ( '进行点赞评论' , index )
LikesToCommentToComPush ( deviceInformation . value [ index ] . udid, index )
LikesToCommentToComPush ( udid , index )
} else {
console . log ( '下一个' , index )
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
randomSeeVideo ( deviceInformation . value [ index ] . udid, index ) //30-50秒后继续循环任务
wsActions . slideDown ( udid , index ) //是否继续下一个视频
randomSeeVideo ( udid , index ) //30-50秒后继续循环任务
}
}
} else if ( resData . type == 'openDY' ) { //视频关注主播
createTaskQueue( index ) . clear ( ) ; //清除队伍中的任务
// createTaskQueue(index).clear(); //清除队伍中的任务
} else if ( resData . type == 'toLive' ) { //打开直播
wsActions . isHead ( deviceInformation . value [ index ] . udid, index ) //判断直播
wsActions . isHead ( udid , index ) //判断直播
} else if ( resData . type == 'isHead' ) { //判断有没有头像
if ( resData . message == 1 ) {
wsActions . isOneLive ( deviceInformation . value [ index ] . udid, index ) //判断直播
wsActions . isOneLive ( udid , index ) //判断直播
} else {
return
}
} else if ( resData . type == 'isOneLive' ) { //判断单人还是双人
if ( resData . message == 0 ) {
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
wsActions . isHead ( deviceInformation . value [ index ] . udid, index ) //判断直播
wsActions . slideDown ( udid , index ) //是否继续下一个视频
wsActions . isHead ( udid , index ) //判断直播
return
}
// 用法:
@@ -739,8 +887,8 @@ const initVideoStream = async (udid, index) => {
const interval = setInterval ( ( ) => {
if ( count >= num ) {
clearInterval ( interval ) ;
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
wsActions . isHead ( deviceInformation . value [ index ] . udid, index ) //判断直播
wsActions . slideDown ( udid , index ) //是否继续下一个视频
wsActions . isHead ( udid , index ) //判断直播
return ;
}
@@ -753,8 +901,8 @@ const initVideoStream = async (udid, index) => {
} , 300 ) ;
return ;
} else {
wsActions . slideDown ( deviceInformation . value [ index ] . udid, index ) //是否继续下一个视频
wsActions . isHead ( deviceInformation . value [ index ] . udid, index ) //判断直播
wsActions . slideDown ( udid , index ) //是否继续下一个视频
wsActions . isHead ( udid , index ) //判断直播
return
}
} ) ( ) ;
@@ -780,7 +928,7 @@ const initVideoStream = async (udid, index) => {
console . log ( "正在安装..." )
} else if ( resData . message == '安装成功' ) {
if ( resData . apkName == 'clipper.apk' ) {
wsActions . startClipserve ( deviceInformation . value [ index ] . udid, index )
wsActions . startClipserve ( udid , index )
}
} else if ( resData . message === 500 ) {
@@ -808,8 +956,8 @@ const initVideoStream = async (udid, index) => {
} else {
resetApp ( udid , index )
setTimeout ( ( ) => {
wsActions . isHost ( deviceInformation . value [ index ] . udid, index )
} , 1 000)
wsActions . isHost ( udid , index )
} , 2 000)
}
//如果该视频无法被搜索到,返回刷下一条视频
} else if ( resData . type == 'toHost' ) {
@@ -819,7 +967,7 @@ const initVideoStream = async (udid, index) => {
createTaskQueue ( index ) . clear ( ) ; //清除队伍中的任务
setTimeout ( ( ) => {
Back ( '' , index )
LikesToLikesToLikes ( deviceInformation . value [ index ] . udid, index )
LikesToLikesToLikes ( udid , index )
} , 1000 )
} , 1000 )
} else if ( resData . type == 'PrivatePush' || resData . type == 'Privatetex' || resData . type == 'hostVideo' || resData . type == 'search' || resData . type == 'Attention' || resData . type == 'Comment' ) {
@@ -829,20 +977,20 @@ const initVideoStream = async (udid, index) => {
setTimeout ( ( ) => {
if ( isMonitor . value ) {
//正常没有消息,发送完私信以后,返回六次,然后继续下一个任务
wsActions . getmesNum ( deviceInformation . value [ index ] . udid, index )
wsActions . getmesNum ( udid , index )
} else {
LikesToLikesToLikes ( deviceInformation . value [ index ] . udid, index )
LikesToLikesToLikes ( udid , index )
}
// LikesToLikesToLikes(deviceInformation.value[index]. udid, index)
} , 1 000)
// LikesToLikesToLikes(udid, index)
} , 2 000)
}
} else if ( resData . type == 'getmesNum' ) {
if ( runType . value == 'follow' ) {
LikesToLikesToLikes ( deviceInformation . value [ index ] . udid, index )
LikesToLikesToLikes ( udid , index )
}
//getmesNum出现没有消息的情况
} else if ( resData . type == 'clickMesage' || resData . type == 'ComPush' ) {
} else if ( resData . type == 'clickMesage' || resData . type == 'ComPush' || resData . type == 'openClose' ) {
//ComPush关注主播的时候出现无法评论的视频 会跳过评论发送,不处理评论发送的返回错误
} else if ( resData . type == 'clickCopyList' ) {
//如果无法获取到聊天记录,返回继续检测
@@ -855,11 +1003,17 @@ const initVideoStream = async (udid, index) => {
} else if ( resData . type == 'clickSysMesage' ) {
//如果没有系统消息,则点击新消息
wsActions . clickMesage ( deviceInformation . value [ index ] . udid, index ) //点击消息进入对话框
wsActions . clickMesage ( udid , index ) //点击消息进入对话框
} else {
console . error ( resData . message , resData . type ) ; // 错误处理
ElMessage . error ( resData . message ) ;
createTaskQueue ( index ) . clear ( ) ; //清除队伍中的任务
resetApp ( udid , index )
setTimeout ( ( ) => {
continueAfterReset ( udid , index )
} , 5000 ) // ← 一步到位:恢复并在 1.5s 重试
}
// createTaskQueue(index).next(); // 继续队列中下一个任务
}
@@ -903,7 +1057,7 @@ const { open: openDiscovery } = useDeviceDiscovery({
initCanvas ,
initVideoStream ,
wsActionsRef : ( ) => wsActions ,
td
td ,
} )
// 鼠标按下事件处理
@@ -1108,6 +1262,8 @@ onUnmounted(() => {
console . log ( "卸载组件" ) ;
td . disposeAll ( 'logout' )
cloesMonitor ( ) ; //关闭检测消息
if ( scheduleTimer ) clearInterval ( scheduleTimer )
} ) ;
//获取设备信息
@@ -1157,10 +1313,69 @@ async function PrivatetexToPrivatePush(udid, index) {
//重置当前应用
async function resetApp ( udid , index ) {
createTaskQueue ( index ) . clear ( ) ; //清除队伍中的任务
wsActions . open ( udid , index )
await sleep ( 1000 ) ; //等待1秒
await sendWsTask ( index , { udid , action : 'killNow' } ) ;
await sendWsTask ( index , { udid , action : 'openDY' } ) ;
continueAfterReset ( udid , index )
}
// //发送评论字符到手机方法
// function setComText(index) {
// isSend.value = true;
// setTimeout(() => {
// isSend.value = false;
// }, 300);
// console.log('发送评论内容', index, textContent.value[index])
// wsActions.setClipboard(deviceInformation.value[index].udid, index, textContent.value[index], "ComText")
// if (runType.value === 'follow') {
// textContent.value[index] = getContentList()[index][getRandomNumber(getContentList()[index].length - 1)];
// }
// }
// //发送主播ID字符到手机方法
// function setHostId(index) {
// isSend.value = true;
// setTimeout(() => {
// isSend.value = false;
// }, 300);
// const host = markFirstFalseAsTrue(getHostList())
// if (host == null) {
// createTaskQueue(index).clear();//清除队伍中的任务
// ElMessage.success('主播ID已全部发送完毕');
// return;
// }
// hostIdArr.value[index] = host;
// // wslist[index].send(setClipboard(host.text)); //发送内容
// wsActions.setClipboard(deviceInformation.value[index].udid, index, host.text, "id")
// }
// //发送私信字符到手机方法
// function setPrivateText(index) {
// isSend.value = true;
// setTimeout(() => {
// isSend.value = false;
// }, 300);
// console.log('发送私信内容', index, textContentpri.value[index])
// //如果是在关注主播中,发送的开场白进行对应国家翻译
// if (runType.value === 'follow') {
// translation({ msg: getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)], country: hostIdArr.value[index].country }).then(res => {
// console.log(res)
// textContentpri.value[index] = res;
// // wslist[index].send(setClipboard(textContentpri.value[index]));
// wsActions.setClipboard(deviceInformation.value[index].udid, index, textContentpri.value[index], "Private")
// })
// } else {
// // wslist[index].send(setClipboard(textContentpri.value[index]));
// wsActions.setClipboard(deviceInformation.value[index].udid, index, textContentpri.value[index], "Private")
// if (getContentpriList()[index]) {
// textContentpri.value[index] = getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)];
// }
// }
// }
// 发送评论字符到手机方法
function setComText ( index ) {
isSend . value = true ;
@@ -1168,7 +1383,7 @@ function setComText(index) {
isSend . value = false ;
} , 300 ) ;
console . log ( '发送评论内容' , index , textContent . value [ index ] )
wsActions . setClipboard ( deviceInformation . value [ index ] . udid , index , textContent . value [ index ] , "ComText" )
wslist [ index ] . send ( setClipboard ( textContent . value [ index ] ) ) ;
if ( runType . value === 'follow' ) {
textContent . value [ index ] = getContentList ( ) [ index ] [ getRandomNumber ( getContentList ( ) [ index ] . length - 1 ) ] ;
}
@@ -1187,8 +1402,8 @@ function setHostId(index) {
return ;
}
hostIdArr . value [ index ] = host ;
// wslist[index].send(setClipboard(host.text)); //发送内容
wsActions . setClipboard ( deviceInformation . value [ index ] . udid , index , host . text , "id" )
wslist[ index ] . send ( setClipboard ( host . text ) ) ; //发送内容
}
@@ -1204,19 +1419,16 @@ function setPrivateText(index, datatype) {
translation ( { msg : getContentpriList ( ) [ index ] [ getRandomNumber ( getContentpriList ( ) [ index ] . length - 1 ) ] , country : hostIdArr . value [ index ] . country } ) . then ( res => {
console . log ( res )
textContentpri . value [ index ] = res ;
// wslist[index].send( setClipboard( textContentpri.value[index]));
wsActions . setClipboard ( deviceInformation . value [ index ] . udid , index , textContentpri . value [ index ] , "Private" )
wslist[ index ] . send ( setClipboard( textContentpri. value [ index ] ) ) ;
} )
} else {
// wslist[index].send( setClipboard( textContentpri.value[index]));
wsActions . setClipboard ( deviceInformation . value [ index ] . udid , index , textContentpri . value [ index ] , "Private" )
wslist[ index ] . send ( setClipboard( textContentpri. value [ index ] ) ) ;
if ( getContentpriList ( ) [ index ] ) {
textContentpri . value [ index ] = getContentpriList ( ) [ index ] [ getRandomNumber ( getContentpriList ( ) [ index ] . length - 1 ) ] ;
}
}
}
//获取手机粘贴板方法
function getText ( index ) {
wslist [ index ] . send ( getClipboard ( ) ) ;
@@ -1280,7 +1492,10 @@ function sendWsTask(index, data) {
}
//发送私信的文本粘贴事件
if ( data . type == 'PrivatePush' || data . type == 'PrivatePushFollow' ) {
setTimeout ( ( ) => {
setPrivateText ( index , data . type )
} , 500 )
}
//关注前的返回和右滑
if ( data . type == 'Attention' ) {
@@ -1376,6 +1591,9 @@ function stop() {
isStop . value = true ; //停止所有任务
isMsgPop . value = false ; //关闭爬虫sse任务
// —— 暂停调度,防止它又切回来 ——
scheduleEnabled . value = false
deviceInformation . value . forEach ( ( item , i ) => {
console . log ( '停止' , i ) ;
createTaskQueue ( i ) . clear ( ) ; //清除队伍中的任务
@@ -1585,7 +1803,84 @@ function printCurrentTime() {
return now . toLocaleString ( )
}
//中途出错 → 重置应用 → 根据当前模式自动续跑同一类任务
function continueAfterReset ( udid , index ) {
console . error ( "请求重试" , runType . value )
const dev = deviceInformation . value [ index ] ;
if ( ! dev ) return ;
const curUdid = dev . udid ;
if ( runType . value === 'follow' ) {
if ( isMonitor . value ) {
wsActions . getmesNum ( curUdid , index ) ;
} else {
LikesToLikesToLikes ( curUdid , index ) ;
}
} else if ( runType . value === 'like' ) {
wsActions . isHost ( curUdid , index ) ;
setTimeout ( ( ) => randomSeeVideo ( curUdid , index ) , 1000 ) ;
} else if ( runType . value === 'brushLive' ) {
wsActions . toLive ( curUdid , index ) ;
} else if ( runType . value === 'listen' || isMonitorOn . value ) {
resumeAndKick ( index ) ;
}
}
function runTask ( key ) {
if ( ! scheduleEnabled . value ) return
console . log ( '[schedule] 切换到任务:' , key )
forceActivate ( key , ( ) => {
if ( key === 'follow' ) {
runType . value = 'follow'
// 这三行保持你现有的唤起流程( 弹“主播ID”输入等)
// showDialog.value = true
// dialogTitle.value = '主播ID'
// selectedDevice.value = 999
resetTk ( )
} else if ( key === 'like' ) {
runType . value = 'like'
resetTk ( )
} else if ( key === 'brushLive' ) {
runType . value = 'brushLive'
resetTk ( )
} else if ( key === 'listen' ) {
runType . value = 'listen'
isMonitorOn . value = true
resetTk ( )
}
} )
}
function startScheduleLoop ( ) {
// 先按照当前 index 跑一次,保证“即刻对齐”
runTask ( schedulePlan [ scheduleState . index ] . key )
// 清理旧轮询,防止重复
if ( scheduleTimer ) clearInterval ( scheduleTimer )
scheduleTimer = setInterval ( ( ) => {
if ( ! scheduleEnabled . value ) return
const now = Date . now ( )
const cur = schedulePlan [ scheduleState . index ]
const elapsed = now - scheduleState . startTime
if ( elapsed >= cur . duration ) {
// 进入下一个时间片
scheduleState . index = ( scheduleState . index + 1 ) % schedulePlan . length
scheduleState . startTime = now
localStorage . setItem ( 'SCHEDULE_STATE' , JSON . stringify ( scheduleState ) )
runTask ( schedulePlan [ scheduleState . index ] . key )
}
} , scheduleTickMs )
}
function forceActivate ( key , runner ) {
// 跳过互斥逻辑,直接切换
runType . value = key ;
if ( typeof runner === 'function' ) runner ( ) ;
}
< / script >