提升稳定性

This commit is contained in:
2025-09-01 14:42:04 +08:00
parent 3a7c5556fd
commit 1666d9aa14
10 changed files with 139 additions and 41 deletions

33
package-lock.json generated
View File

@@ -11,6 +11,7 @@
"@ffmpeg/core": "^0.12.10",
"@ffmpeg/util": "^0.12.2",
"@vueuse/core": "^13.1.0",
"amqplib": "^0.10.9",
"axios": "^1.8.4",
"core-js": "^3.8.3",
"echarts": "^5.6.0",
@@ -4466,6 +4467,18 @@
"ajv": "^6.9.1"
}
},
"node_modules/amqplib": {
"version": "0.10.9",
"resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.9.tgz",
"integrity": "sha512-jwSftI4QjS3mizvnSnOrPGYiUnm1vI2OP1iXeOUz5pb74Ua0nbf6nPyyTzuiCLEE3fMpaJORXh2K/TQ08H5xGA==",
"dependencies": {
"buffer-more-ints": "~1.0.0",
"url-parse": "~1.5.10"
},
"engines": {
"node": ">=10"
}
},
"node_modules/ansi-escapes": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
@@ -4974,6 +4987,11 @@
"dev": true,
"license": "MIT"
},
"node_modules/buffer-more-ints": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz",
"integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg=="
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -11882,6 +11900,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -12153,7 +12176,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true,
"license": "MIT"
},
"node_modules/resolve": {
@@ -13466,6 +13488,15 @@
"punycode": "^2.1.0"
}
},
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View File

@@ -10,6 +10,7 @@
"@ffmpeg/core": "^0.12.10",
"@ffmpeg/util": "^0.12.2",
"@vueuse/core": "^13.1.0",
"amqplib": "^0.10.9",
"axios": "^1.8.4",
"core-js": "^3.8.3",
"echarts": "^5.6.0",

View File

