yolo助手AI ui 1.5.0

This commit is contained in:
2025-08-07 21:35:27 +08:00
parent a92c164af1
commit 85e399bf96
33 changed files with 888 additions and 990 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

BIN
src/assets/video/leftBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 902 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/assets/video/mainBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -1,7 +1,10 @@
<template>
<div v-if="visible" class="dialog-overlay" @click.self="close">
<div class="dialog-content">
<h3 class="text-lg font-bold mb-4">最近一条的消息翻译</h3>
<h3 class="text-lg font-bold mb-4">
<img style="margin: 0px 15px;" src="@/assets/video/chatMes.png"></img>
最近一条的消息翻译
</h3>
<el-scrollbar class="chat-box">
<div v-for="(msg, index) in messages" :key="index"
:class="msg.position === 'left' ? 'left-message' : 'right-message'">
@@ -126,4 +129,10 @@ function fallbackCopyTextToClipboard(index, text) {
border-radius: 6px;
cursor: pointer;
}
.center-justify {
display: flex;
justify-content: space-around;
align-items: center;
}
</style>

View File

@@ -1,107 +0,0 @@
<template>
<el-dialog draggable :title="title" v-model="visibleLocal" width="600px" @close="handleCancel">
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
// 定义接收的 props
const props = defineProps({
/** 对话框可见性,外部通过 v-model:visible 绑定 */
visible: {
type: Boolean,
required: true,
},
/** 对话框标题 */
title: {
type: String,
default: '',
},
/** 文本框初始内容,可选 */
initialText: {
type: String,
default: '',
},
/** 文本框行数 */
type: {
type: Number,
default: 10,
},
/** index */
index: {
type: Number,
default: 999,
},
/** 文本框占位符 */
placeholder: {
type: String,
default: '每行一条,支持粘贴多行后自动拆分',
},
/** 是否去重,默认 true */
dedupe: {
type: Boolean,
default: true,
},
});
// 定义 emits
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
// 本地 rawText用于绑定 textarea
const rawText = ref(props.initialText);
// 当 props.initialText 变化时,更新 rawText
watch(
() => props.initialText,
(newVal) => {
rawText.value = newVal;
}
);
// 计算属性,用于 v-model:visible 绑定 el-dialog
const visibleLocal = computed({
get() {
return props.visible;
},
set(val) {
emit('update:visible', val);
},
});
/** 解析 rawText 为数组按行拆分trim去空去重如 dedupe=true */
function parseLines() {
const lines = rawText.value
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line.length > 0);
if (props.dedupe) {
return Array.from(new Set(lines));
}
return lines;
}
/** 点击确定按钮 */
function handleConfirm() {
const items = parseLines();
emit('confirm', items, props.title, props.index);
// 关闭对话框
emit('update:visible', false);
rawText.value = '';
}
/** 点击取消或对话框关闭 */
function handleCancel() {
emit('update:visible', false);
emit('cancel');
}
</script>
<style scoped>
/* 可根据项目风格调整 */
</style>

View File

