编辑ai人设,新消息提醒
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
# iOS 控制服务
|
||||
# VUE_APP_BASE_LOCAL=http://192.168.1.218:34567/
|
||||
VUE_APP_BASE_LOCAL=http://127.0.0.1:34567/
|
||||
# VUE_APP_BASE_LOCAL=http://192.168.1.209:34567/
|
||||
|
||||
# 业务后端(开发用内网地址)
|
||||
# VUE_APP_BASE_REMOTE=https://crawlclient.api.yolozs.com
|
||||
VUE_APP_BASE_REMOTE=http://192.168.1.144:8101/
|
||||
VUE_APP_BASE_REMOTE=https://crawlclient.api.yolozs.com
|
||||
# VUE_APP_BASE_REMOTE=http://192.168.1.144:8101/
|
||||
|
||||
# AI 服务
|
||||
VUE_APP_BASE_SPECIAL=http://ai.zhukeping.com
|
||||
VUE_APP_BASE_SPECIAL=https://ai.yolozs.com
|
||||
@@ -5,4 +5,4 @@ VUE_APP_BASE_LOCAL=http://127.0.0.1:34567/
|
||||
VUE_APP_BASE_REMOTE=https://crawlclient.api.yolozs.com
|
||||
|
||||
# AI 服务(如支持 HTTPS,最好用 https)
|
||||
VUE_APP_BASE_SPECIAL=http://ai.zhukeping.com
|
||||
VUE_APP_BASE_SPECIAL=https://ai.yolozs.com
|
||||
@@ -71,4 +71,8 @@ export function anchorList(data) {
|
||||
//设置主播列表
|
||||
export function deleteAnchorWithIds(data) {
|
||||
return postAxios({ url: 'deleteAnchorWithIds', data })
|
||||
}
|
||||
//设置经纪人信息
|
||||
export function aiConfig(data) {
|
||||
return postAxios({ url: 'aiConfig', data })
|
||||
}
|
||||
122
src/components/AgentGuildDialog.vue
Normal file
122
src/components/AgentGuildDialog.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<el-dialog :model-value="modelValue" :title="title" :width="width" :close-on-click-modal="false" append-to-body
|
||||
@open="onOpen" @close="onClose">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="90px">
|
||||
<el-form-item label="经纪人" prop="agentName">
|
||||
<el-input v-model="form.agentName" placeholder="请输入经纪人名字" maxlength="50" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="公会" prop="guildName">
|
||||
<el-input v-model="form.guildName" placeholder="请输入公会名字" maxlength="50" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 自由输入的联系工具(可不填) -->
|
||||
<el-form-item label="联系工具" prop="contactTool">
|
||||
<el-input v-model="form.contactTool" placeholder="例如:微信 / Telegram / 邮箱 / WhatsApp / 其它(可不填)"
|
||||
maxlength="30" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 联系方式:仅当联系工具已填写时才必填 -->
|
||||
<el-form-item label="联系方式" prop="contact">
|
||||
<el-input v-model="form.contact" placeholder="请输入联系方式(当填写了联系工具时必填)" maxlength="100" show-word-limit
|
||||
clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="onCancel">取 消</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="onConfirm">保 存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: Boolean, default: false },
|
||||
title: { type: String, default: '设置经纪信息' },
|
||||
width: { type: [String, Number], default: '480px' },
|
||||
// 初始值:新增 contactTool 字段(可为空)
|
||||
model: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
agentName: '',
|
||||
guildName: '',
|
||||
contactTool: '',
|
||||
contact: ''
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['update:modelValue', 'save', 'open'])
|
||||
|
||||
const formRef = ref()
|
||||
const submitting = ref(false)
|
||||
const form = reactive({
|
||||
agentName: '',
|
||||
guildName: '',
|
||||
contactTool: '',
|
||||
contact: ''
|
||||
})
|
||||
|
||||
function syncFromProps() {
|
||||
form.agentName = props.model?.agentName ?? ''
|
||||
form.guildName = props.model?.guildName ?? ''
|
||||
form.contactTool = props.model?.contactTool ?? ''
|
||||
form.contact = props.model?.contact ?? ''
|
||||
}
|
||||
|
||||
watch(() => props.modelValue, v => { if (v) syncFromProps() })
|
||||
|
||||
function onOpen() {
|
||||
syncFromProps()
|
||||
emits('open')
|
||||
}
|
||||
function onClose() { emits('update:modelValue', false) }
|
||||
function onCancel() { onClose() }
|
||||
|
||||
const rules = {
|
||||
agentName: [{ required: true, message: '请输入经纪人名字', trigger: 'blur' }],
|
||||
guildName: [{ required: true, message: '请输入公会名字', trigger: 'blur' }],
|
||||
// contactTool 不必填,不加 required
|
||||
contact: [
|
||||
{
|
||||
validator: (rule, value, cb) => {
|
||||
const tool = (form.contactTool || '').trim()
|
||||
const contact = (value || '').trim()
|
||||
if (tool && !contact) {
|
||||
return cb(new Error('已填写联系工具时,联系方式为必填'))
|
||||
}
|
||||
cb()
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
async function onConfirm() {
|
||||
try {
|
||||
submitting.value = true
|
||||
await formRef.value?.validate()
|
||||
|
||||
// 提交前做一次 trim
|
||||
const payload = {
|
||||
agentName: form.agentName.trim(),
|
||||
guildName: form.guildName.trim(),
|
||||
contactTool: form.contactTool.trim(),
|
||||
contact: form.contact.trim()
|
||||
}
|
||||
emits('save', payload)
|
||||
onClose()
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="dialog-content">
|
||||
<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.filter(m => m.type !== 'time')" :key="index"
|
||||
@@ -71,6 +71,7 @@ function fallbackCopyTextToClipboard(index, text) {
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
margin-top: 5vh;
|
||||
background: rgb(246, 246, 246);
|
||||
padding: 0px 20px 20px 20px;
|
||||
border-radius: 12px;
|
||||
@@ -81,7 +82,7 @@ function fallbackCopyTextToClipboard(index, text) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
height: 80vh;
|
||||
height: 35vh;
|
||||
}
|
||||
|
||||
.left-message {
|
||||
|
||||
197
src/components/MessageDialogd.vue
Normal file
197
src/components/MessageDialogd.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div v-if="visible" class="dialog-overlay" @click.self="close">
|
||||
<div class="dialog-content">
|
||||
<h3 class="text-lg font-bold mb-4">
|
||||
<img style="margin: 0 15px;" src="@/assets/video/chatMes.png" />
|
||||
新消息提醒
|
||||
</h3>
|
||||
|
||||
<el-scrollbar class="chat-box">
|
||||
<div v-for="(item, idx) in normalizedMessages" :key="idx" class="msg-item">
|
||||
<div class="meta" @click="onClickMessage(item)">
|
||||
<span class="name">{{ item.sender || '未知用户' }}</span>
|
||||
<span class="sep">·</span>
|
||||
<span class="device">{{ item.device || '未知设备' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="bubble" :class="isSeen(item) ? 'seen' : 'unread'" :style="bubbleStyle(item)"
|
||||
@click="onClickMessage(item)">
|
||||
{{ item.text }}
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits, ref, computed, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const props = defineProps({
|
||||
visible: Boolean,
|
||||
messages: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
// 可自定义颜色
|
||||
reminderColor: {
|
||||
type: String,
|
||||
// Element Plus 警告浅色(看起来像“提醒”)
|
||||
default: 'var(--el-color-warning-light-5, #ffe58f)' // 更深一点
|
||||
},
|
||||
seenColor: {
|
||||
type: String,
|
||||
// EP 填充浅色(更“平静”的已读态)
|
||||
default: 'var(--el-fill-color-light, #f2f3f5)'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['close', 'seen'])
|
||||
const close = () => emit('close')
|
||||
|
||||
// 记录哪些消息已读(用原始索引做 key,避免过滤后索引错位)
|
||||
const seenSet = ref(new Set())
|
||||
|
||||
// 规范化并带上原始索引,过滤掉 type === 'time'
|
||||
const normalizedMessages = computed(() => {
|
||||
const res = []
|
||||
; (props.messages || []).forEach((m, i) => {
|
||||
if (m?.type === 'time') return
|
||||
res.push({
|
||||
origIndex: i,
|
||||
raw: m,
|
||||
sender: m?.sender ?? m?.name ?? m?.user ?? m?.from ?? '',
|
||||
device: m?.device ?? m?.deviceName ?? m?.udid ?? '',
|
||||
text: m?.text ?? m?.content ?? ''
|
||||
})
|
||||
})
|
||||
return res
|
||||
})
|
||||
|
||||
// 初始化:如果消息本身标注了 seen/read,则置为已读
|
||||
watch(
|
||||
() => props.messages,
|
||||
(list) => {
|
||||
const s = new Set()
|
||||
list?.forEach((m, i) => {
|
||||
if (m && (m.seen === true || m.read === true)) s.add(i)
|
||||
})
|
||||
seenSet.value = s
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
function isSeen(item) {
|
||||
return seenSet.value.has(item.origIndex)
|
||||
}
|
||||
|
||||
function markSeen(item) {
|
||||
if (!isSeen(item)) {
|
||||
seenSet.value.add(item.origIndex)
|
||||
// 通知父组件(可选):你也可以在父里把 messages[item.origIndex].seen = true 持久化
|
||||
emit('seen', { index: item.origIndex, message: item.raw })
|
||||
}
|
||||
}
|
||||
|
||||
function bubbleStyle(item) {
|
||||
return {
|
||||
backgroundColor: isSeen(item) ? props.seenColor : props.reminderColor,
|
||||
color: '#333'
|
||||
}
|
||||
}
|
||||
|
||||
// 点击:标记已读 + 复制文本
|
||||
function onClickMessage(item) {
|
||||
markSeen(item)
|
||||
fallbackCopyTextToClipboard(item.text)
|
||||
}
|
||||
|
||||
// 兜底复制
|
||||
function fallbackCopyTextToClipboard(text) {
|
||||
// const textArea = document.createElement('textarea')
|
||||
// textArea.value = text || ''
|
||||
// textArea.style.position = 'fixed'
|
||||
// textArea.style.left = '-999999px'
|
||||
// textArea.style.top = '-999999px'
|
||||
// document.body.appendChild(textArea)
|
||||
// textArea.focus()
|
||||
// textArea.select()
|
||||
|
||||
try {
|
||||
// const ok = document.execCommand('copy')
|
||||
// ok ? ElMessage.success('已读') : ElMessage.error('复制失败1')
|
||||
ElMessage.success('已读')
|
||||
} catch (err) {
|
||||
// ElMessage.error('复制失败2')
|
||||
} finally {
|
||||
// document.body.removeChild(textArea)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialog-overlay {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
margin-top: 3vh;
|
||||
background: rgb(246, 246, 246);
|
||||
padding: 0 20px 20px 20px;
|
||||
border-radius: 12px;
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.chat-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
height: 35vh;
|
||||
}
|
||||
|
||||
/* 全部左对齐 */
|
||||
.msg-item {
|
||||
align-self: flex-start;
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.meta {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin: 2px 0 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.meta .name {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.meta .sep {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.meta .device {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
padding: 10px 14px;
|
||||
border-radius: 12px;
|
||||
max-width: 90%;
|
||||
display: inline-block;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* 颜色通过内联样式控制(.unread/.seen 仅用于语义钩子) */
|
||||
.bubble.unread {}
|
||||
|
||||
.bubble.seen {}
|
||||
</style>
|
||||
@@ -20,7 +20,7 @@ function attachInterceptors(instance) {
|
||||
instance.interceptors.request.use((config) => {
|
||||
// 登录/换租户接口可能不需要 token,根据你的需求放行
|
||||
const urlLast = sliceUrl(config.url || '')
|
||||
if ((urlLast === 'prologue' || urlLast === 'comment')) {
|
||||
if ((urlLast === 'prologue' || urlLast === 'comment' || urlLast === 'aiChat-logout')) {
|
||||
config.headers['vvtoken'] = getToken()
|
||||
}
|
||||
// 超时 & 通用头
|
||||
@@ -42,6 +42,8 @@ function attachInterceptors(instance) {
|
||||
if (data?.code === 0 || data?.code === 200) {
|
||||
// 成功:返回业务数据(没有就回传原 data)
|
||||
return (data?.data !== undefined) ? data.data : data
|
||||
} else if (data?.code === 40400) {
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
// 业务失败:提示 + reject
|
||||
|
||||
@@ -79,7 +79,7 @@ import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/stores/
|
||||
import { ElLoading, ElMessage } from 'element-plus';
|
||||
import { passToken } from '@/api/ios';
|
||||
|
||||
let version = ref('1.1.1');
|
||||
let version = ref('1.1.4');
|
||||
onMounted(() => {
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<el-scrollbar class="left"> <!-- 左边栏 -->
|
||||
<div style="position: absolute;left: 20px; top: 20px;">
|
||||
<el-button style="background: linear-gradient(90deg, #60a5fa, #34d399); color: azure;"
|
||||
@click="showMyInfo = true">人设编辑</el-button>
|
||||
</div>
|
||||
<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="btn.style ? btn.style() : {}" @click="btn.onClick"
|
||||
@@ -29,6 +33,8 @@
|
||||
<div class="input-info" v-show="selectedDevice == index">
|
||||
|
||||
<div class="app-button" @click="getMesList(device.deviceId)">获取当前聊天记录</div>
|
||||
<div class="app-button" @click="stopScript({ udid: device.deviceId })">停止任务</div>
|
||||
<div class="app-button" @click="runTask(runType, device.deviceId)">开启</div>
|
||||
<!-- <div class="app-button" @click="mqSend()">mq</div> -->
|
||||
<!-- <div class="app-button"
|
||||
@click="wsActions.clickCopyList(device.deviceId, index); openShowChat = true; istranslate = true">
|
||||
@@ -52,15 +58,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right center-justify" @click.self="selectedDevice = 999">
|
||||
<div class="right center-line" @click.self="selectedDevice = 999">
|
||||
<!-- <div style="margin: 30px;"></div> -->
|
||||
<ChatDialog :visible="openShowChat" :messages="chatList" />
|
||||
<MessageDialogd :visible="openShowChat" :messages="MesNewList" />
|
||||
</div>
|
||||
<MultiLineInputDialog v-model:visible="showDialog" :initialText='""' :title="dialogTitle" :index="selectedDevice"
|
||||
@confirm="onDialogConfirm" @cancel="stopAll" />
|
||||
<HostListManagerDialog v-model:visible="showHostDlg" @save="onHostSaved" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <AgentGuildDialog v-model="showMyInfo" :model="formInit" @save="handleSave" /> -->
|
||||
<AgentGuildDialog v-model="showMyInfo" :model="{
|
||||
agentName: borkerConfig.agentName,
|
||||
guildName: borkerConfig.guildName,
|
||||
contactTool: borkerConfig.contactTool,
|
||||
contact: borkerConfig.contact
|
||||
}" @save="onSave" />
|
||||
<!-- 定时调度配置弹窗 -->
|
||||
<el-dialog v-model="showScheduleDlg" title="定时调度(每小时)" width="420px">
|
||||
<div style="display:grid;grid-template-columns: 100px 1fr; gap:12px; align-items:center;">
|
||||
@@ -106,7 +120,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, onBeforeUnmount, watch, inject, computed } from "vue";
|
||||
import { ref, reactive, onMounted, onUnmounted, onBeforeUnmount, watch, inject, computed } from "vue";
|
||||
import { useRouter } from 'vue-router';
|
||||
import {
|
||||
setphoneXYinfo, getphoneXYinfo, getUser,
|
||||
@@ -118,8 +132,11 @@ import { connectSSE } from '@/utils/sseUtils'
|
||||
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
|
||||
import { chat, translationToChinese, translation } from "@/api/chat";
|
||||
import HostListManagerDialog from '@/components/HostListManagerDialog.vue'
|
||||
import AgentGuildDialog from '@/components/AgentGuildDialog.vue'
|
||||
|
||||
import MultiLineInputDialog from '@/components/MultiLineInputDialog.vue'; // 根据实际路径修改
|
||||
import ChatDialog from '@/components/ChatDialog.vue'
|
||||
import MessageDialogd from '@/components/MessageDialogd.vue'
|
||||
import { pickTikTokBundleId } from '@/utils/arrUtils'
|
||||
import { logout } from '@/api/account';
|
||||
import {
|
||||
@@ -137,19 +154,76 @@ import {
|
||||
launchApp,
|
||||
getChatTextInfo,
|
||||
setLoginInfo,
|
||||
|
||||
aiConfig,
|
||||
|
||||
} from '@/api/ios';
|
||||
import { set } from "lodash";
|
||||
const router = useRouter();
|
||||
const openShowChat = ref([true])
|
||||
//主播库
|
||||
const showHostDlg = ref(false)
|
||||
//ai人设
|
||||
const showMyInfo = ref(false)
|
||||
// 假设这是你已有的数据
|
||||
const borkerConfig = reactive({
|
||||
agentName: '',
|
||||
guildName: '',
|
||||
contactTool: '',
|
||||
contact: ''
|
||||
})
|
||||
|
||||
let hostList = []
|
||||
//查询列表轮询
|
||||
let getListtimer = null;
|
||||
let userdata = getUser();
|
||||
let chatList = ref([])
|
||||
|
||||
let MesNewList = ref([{
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
}, {
|
||||
sender: 'Alice', // 或 name/user/from
|
||||
device: 'iPhone 14 Pro', // 或 deviceName/udid
|
||||
text: '你好呀~', // 或 content
|
||||
type: 'msg' // 可选;有些是 'time' 会被过滤
|
||||
},])
|
||||
let isImg = ref(true)
|
||||
// 引入刷新方法
|
||||
const reload = inject("reload")
|
||||
@@ -172,6 +246,8 @@ let deviceInformation = ref([])
|
||||
// 你可以用这种方式声明按钮们
|
||||
//联动用作标记
|
||||
let batchMode = ref('init'); // 'init' | 'follow'(仅作标记)
|
||||
//停止中
|
||||
let stopLoading = null
|
||||
|
||||
// 当前是否被其它模式占用(四个互斥按钮专用)
|
||||
const isLocked = (type) => !!runType.value && runType.value !== type
|
||||
@@ -642,20 +718,36 @@ function getMesList(deviceId) {
|
||||
})
|
||||
}
|
||||
|
||||
function stopAll() {
|
||||
async function stopAll() {
|
||||
stopLoading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '停止中',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
// if (!runType.value) return
|
||||
deviceInformation.value.forEach((item) => {
|
||||
stopScript({ udid: item.deviceId }).then((res) => {
|
||||
console.log(`停止成功:${item.deviceId}`, res, printCurrentTime())
|
||||
ElMessage.success(`停止成功:${item.deviceId}`)
|
||||
}).catch((res) => {
|
||||
console.log(`停止失败`, printCurrentTime())
|
||||
ElMessage.error(`脚本已停止`)
|
||||
})
|
||||
})
|
||||
scheduleEnabled.value = false
|
||||
runType.value = ''
|
||||
batchMode.value = 'init';
|
||||
|
||||
try {
|
||||
// 使用 Promise.all 并行处理所有设备的停止操作
|
||||
await Promise.all(deviceInformation.value.map(async (item) => {
|
||||
try {
|
||||
const res = await stopScript({ udid: item.deviceId })
|
||||
console.log(`停止成功:${item.deviceId}`, res, printCurrentTime())
|
||||
ElMessage.success(`停止成功:${item.deviceId}`)
|
||||
stopLoading.close()
|
||||
} catch (error) {
|
||||
console.log(`停止失败`, printCurrentTime())
|
||||
ElMessage.error(`脚本已停止`)
|
||||
stopLoading.close()
|
||||
}
|
||||
}))
|
||||
|
||||
// 所有操作完成后执行以下代码
|
||||
scheduleEnabled.value = false
|
||||
runType.value = ''
|
||||
batchMode.value = 'init'
|
||||
} catch (error) {
|
||||
console.error('批量停止过程中发生错误:', error)
|
||||
}
|
||||
}
|
||||
|
||||
//确认多行文本框内容
|
||||
@@ -682,6 +774,8 @@ function onDialogConfirm(result, type, index, isMon) {
|
||||
needReply: isMon
|
||||
}
|
||||
).then((res) => {
|
||||
ElMessage({ type: 'success', message: '任务开启成功' });
|
||||
|
||||
hostList = []
|
||||
})
|
||||
}
|
||||
@@ -741,7 +835,6 @@ onMounted(() => {
|
||||
{ confirmButtonText: '开始', cancelButtonText: '取消', type: 'success' }
|
||||
)
|
||||
.then(() => {
|
||||
ElMessage({ type: 'success', message: '任务开启成功' });
|
||||
// runType.value = 'follow';
|
||||
batchMode.value = 'follow';
|
||||
|
||||
@@ -749,8 +842,12 @@ onMounted(() => {
|
||||
// 不直接发;把这“一波”的主播先塞进 hostList,然后弹出“私信”输入框
|
||||
scheduleFlush((items) => {
|
||||
hostList = (items || []).map(h => ({ id: h.text, country: h.country || '' }))
|
||||
showScheduleDlg.value = true
|
||||
|
||||
})
|
||||
setTimeout(() => {
|
||||
showScheduleDlg.value = true
|
||||
}, 600)
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
// 取消:清理状态,丢弃批次
|
||||
@@ -808,6 +905,8 @@ onUnmounted(() => {
|
||||
clearInterval(getListtimer)
|
||||
getListtimer = null
|
||||
})
|
||||
|
||||
let isStartLac = false
|
||||
const getDeviceListFun = () => {
|
||||
getDeviceList().then((res) => {
|
||||
console.log('返回', res.length)
|
||||
@@ -823,7 +922,12 @@ const getDeviceListFun = () => {
|
||||
}
|
||||
// deviceInformation.value = ['', '', '', '', '', '',]
|
||||
}).catch((err) => {
|
||||
ElMessage.error(`IOSAI服务错误`)
|
||||
if (isStartLac) {
|
||||
ElMessage.error(`IOSAI服务错误`)
|
||||
isStartLac = true
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
@@ -875,15 +979,30 @@ async function uploadLogFile() {
|
||||
|
||||
}
|
||||
}
|
||||
function runTask(key) {
|
||||
function runTask(key, deviceId) {
|
||||
console.log('[schedule] 切换到任务:', key, printCurrentTime())
|
||||
|
||||
forceActivate(key, () => {
|
||||
forceActivate(key, async () => {
|
||||
if (key === 'follow') {
|
||||
|
||||
|
||||
if (scheduleEnabled.value) {
|
||||
stopAll()
|
||||
if (!deviceId) {
|
||||
await stopAll()
|
||||
} else {
|
||||
passAnchorData(
|
||||
{
|
||||
deviceList: [deviceId],
|
||||
anchorList: [],
|
||||
prologueList: getContentpriList(),
|
||||
needReply: false
|
||||
}
|
||||
).then((res) => {
|
||||
hostList = []
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
runType.value = 'follow'
|
||||
|
||||
@@ -903,7 +1022,7 @@ function runTask(key) {
|
||||
}
|
||||
|
||||
scheduleEnabled.value = true
|
||||
if (hostList.length <= 0) {
|
||||
if (batchMode.value == 'init') {
|
||||
dialogTitle.value = '主播ID';
|
||||
} else {
|
||||
dialogTitle.value = '私信';
|
||||
@@ -912,7 +1031,12 @@ function runTask(key) {
|
||||
|
||||
} else if (key === 'like') {
|
||||
|
||||
stopAll()
|
||||
if (!deviceId) {
|
||||
await stopAll()
|
||||
} else {
|
||||
growAccount({ udid: deviceId })
|
||||
return
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
scheduleEnabled.value = true
|
||||
@@ -921,7 +1045,12 @@ function runTask(key) {
|
||||
}, 1000)
|
||||
|
||||
} else if (key === 'brushLive') {
|
||||
stopAll()
|
||||
if (!deviceId) {
|
||||
await stopAll()
|
||||
} else {
|
||||
watchLiveForGrowth({ udid: deviceId })
|
||||
return
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
scheduleEnabled.value = true
|
||||
@@ -930,7 +1059,12 @@ function runTask(key) {
|
||||
}, 1000)
|
||||
runType.value = 'brushLive'
|
||||
} else if (key === 'listen') {
|
||||
stopAll()
|
||||
if (!deviceId) {
|
||||
await stopAll()
|
||||
} else {
|
||||
monitorMessages({ udid: deviceId })
|
||||
return
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
runType.value = 'listen'
|
||||
@@ -1014,6 +1148,14 @@ function printCurrentTime() {
|
||||
return now.toLocaleString()
|
||||
}
|
||||
|
||||
|
||||
function onSave(payload) {
|
||||
console.log(payload)
|
||||
aiConfig(payload).then((res) => {
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
Reference in New Issue
Block a user