@@ -36,6 +36,7 @@ const hoverIndex = ref(null)
}
.left-button {
cursor: default;
position: relative;
z-index: 999;
margin-bottom: 19px;

View File

@@ -11,7 +11,8 @@ export function createTaskQueue(index) {
q.push(task);
if (q.length === 1) task(); // 只有第一个任务时立即执行
},
next() {
next(type, time) {
console.log('任务发送', index, type, time);
const q = _queues.get(index) || [];
q.shift();
if (q.length > 0) q[0](); // 执行下一个

View File

@@ -142,7 +142,8 @@ video {
.app-button {
// background-color: darkcyan;
// color: white;
// color: white;
cursor: default;
width: 260px;
height: 50px;
background: linear-gradient(0deg, #4FCACD 0%, #5FDBDE 100%);

View File

@@ -18,7 +18,7 @@ let baseURL = ''
if (process.env.NODE_ENV === 'development') {
// 生产环境
// baseURL = "https://api.tkpage.yolozs.com"
// baseURL = "http://192.168.1.155:8101"
// baseURL = "http://192.168.1.174:8101"
baseURL = "https://crawlclient.api.yolozs.com"
} else {
// 测试环境

View File

@@ -17,7 +17,9 @@ export function connectSSE(url, onMessage) {
}
eventSource.onmessage = (event) => {
console.log('[SSE] 收到消息:', event)
try {
const data = JSON.parse(event.data)
if (onMessage) onMessage(data)
} catch (e) {

View File

@@ -16,7 +16,7 @@ const mouseData = {
export function createWsActions(wslist) {
// 通用 ws 发送方法
function send(index, payload) {
console.log("发送任务", payload.type)
// console.log("发送任务", payload.type)
if (wslist[index]) {
setTimeout(() => {
@@ -32,11 +32,15 @@ export function createWsActions(wslist) {
open: (udid, index) => send(index, { udid, action: 'openDY' }), //打开tk
killNow: (udid, index) => send(index, { udid, action: 'killNow' }), //关闭当前进程
install: (udid, index, path) => send(index, { udid, action: 'install', resourceId: path }), //安装应用
installc: (udid, index) => send(index, { udid, action: 'installt', resourceId: 'clipper.apk' }), //安装应用clipper
startClipserve: (udid, index) => send(index, { udid, action: 'startClipserve' }), //安装应用clipper
installt: (udid, index) => send(index, { udid, action: 'installt', resourceId: 'tiktok-39-3-3.apk' }), //安装应用 tiktok
pushFile: (udid, index, path) => send(index, { udid, action: 'pushFile', resourceId: path }), //发送文件
slideDown: (udid, index) => send(index, { udid, action: 'slideDown' }),//下滑动视频
slideUp: (udid, index) => send(index, { udid, action: 'slideUp' }),//上滑动视频
slideRight: (udid, index) => send(index, { udid, action: 'slideRight' }),//右滑动视频
getSize: (udid, index) => send(index, { udid, action: 'getSize', index }),//右滑动视频
setClipboard: (udid, index, text, type) => send(index, { udid, action: 'setClipboard', type: type, index, resourceId: text }), //截屏测试
clickLikes: (udid, index) => send(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' }),//点赞
clickComment: (udid, index) => send(index, { udid, action: 'click', type: 'Comment', index, resourceId: 'com.zhiliaoapp.musically:id/cvd' }),//打开评论
clickComtext: (udid, index) => send(index, { udid, action: 'click', type: 'Comtext', index, resourceId: 'com.zhiliaoapp.musically:id/cs0' }),//点开输入框

View File

@@ -1,5 +1,5 @@
<template>
<div class="main">
<div class="main-home">
<div class="container">
<div class="right">
<img src="../assets/logoBg.png" class="background-video" alt="">
@@ -79,7 +79,7 @@ import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/stores/
import { ElLoading, ElMessage } from 'element-plus';
let version = ref('1.5.5');
let version = ref('1.5.8(测试版)');
onMounted(() => {
@@ -123,7 +123,7 @@ const onSubmit = () => {
</script>
<style lang="less">
.main {
.main-home {
width: 100vw;
height: 100vh;
overflow: hidden;

View File

@@ -23,7 +23,7 @@
</canvas>
</div>
<div class="input-info" v-show="selectedDevice == index"
:style="{ left: phone.width * 1.4 + 4 + '0px', transform: getTransformStyle(index), }">
:style="{ left: (phone.width * 1.4 + 4) + 'px', transform: getTransformStyle(index), }">
<div class="app-button" @click="resetApp(device.udid, index)">重置应用</div>
<div class="app-button"
@@ -47,6 +47,11 @@
@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 class="app-button" @click="wsActions.isHost(device.udid, index)">一键养号</div> -->
</div>
</div>
@@ -92,9 +97,11 @@ import LeftToolbar from '@/components/LeftToolbar.vue' //左侧工具栏
import { useStreams } from '@/composables/useStreams' //视频流处理
import { useDeviceDiscovery } from '@/composables/useDeviceDiscovery' //设备发现
import { useTouch } from '@/composables/useTouch' //触摸事件
const router = useRouter();
let wsActions = null;
let userdata = getUser();
// 引入刷新方法
const reloadPage = inject("reload")
@@ -172,6 +179,8 @@ const KEY_LABEL = {
listen: '监测消息',
};
const showHostDlg = ref(false)
let loadingAll = null //遮罩
function onHostSaved(list) {
console.log('保存后的 HostList:', list)
}
@@ -473,6 +482,10 @@ const initVideoStream = async (udid, index) => {
setTimeout(() => {
wsActions.clickCopyText(resData.device, index)
}, 1500);
} else if (resData.type == 'setClipboard') {
console.log("发送", resData.text)
wslist[index].send(setClipboard(resData.text));
return;
} else if (resData.type == 'getmesNum') {
if (resData.message == 0) {
console.log('没有消息')
@@ -591,24 +604,19 @@ const initVideoStream = async (udid, index) => {
`[getSize] raw=${RAW_W}x${RAW_H} -> scaled=${scaledW}x${scaledH} (align↓${ALIGN}) ${iponeCoefficient.value[index].width} ${iponeCoefficient.value[index].height}`
);
} else {
console.log(resData.type, '坐标返回x:', resData.x, 'y:', resData.y);
// console.log(resData.type, '坐标返回x:', resData.x, 'y:', resData.y);
}
phoneXYinfo.value[index].id = resData.device
if (resData.type == 'Likes') {//判断是否是 点赞
phoneXYinfo.value[index].Likes = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
if (runType.value == 'follow') {
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
}
} else if (resData.type == 'Comment') {//打开评论
phoneXYinfo.value[index].Comment = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'CommentText') {//复制评论
phoneXYinfo.value[index].CommentText = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
textContent.value[index] = resData.message
} else if (resData.type == 'Comtext') {//评论输入
phoneXYinfo.value[index].Comtext = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'ComPush') {//评论发送
phoneXYinfo.value[index].ComPush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
setTimeout(() => {
Back('', index)
if (runType.value == 'follow') {
@@ -626,22 +634,16 @@ const initVideoStream = async (udid, index) => {
}
}, 800)
} else if (resData.type == 'tomy') {//打开主页
phoneXYinfo.value[index].tomy = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'Attention') {//关注、打开私信
phoneXYinfo.value[index].Attention = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
// LikesToCommentToComPush(deviceInformation.value[index].udid, index) //是否继续循环任务
} else if (resData.type == 'return') {//私信评论
phoneXYinfo.value[index].return = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'addHost') {//添加关注
phoneXYinfo.value[index].addHost = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
setTimeout(() => {
wsActions.isHost(deviceInformation.value[index].udid, index)//检测
}, 1000);
} else if (resData.type == 'Privatetex') {//私信评论
phoneXYinfo.value[index].Privatetex = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'PrivatePush' || resData.type == 'PrivatePushFollow') {//私信发送
phoneXYinfo.value[index].PrivatePush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
setTimeout(() => {
Back('', index);
setTimeout(() => {
@@ -682,11 +684,8 @@ const initVideoStream = async (udid, index) => {
}, 1000);
} else if (resData.type == 'clickCopy') {//点击复制
phoneXYinfo.value[index].clickCopy = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'hostVideo') {//观看主播视频
phoneXYinfo.value[index].hostVideo = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
} else if (resData.type == 'isHost') {//视频关注主播
phoneXYinfo.value[index].isHost = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
if (resData.message == 0) {
console.log('无关注', index)
Back(deviceInformation.value[index].udid, index)
@@ -766,14 +765,34 @@ const initVideoStream = async (udid, index) => {
if (resData.type != 'isHost') {
if (resData.type == 'hostVideo' || resData.type == 'Likes') {
setTimeout(() => {
createTaskQueue(index).next(); // 继续队列中下一个任务
createTaskQueue(index).next(resData.type, printCurrentTime()); // 继续队列中下一个任务
}, 5000)
} else if (resData.type == 'getmesNum') {
} else {
createTaskQueue(index).next(); // 继续队列中下一个任务
createTaskQueue(index).next(resData.type, printCurrentTime()); // 继续队列中下一个任务
}
}
} else if (resData.status === 'install') {
if (resData.message == '正在安装...') {
console.log("传输完成")
loadingAll.close()
console.log("正在安装...")
} else if (resData.message == '安装成功') {
if (resData.apkName == 'clipper.apk') {
wsActions.startClipserve(deviceInformation.value[index].udid, index)
}
} else if (resData.message === 500) {
ElMessageBox.confirm('请勾选读取/写入剪贴板权限后确认')
} else if (resData.message === 400) {
ElMessage.error("请先安装粘贴工具");
} else {
console.error(resData.message, resData.type); // 错误处理
ElMessage.error(resData.message);
}
} else {
// ----------------------------------------------------------------------------------------------------报错处理
//如果该视频无法被评论,或者没有评论,返回刷下一条视频
@@ -829,6 +848,10 @@ const initVideoStream = async (udid, index) => {
//如果无法获取到聊天记录,返回继续检测
console.error('未找到聊天,返回')
Back('', index)
setTimeout(() => {
Back('', index)
resumeAndKick(index); // ← 一步到位:恢复并在 1.5s 后补一次 getmesNum
}, 1000)
} else if (resData.type == 'clickSysMesage') {
//如果没有系统消息,则点击新消息
@@ -960,6 +983,7 @@ onMounted(() => {
// })
ObtainDeviceInformation();
window.electronAPI.startMq(userdata.tenantId)
// window.addEventListener('keydown', (e) => {
// // console.log('触发按键了 键盘事件有效', e)
// if (e.key == 'Backspace') {
@@ -971,13 +995,18 @@ onMounted(() => {
// if (e.key == 'Backspace') {
// key(selectedDevice.value, 'up', 67)
// }
// })
// })
const loading = ElLoading.service({
lock: true,
text: '初始化中...',
background: 'rgba(0, 0, 0, 0.7)',
})
// 如果没有hostList则初始化为空数组
if (!getHostList()) {
setHostList([])
}
// reloadPage()
setTimeout(() => {
loading.close()
@@ -985,7 +1014,7 @@ onMounted(() => {
}, 2000)
//sse接收爬虫发送的消息
const es = connectSSE(`https://datasave.api.yolozs.com/api/sse/connect/${userdata.tenantId}/${userdata.id}`, (data) => {
const es = connectSSE(`http://localhost:3311/events`, (data) => {
// connectSSE(`http://192.168.1.155:19665/api/sse/connect/${userdata.tenantId}/${userdata.id}`, (data) => {
// 处理服务端推送的数据
console.log('来自服务端:', data)
@@ -1011,6 +1040,7 @@ onMounted(() => {
message: '任务开启成功',
})
addToHostList(stroageHost.value)
stroageHost.value = []
//重启tk
resetTk()
//获取评论
@@ -1045,10 +1075,12 @@ onMounted(() => {
})
}
} else {
stroageHost.value = getHostList()
stroageHost.value.push(({ country: data.country, text: data.hostsId, state: false }))
// stroageHost.value = getHostList()
if (runType.value == 'follow') {
addToHostList([{ country: data.country, text: data.hostsId, state: false }])
} else {
stroageHost.value.push(({ country: data.country, text: data.hostsId, state: false }))
}
}
@@ -1067,8 +1099,8 @@ onMounted(() => {
// })
onBeforeUnmount(() => {
// document.removeEventListener("visibilitychange", handleVisibilityChange);
onBeforeUnmount(async () => {
// await rabbitmqDirectService.closeConnection();
});
// 组件卸载时清理
@@ -1136,7 +1168,7 @@ function setComText(index) {
isSend.value = false;
}, 300);
console.log('发送评论内容', index, textContent.value[index])
wslist[index].send(setClipboard(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)];
}
@@ -1155,8 +1187,8 @@ function setHostId(index) {
return;
}
hostIdArr.value[index] = host;
wslist[index].send(setClipboard(host.text)); //发送内容
// wslist[index].send(setClipboard(host.text)); //发送内容
wsActions.setClipboard(deviceInformation.value[index].udid, index, host.text, "id")
}
@@ -1172,10 +1204,12 @@ 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]));
// 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]));
// 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)];
}
@@ -1216,7 +1250,7 @@ const reload = (opts = {}) => {
//发送任务前的处理
function sendWsTask(index, data) {
console.log('任务等待中', data.type);
console.log('任务等待中', index, data.type, printCurrentTime());
return new Promise((resolve) => {
try {
const queue = createTaskQueue(index);
@@ -1286,7 +1320,7 @@ function getRandomNumber(n) {
return Math.floor(Math.random() * (n + 1));
}
//延迟30-50秒后检测关注
//延迟10-30秒后检测关注
function randomSeeVideo(udid, index) {
const delay = Math.floor(Math.random() * (50 - 30) + 10) * 1000;
playTimer.value[index] = setTimeout(() => {
@@ -1351,7 +1385,7 @@ function stop() {
//重置当前状态
runType.value = ''
//清除观看视频定时器
clearInterval(playTimer.value[i])
clearTimeout(playTimer.value[i])
playTimer.value[i] = null;//清除定时器
})
@@ -1371,6 +1405,20 @@ function resetTk() {
})
}
function installt(udid, index, type) {
if (type) {
wsActions.installt(udid, index)
} else {
wsActions.installc(udid, index)
}
loadingAll = ElLoading.service({
lock: true,
text: '正在传输...',
background: 'rgba(0, 0, 0, 0.7)',
})
}
//关闭监听
function cloesMonitor() {
@@ -1491,7 +1539,9 @@ function getTransformStyle(index) {
function manualGc() {
window.electronAPI.manualGc()
}
function mqSend() {
window.electronAPI.mqSend("start")
}
async function uploadLogFile() {
try {
// 先弹出确认框
@@ -1529,6 +1579,13 @@ async function uploadLogFile() {
}
}
}
//当前时间获取
function printCurrentTime() {
const now = new Date();
return now.toLocaleString()
}
</script>