@@ -3,6 +3,9 @@
<el-input type="textarea" v-model="rawText" :rows="10" :placeholder="placeholder" clearable></el-input>
<template #footer>
<span v-if="title == '私信'">自动回复
<el-switch style="margin-right: 20px;" v-model="value1" />
</span>
<el-button v-if="title !== '主播ID'" type="success" @click="exportPrologue(title)">导入{{ title }}</el-button>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
@@ -13,7 +16,7 @@
<script setup>
import { ref, computed, watch } from 'vue';
import { prologue, comment } from '@/api/account';
let value1 = ref(false);
// 定义接收的 props
const props = defineProps({
/** 对话框可见性,外部通过 v-model:visible 绑定 */
@@ -92,7 +95,7 @@ function parseLines() {
/** 点击确定按钮 */
function handleConfirm() {
const items = parseLines();
emit('confirm', items, props.title, props.index);
emit('confirm', items, props.title, props.index, value1.value);
// 关闭对话框
emit('update:visible', false);
rawText.value = '';

View File

@@ -1,107 +0,0 @@
<template>
<el-dialog draggable :title="title" v-model="visibleLocal" width="600px" @close="handleCancel">
<el-input type="textarea" v-model="rawText" :rows="10" :placeholder="placeholder" clearable></el-input>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, computed, watch } from 'vue';
// 定义接收的 props
const props = defineProps({
/** 对话框可见性,外部通过 v-model:visible 绑定 */
visible: {
type: Boolean,
required: true,
},
/** 对话框标题 */
title: {
type: String,
default: '',
},
/** 文本框初始内容,可选 */
initialText: {
type: String,
default: '',
},
/** 文本框行数 */
type: {
type: Number,
default: 10,
},
/** index */
index: {
type: Number,
default: 999,
},
/** 文本框占位符 */
placeholder: {
type: String,
default: '每行一条,支持粘贴多行后自动拆分',
},
/** 是否去重,默认 true */
dedupe: {
type: Boolean,
default: true,
},
});
// 定义 emits
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
// 本地 rawText用于绑定 textarea
const rawText = ref(props.initialText);
// 当 props.initialText 变化时,更新 rawText
watch(
() => props.initialText,
(newVal) => {
rawText.value = newVal;
}
);
// 计算属性,用于 v-model:visible 绑定 el-dialog
const visibleLocal = computed({
get() {
return props.visible;
},
set(val) {
emit('update:visible', val);
},
});
/** 解析 rawText 为数组按行拆分trim去空去重如 dedupe=true */
function parseLines() {
const lines = rawText.value
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line.length > 0);
if (props.dedupe) {
return Array.from(new Set(lines));
}
return lines;
}
/** 点击确定按钮 */
function handleConfirm() {
const items = parseLines();
emit('confirm', items, props.title, props.index);
// 关闭对话框
emit('update:visible', false);
rawText.value = '';
}
/** 点击取消或对话框关闭 */
function handleCancel() {
emit('update:visible', false);
emit('cancel');
}
</script>
<style scoped>
/* 可根据项目风格调整 */
</style>

View File

@@ -18,7 +18,7 @@ app.use(store); // 注册 store
app.use(router);
app.config.globalProperties.Buffer = Buffer; // 注册 Buffer
window.addEventListener('unhandledrejection', event => event.preventDefault());
window.addEventListener('error', event => event.preventDefault()); // 阻止错误和未处overlay理的 Promise 拒绝事件冒泡到 window 对象
// window.addEventListener('unhandledrejection', event => event.preventDefault());
// window.addEventListener('error', event => event.preventDefault()); // 阻止错误和未处overlay理的 Promise 拒绝事件冒泡到 window 对象
app.mount('#app');

View File

@@ -8,26 +8,39 @@ body {
width: 100vw;
height: 100vh;
background: #222;
background-image: url('../../assets/video/mainBg.png');
background-size: 100% 100%;
/* 或其他适合的值例如contain */
background-position: center;
background-repeat: no-repeat;
}
.left {
background: #191c23;
background-image: url('../../assets/video/leftBg.png');
background-size: 100% 100%;
/* 或其他适合的值例如contain */
background-position: center;
background-repeat: no-repeat;
width: 20vw;
box-sizing: content-box;
box-sizing: border-box;
box-shadow: 0px 0px 10px #b3b3b3;
border-radius: 0px 40px 40px 0px;
padding: 53px 31px;
}
.content {
width: 50vw;
width: 60vw;
display: grid;
grid-template-columns: repeat(3, minmax(160px, 320px));
padding: 0 5vw;
/* 每行 3 个,宽度自适应 */
/* gap: 10px; */
}
.right {
width: 30vw;
background-color: #272727;
// background-color: #272727;
}
.video-container {
@@ -52,6 +65,10 @@ body {
background-color: #424242;
position: absolute;
z-index: 10;
padding: 15px;
background: linear-gradient(0deg, #EEFFFF 0%, #FFFFFF 100%);
border-radius: 12px;
box-shadow: 4px 3px 14px 2px rgba(174, 174, 174, 0.5)
}
}
@@ -122,13 +139,69 @@ video {
}
.el-button {
width: 200px;
margin: 20px;
.app-button {
// background-color: darkcyan;
// color: white;
width: 260px;
height: 50px;
background: linear-gradient(0deg, #4FCACD 0%, #5FDBDE 100%);
border-radius: 10px;
display: flex;
justify-content: space-around;
align-items: center;
position: relative;
z-index: 999;
font-family: Source Han Sans SC;
font-weight: 500;
font-size: 20px;
color: #FFFFFF;
line-height: 16px;
margin: 12px;
}
/* 鼠标按下时效果 */
.app-button:active {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
transform: translateY(1px);
}
.left-button {
position: relative;
z-index: 999;
margin-bottom: 19px;
width: 100%;
height: 72px;
// background: #32C9CD;
border-radius: 10px;
font-family: Source Han Sans SC;
font-weight: 800;
font-size: 20px;
color: #7A8B97;
line-height: 16px;
align-items: center;
display: flex;
align-items: center;
img {
width: 30px;
margin: 20px;
}
}
.left-button:hover {
background: #32C9CD;
color: #F9FAFE;
}
/* 鼠标按下时效果 */
.left-button:active {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
transform: translateY(1px);
}
.center-justify {

View File

@@ -43,6 +43,8 @@ export function setphoneXYinfo(data) {
export function getphoneXYinfo() {
return JSON.parse(localStorage.getItem('XYinfo'));
}
// 用于获取主播信息
export function getHostList() {
return JSON.parse(localStorage.getItem('hostList'));
@@ -51,6 +53,23 @@ export function getHostList() {
export function setHostList(data) {
localStorage.setItem('hostList', JSON.stringify(data));
}
export function clearHostList() {
// 清空存储的数组
localStorage.setItem('hostList', JSON.stringify([]));
}
export function addToHostList(newItem) {
// 获取当前的数组
const currentList = JSON.parse(localStorage.getItem('hostList') || '[]');
// 向数组添加新元素
currentList.push(newItem);
// 更新存储的数组
localStorage.setItem('hostList', JSON.stringify(currentList));
}
// 用于获取私信信息
export function getContentpriList() {
@@ -72,12 +91,11 @@ export function setContentList(data) {
localStorage.setItem('Content', JSON.stringify(data));
}
// 用于绘画信息
// export function setContentList(data) {
// sessionStorage.setItem('Content', JSON.stringify(data));
// }
export function setsessionId(data) {
sessionStorage.setItem('sessionList', JSON.stringify(data));
}
// // 用于获取评论信息
// export function getContentList() {
// const arr = JSON.parse(sessionStorage.getItem('Content'))
// return [arr, arr, arr, arr, arr, arr, arr, arr];
// }
// 用于获取评论信息
export function getsessionId() {
return JSON.parse(sessionStorage.getItem('sessionList'));
}

View File

@@ -3,7 +3,7 @@
* https://rudon.blog.csdn.net/
*/
import axios from 'axios'
import { getToken, getUser } from '@/utils/storage'
import { getToken, getUser } from '@/stores/storage'
import router from '@/router'
import { ElMessage } from 'element-plus';

View File

@@ -1,12 +1,23 @@
// src/utils/wsActions.js
import { toBuffer } from '@/utils/bufferUtils';
const mouseData = {
type: 2,
action: 0,
pointerId: 0,
position: {
point: { x: 0, y: 0 },
screenSize: { width: 320, height: 720 },
},
pressure: 1,
buttons: 1,
};
// 传入 wslist、isStopLike 等需要依赖的外部变量
export function createWsActions(wslist) {
// 通用 ws 发送方法
function send(index, payload) {
if (wslist[index]) {
setTimeout(() => {
mouseData.action = 1;
wslist[index].send(toBuffer(mouseData));
@@ -39,7 +50,7 @@ export function createWsActions(wslist) {
getmesNum: (udid, index) => send(index, { udid, action: 'dump', type: 'getmesNum', index, resourceId: 'com.zhiliaoapp.musically:id/jyv' }), //获取收件箱消息数量
clickMesage: (udid, index) => send(index, { udid, action: 'click', type: 'clickMesage', index, resourceId: 'com.zhiliaoapp.musically:id/e3_' }), //点击有消息的私信
clickSysMesage: (udid, index) => send(index, { udid, action: 'click', type: 'clickSysMesage', index, resourceId: 'com.zhiliaoapp.musically:id/j7s' }), //点击有消息的系统通知
// isVideoAndLive: (udid, index) => send(index, { udid, action: 'click', type: 'isVideoAndLive', index, resourceId: 'com.zhiliaoapp.musically:id/long_press_layout' }), //获取是视频还是直播
isVideoAndLive: (udid, index) => send(index, { udid, action: 'click', type: 'isVideoAndLive', index, resourceId: 'com.zhiliaoapp.musically:id/long_press_layout' }), //获取是视频还是直播
addHost: (udid, index) => send(index, { udid, action: 'click', type: 'addHost', index, resourceId: 'com.zhiliaoapp.musically:id/fuq' }), //视频页面的关注
isHost: (udid, index) => send(index, { udid, action: 'click', type: 'isHost', index, resourceId: 'com.zhiliaoapp.musically:id/fuq' }), //判断视频页面的关注
search: (udid, index) => send(index, { udid, action: 'click', type: 'search', index, resourceId: 'com.zhiliaoapp.musically:id/gtz' }), //搜索页面

View File

@@ -75,7 +75,7 @@
import { ref, reactive, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { login, getIdByName } from '@/api/account';
import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/utils/storage';
import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/stores/storage';
import { ElLoading, ElMessage } from 'element-plus';

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +1,18 @@
<template>
<div class="main">
<el-scrollbar class="left">
<div class=" center-line">
<!-- <el-button class="open" @click="wsActions.open(device.udid, index)"></el-button>
<el-button class="Back" @click="Back(device.udid, index)"></el-button>
<el-button class="Home" @click="Home(device.udid, index)"></el-button>
<el-button class="Overview" @click="Overview(device.udid, index)"></el-button> -->
<!-- <el-button @click="play(device.udid, index)">play</el-button> -->
<!-- <el-button class="open" @click="slideDown(device.udid, index)"></el-button>
<el-button class="open" @click="slideUp(device.udid, index)"></el-button>
<el-button class="open" @click="clickLike(device.udid, index)"></el-button> -->
<div></div>
<!-- <el-button @click="clickLikes(device.udid, index)">点赞</el-button> -->
<!-- <el-button @click="stopLike(index)">停止点赞</el-button> -->
<!-- <div></div>
<el-button @click="clickComment(device.udid, index)">评论</el-button>
<el-button @click="clickComtext(device.udid, index)">评论框</el-button>
<el-button @click="clickComPush(device.udid, index)">发布评论</el-button>
<div></div>
<el-button @click="clicktomy(device.udid, index)">主页</el-button> -->
<!-- <el-button @click="wsActions.clickAttention(device.udid, index)">关注/私信</el-button> -->
<!-- <div></div>
<el-button @click="clickPrivatetext(device.udid, index)">私信输入</el-button>
<el-button @click="clickPrivatePush(device.udid, index)">私信发送</el-button> -->
<el-button type="warning" @click="reload()">刷新</el-button>
<!-- <el-button type="warning" @click="opentanchuan()">123</el-button> -->
<div></div>
<!-- <el-button @click="wsActions.clickCopy(device.udid, index)">找私信</el-button> -->
<!-- <el-button @click="wsActions.clickCopyList(device.udid, index)">私信列表</el-button> -->
<div></div>
<!-- <el-button @click="wsActions.getmesNum(device.udid, index)">获取收件箱</el-button> -->
<!-- <el-button @click="wsActions.getSize(device.udid, index)">获取屏幕尺寸</el-button> -->
<!-- <el-button @click="wsActions.slideRight(device.udid, index)">右滑</el-button> -->
<!-- <el-button @click="wsActions.isHost(device.udid, index)">一键养号</el-button> -->
<el-button type="success" @click="openTk()">打开tiktok</el-button>
<el-button type="success" @click="resetTk()">重置tiktok</el-button>
<el-button type="success" @click="brushLive()">打开直播</el-button>
<el-button :type="runType[0] == 'like' ? 'danger' : 'success'" @click="parentNum()">{{ runType[0] == 'like' ?
'养号中' : '一键养号' }}</el-button>
<el-button type="success"
@click="showDialog = true; dialogTitle = '主播ID'; selectedDevice = 999">一键关注并打招呼</el-button>
<el-button type="success" v-if="!isShowMes" @click="openMonitor()">开启监测消息</el-button>
<el-button type="danger" v-else @click="cloesMonitor()">关闭监测消息</el-button>
<el-button type="danger" @click="stop()">全部停止</el-button>
<el-button type="danger" @click="router.push('/')">登出</el-button>
<div></div>
<!-- <div style="display: flex;">
<div style="width: 150px;">主播id</div>
<el-input style="border: 1px solid #000;" v-model="hostIdContent[index]" type="text"></el-input>
<el-button @click="setHostId(index)">发送</el-button>
</div>
<div style="display: flex;">
<div style="width: 150px;">评论内容</div>
<el-input style="border: 1px solid #000;" v-model="textContent[index]" type="text"></el-input>
<el-button @click="setComText(index)">发送</el-button>
</div> -->
<!-- <div style="display: flex;">
<div style="width: 150px;">私信内容</div>
<el-input style="border: 1px solid #000;" v-model="textContentpri[index]" type="text"></el-input>
<el-button @click="setPrivateText(index)">发送</el-button>
</div> -->
<div></div>
<!-- <el-button @click="getText(index)">获取粘贴板内容</el-button> -->
<div></div>
<!-- <el-button @click="wsActions.isVideoAndLive(device.udid, index)">判断视频还是直播</el-button> -->
<el-scrollbar class="left"> <!-- 左边栏 -->
<div class="center-line"> <!-- 左边栏按钮 -->
<div v-for="(btn, index) in buttons" :key="index" style="width: 100%;">
<div v-if="btn.show?.()" class="left-button" :style="{
backgroundColor: btn.label == '关闭监测消息' ? 'red' : '',
}" @click="btn.onClick" @mouseenter="hoverIndex = index" @mouseleave="hoverIndex = null">
<img :src="hoverIndex === index ? btn.img.hover : btn.img.normal" alt="">
{{ btn.label }}
</div>
</div>
</div>
</el-scrollbar>
<!-- 中间手机区域 -->
<div class="content" @click.self="selectedDevice = 999">
<div class="video-container" @click.self="selectedDevice = 999" v-for="(device, index) in deviceInformation"
:key="device.udid" @mouseup="(e) => handleCanvasup(device.udid, e, index)">
@@ -75,50 +21,42 @@
:style="getVideoStyle(index)" @click.stop="selectedDevice = index"></video>
<canvas class="canvas" v-show="selectedDevice == index" :ref="(el) => (canvasRef[device.udid] = el)"
@mousemove.stop="(e) => handleMouseMove(device.udid, e, index)"
@mousedown.stop="(e) => handleCanvasdown(device.udid, e, index)">
@mousedown.stop="(e) => handleCanvasdown(device.udid, e, index)" :style="{
transform: getTransformStyle(index)
}">
</canvas>
</div>
<div class="input-info" v-show="selectedDevice == index" :style="{ left: phone.width * 1.4 + 4 + '0px' }">
<!-- <div class="input-info" v-show="false"> -->
<!-- <el-button @click="showDialog = true; dialogTitle = '主播ID';">批量关注</el-button> -->
<div></div>
<!-- <el-button @click="showDialog = true; dialogTitle = '评论';">导入评论</el-button> -->
<div></div>
<el-button @click="getComArr(index, '评论')">查看评论</el-button>
<div></div>
<!-- <el-button @click="showDialog = true; dialogTitle = '私信';">导入私信</el-button> -->
<div></div>
<el-button @click="getComArr(index, '私信')">查看私信</el-button>
<!-- <el-button @click="wsActions.search(device.udid, index)">搜索</el-button> -->
<!-- <el-button @click="wsActions.getmesNum(device.udid, index)">检测消息</el-button> -->
<!-- <el-button @click="wsActions.clickMesage(device.udid, index)">进入消息</el-button> -->
<el-button @click="wsActions.clickSysMesage(device.udid, index)">进入消息</el-button>
<el-button @click="resetApp(device.udid, index)">重置应用</el-button>
<el-button
@click="wsActions.clickCopyList(device.udid, index); openShowChat = true; istranslate = true">翻译本页对话</el-button>
<!-- <el-button @click="wsActions.getSize(device.udid, index)">获取屏幕尺寸</el-button> -->
<div class="input-info" v-show="selectedDevice == index"
:style="{ left: phone.width * 1.4 + 4 + '0px', transform: getTransformStyle(index), }">
<div class="app-button" @click="resetApp(device.udid, index)">重置应用</div>
<div class="app-button"
@click="wsActions.clickCopyList(device.udid, index); openShowChat = true; istranslate = true">
翻译本页对话</div>
<div class="app-button" @click="wsActions.clickCopyList(device.udid, index); openShowChat = true;">
回复消息</div>
<!-- <div class="app-button" @click="wsActions.getSize(device.udid, index)">获取屏幕尺寸</div> -->
<div class="app-button" @click="wsActions.test(device.udid, index)">打印ui节点树</div>
<div class="app-button" @click="wsActions.isOneLive(device.udid, index)">判断单人还是双人</div>
<div class="app-button" @click="wsActions.slideDown(device.udid, index)">下滑</div>
<div class="app-button" @click="wsActions.killNow(device.udid, index)">关闭当前应用</div>
<div class="app-button" @click="chooseFile(device.udid, index, 1, wsActions)">安装 APK
文件</div>
<div class="app-button" @click="chooseFile(device.udid, index, 2, wsActions)">
传送文件</div>
<div style="display: flex;">
<el-input style="border: 1px solid #000;" v-model="textContent[index]" type="text"></el-input>
<el-button @click="setComText(index)">发送</el-button>
<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="setComText(index)">发送
</div>
</div>
<el-button @click="wsActions.test(device.udid, index)">打印ui节点树</el-button>
<el-button @click="wsActions.isOneLive(device.udid, index)">判断单人还是双人</el-button>
<el-button @click="wsActions.slideDown(device.udid, index)">下滑</el-button>
<el-button @click="wsActions.killNow(device.udid, index)">关闭当前应用</el-button>
<el-button @click="chooseFile(device.udid, index, 1, wsActions)">安装 APK 文件</el-button>
<el-button @click="chooseFile(device.udid, index, 2, wsActions)">传送文件</el-button>
<!-- <el-button @click="wsActions.isHost(device.udid, index)">一键养号</el-button> -->
<!-- <div class="app-button" @click="wsActions.isHost(device.udid, index)">一键养号</div> -->
</div>
</div>
<!--
<div class="video-container" @click.self="selectedDevice = 999" v-for="item in 4" :style="getVideoStyle()"
:class="{ 'bottom-row': item >= 2 }">
<div style="position: relative;box-sizing: border-box; ">
</div>
</div> -->
</div>
<div class="right">
<!-- <el-button @click="openShowChat = !openShowChat">聊天</el-button> -->
<div class="right" @click.self="selectedDevice = 999">
<div style="margin: 14px;"></div>
<ChatDialog :visible="openShowChat" :messages="chatList" />
</div>
<MultiLineInputDialog v-model:visible="showDialog" :initialText='""' :title="dialogTitle" :index="selectedDevice"
@@ -130,7 +68,12 @@
import { ref, onMounted, onUnmounted, onBeforeUnmount, watch, inject } from "vue";
import VideoConverter from "h264-converter";
import { useRouter } from 'vue-router';
import { setphoneXYinfo, getphoneXYinfo, getUser, getHostList, setHostList, getContentpriList, setContentpriList, getContentList, setContentList } from '@/utils/storage'
import {
setphoneXYinfo, getphoneXYinfo, getUser,
getHostList, setHostList, getContentpriList,
setContentpriList, getContentList, setContentList,
setsessionId, getsessionId
} from '@/stores/storage'
import { toBufferBtn, stringToUtf8ByteArray, getClipboard, setClipboard, bufferToString, startsWithHeader, trimLongArray, base64ToBinary, toBuffer } from '@/utils/bufferUtils';
import { createWsActions } from '@/utils/wsActions';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
@@ -162,7 +105,7 @@ let dialogTitle = ref('');
//评论文本内容
let textContent = ref(['', '', '', '', '', '', '', '']);
let textContentArr = ref([[], [], [], [], [], [], [], [], []]);
//主播id内容
//当前主播id内容
let hostIdArr = ref([{}, {}, {}, {}, {}, {}, {}, {}]);
// let hostIdContentArr = ref([[], [], [], [], [], [], [], [], []]);
//私信文本内容
@@ -185,6 +128,7 @@ let instanceList = ref([{}, {}, {}, {}, {}, {}, {}, {}]);
//是否是在关注主播
let runType = ref(['', '', '', '', '', '', '', '']);
//屏幕尺寸系数
let isMonitor = ref(false);
let iponeCoefficient = ref([{ width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }]);
//是否是发送的内容
let isSend = ref(false)
@@ -207,11 +151,113 @@ const mouseData = {
buttons: 1,
};
//打开聊天窗口的状态
let openShowChat = ref(false);
let openShowChat = ref(true);
let istranslate = ref(false); //是否是翻译本页
let phoneXYinfo = ref(getphoneXYinfo() == null ? [{}, {}, {}, {}, {}, {}, {}, {}] : getphoneXYinfo());
console.log('phoneXYinfo.value', phoneXYinfo.value)
// 当前悬浮的按钮索引
const hoverIndex = ref(null)
// 你可以用这种方式声明按钮们
const buttons = [
{
label: '刷新',
onClick: () => reload(),
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: '打开tiktok',
onClick: () => openTk(),
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn2.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn2-2.png', import.meta.url).href
}
},
{
label: '重置tiktok',
onClick: () => resetTk(),
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn3.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn3-3.png', import.meta.url).href
}
},
{
label: '打开直播',
onClick: () => brushLive(),
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn4.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn4-4.png', import.meta.url).href
}
},
{
label: '一键养号',
onClick: () => parentNum(),
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn5.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn5-5.png', import.meta.url).href
}
},
{
label: '一键关注并打招呼',
onClick: () => {
showDialog.value = true
dialogTitle.value = '主播ID'
selectedDevice.value = 999
},
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn6.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn6-6.png', import.meta.url).href
}
},
{
label: '开启监测消息',
onClick: () => openMonitor(),
show: () => !isShowMes.value, // 只有在未开启时显示
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: () => cloesMonitor(),
show: () => isShowMes.value, // 只有在已开启时显示
img: {
normal: new URL('@/assets/video/leftBtn1.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn1-1.png', import.meta.url).href
},
style: { backgroundColor: 'red' }
},
{
label: '全部停止',
onClick: () => stop(),
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn8.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn8-8.png', import.meta.url).href
}
},
{
label: '登出',
onClick: () => router.push('/'),
show: () => true,
img: {
normal: new URL('@/assets/video/leftBtn9.png', import.meta.url).href,
hover: new URL('@/assets/video/leftBtn9-9.png', import.meta.url).href
}
}
]
const wsCache = new Map();
//``````````````````````````````````````````````````````````````````````````````````
// 初始化 手机显示WebSocket 和视频流
const initVideoStream = (udid, index) => {
@@ -296,9 +342,11 @@ const initVideoStream = (udid, index) => {
//点击进入新消息页面以后,获取页面信息
wsActions.clickCopyList(deviceInformation.value[index].udid, index)
} else if (resData.type == 'clickSysMesage') {
Back('', index)
setTimeout(() => {
Back('', index)
}, 3000)
}, 1000)
} else if (resData.type == 'isVideoAndLive') {
console.log(resData.message)
} else if (resData.type == 'clickCopyList') { //获取到的消息列表
@@ -314,11 +362,13 @@ const initVideoStream = (udid, index) => {
if (mesBox.position == 'right') return
openShowChat.value = true
console.log("执行ai")
chat({ msg: mesBox.text }).then(res => {
console.log("ai返回", res)
textContentpri.value[index] = res.result
PrivatetexToPrivatePush(deviceInformation.value[index].udid, index)
})
} else {
console.log("翻译本页")
istranslate.value = false
@@ -396,9 +446,13 @@ const initVideoStream = (udid, index) => {
Back('', index);
setTimeout(() => {
Back('', index);
//正常没有消息,发送完私信以后,返回六次,然后继续下一个任务
wsActions.getmesNum(deviceInformation.value[index].udid, index)
// LikesToLikesToLikes(deviceInformation.value[index].udid, index)
if (isMonitor.value) {
//正常没有消息,发送完私信以后,返回六次,然后继续下一个任务
wsActions.getmesNum(deviceInformation.value[index].udid, index)
} else {
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}
}, 1000);
}, 1000);
@@ -506,7 +560,7 @@ const initVideoStream = (udid, index) => {
}
} else {
// ----------------------------------------------------------------------------------------------------报错处理
//如果该视频无法被评论,返回刷下一条视频
//如果该视频无法被评论,或者没有评论,返回刷下一条视频
if (resData.type == 'Comtext' || resData.type == 'CommentText') {
if (runType.value[index] == 'follow') {
@@ -533,7 +587,7 @@ const initVideoStream = (udid, index) => {
LikesToLikesToLikes(deviceInformation.value[index].udid, index)
}, 1000)
}, 1000)
} else if (resData.type == 'Privatetex' || resData.type == 'hostVideo' || resData.type == 'search') {
} else if (resData.type == 'Privatetex' || resData.type == 'hostVideo' || resData.type == 'search' || resData.type == 'Attention' || resData.type == 'Comment') {
if (runType.value[index] == 'follow') {
//关注的时候出现无法私信和没有视频的情况 错误重置
resetApp(udid, index)
@@ -756,6 +810,7 @@ onMounted(() => {
if (data === 'start') {
if (!isMsgPop.value) {
isMsgPop.value = true;
ElMessageBox.confirm(
'检测到YOLO助手正在爬取主播是否进行操作',
'消息提醒',
@@ -767,7 +822,6 @@ onMounted(() => {
)
.then(() => {
//开启sse版follow任务
ElMessage({
type: 'success',
message: '任务开启成功',
@@ -807,75 +861,26 @@ onMounted(() => {
})
}
} else {
stroageHost.value = getHostList()
// stroageHost.value = getHostList()
stroageHost.value.push(({ country: data.country, text: data.hostsId, state: false }))
if (isMsgPop.value) {
if (runType.value[0] == 'follow') {
setHostList(stroageHost.value)
}
}
//更新状态
// update(
// {
// id: data.id,
// operationStatus: 1,
// }
// ).then(() => {
// })
})
});
//更新状态
// update(
// {
// id: data.id,
// operationStatus: 1,
// }
// ).then(() => {
function opentanchuan() {
ElMessageBox.confirm(
'接收到YOLO爬虫爬取到的主播开始进行操作',
'消息提醒',
{
confirmButtonText: '开始',
cancelButtonText: '取消',
type: 'success',
}
)
.then(() => {
ElMessage({
type: 'success',
message: '任务开启成功',
})
resetTk()
comment().then((resA) => {
console.log('resA:', resA);
setContentList(resA)
//评论
textContentArr.value.forEach((item, indexA) => {
textContent.value[indexA] = resA[getRandomNumber(resA.length - 1)];
})
prologue().then((resB) => {
console.log('resB:', resB);
setContentpriList(resB)
//私信
textContentpriArr.value.forEach((item, indexA) => {
textContentpri.value[indexA] = resB[getRandomNumber(resB.length - 1)];
runType.value[indexA] = 'follow'
console.log('runType', runType.value[indexA])
})
deviceInformation.value.forEach((device, indexB) => {
if (getHostList().length <= 0) return;
// LikesToLikesToLikes(device.udid, indexB)
wsActions.getmesNum(device.udid, indexB)
})
})
})
})
.catch(() => {
})
}
// })
onBeforeUnmount(() => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
@@ -1313,7 +1318,7 @@ function getVideoStyle(index) {
const isSelected = selectedDevice.value === index;
const baseWidth = phone.value.width;
const baseHeight = phone.value.height;
// console.log(isSelected, '是否相等')
return {
width: isSelected ? baseWidth * 1.4 + 'px' : baseWidth + 'px',
height: isSelected ? baseHeight * 1.4 + 'px' : baseHeight + 'px',
@@ -1323,6 +1328,8 @@ function getVideoStyle(index) {
left: isSelected ? '0' : 'unset',
zIndex: isSelected ? 1000 : 1,
pointerEvents: isSelected ? 'none' : 'auto',
transform: getTransformStyle(index),
transition: 'all 0.3s ease',
};
}
@@ -1400,20 +1407,9 @@ function brushLive() {
})
}
//确认多行文本框内容
function onDialogConfirm(result, type, index) {
console.log(result, type, index);
function onDialogConfirm(result, type, index, isMon) {
console.log(type, index, isMon);
if (type == '评论') {
//index ==999 表示批量养号,输入完评论后 即可直接执行脚本
// if (index == 999) {
// getContentList().forEach((item, indexA) => {
// // textContentArr.value[indexA] = result;
// textContent.value[indexA] = result[getRandomNumber(result.length - 1)];
// })
// setContentList(result)
// console.log(getContentList())
// parentNum()
// //index==998是批量关注主播 输入完评论后 还需要输入私信内容
// } else
if (index == 998) {
textContentArr.value.forEach((item, indexA) => {
textContent.value[indexA] = result[getRandomNumber(result.length - 1)];
@@ -1433,17 +1429,26 @@ function onDialogConfirm(result, type, index) {
} else if (type == '私信') {
//index ==999 表示全部
if (index == 999) {
isMonitor.value = isMon //是否自动回复
textContentpriArr.value.forEach((item, indexA) => {
textContentpri.value[indexA] = result[getRandomNumber(result.length - 1)];
runType.value[indexA] = 'follow'
})
// isStop.value = true; //停止所有任务
setContentpriList(result)
deviceInformation.value.forEach((device, indexB) => {
if (getHostList().length <= 0) return;
if (isMon) {
console.log(isMon)
console.error('自动回复');
wsActions.getmesNum(device.udid, indexB)
} else {
console.error('开始关注');
LikesToLikesToLikes(device.udid, indexB)
}
// LikesToLikesToLikes(device.udid, indexB)
wsActions.getmesNum(device.udid, indexB)
})
} else {
textContentpriArr.value[index] = result;
@@ -1465,15 +1470,6 @@ function onDialogConfirm(result, type, index) {
showDialog.value = true;
}, 600)
}
// else {
// hostIdContentArr.value[index] = result;
// hostIdContent.value[index] = result[0];
// deviceInformation.value.forEach((device, indexA) => {
// if (index == indexA) {
// LikesToLikesToLikes(device.udid, index)
// }
// })
// }
}
}
@@ -1495,8 +1491,16 @@ function markFirstFalseAsTrue(hostList) {
}
return null; // 没有找到 false 的项
}
//计算手机canvas是否需要偏移
function getTransformStyle(index) {
return selectedDevice.value === index && index >= 3
? 'translateY(-30%)'
: 'none';
}
function manualGc() {
window.electronAPI.manualGc()
}
</script>
<style scoped lang="less">