2.4.7 优化过滤 新增重置任务
This commit is contained in:
@@ -125,6 +125,8 @@ onMounted(() => {
|
|||||||
|
|
||||||
window.addEventListener('beforeunload', handleBeforeUnload)
|
window.addEventListener('beforeunload', handleBeforeUnload)
|
||||||
window.addEventListener('storage', handleStorageChange)
|
window.addEventListener('storage', handleStorageChange)
|
||||||
|
// 监听账号组配置更新事件
|
||||||
|
window.addEventListener('config-updated', handleConfigUpdate)
|
||||||
|
|
||||||
loadConfig()
|
loadConfig()
|
||||||
|
|
||||||
@@ -135,6 +137,7 @@ onMounted(() => {
|
|||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('beforeunload', handleBeforeUnload)
|
window.removeEventListener('beforeunload', handleBeforeUnload)
|
||||||
window.removeEventListener('storage', handleStorageChange)
|
window.removeEventListener('storage', handleStorageChange)
|
||||||
|
window.removeEventListener('config-updated', handleConfigUpdate)
|
||||||
stopHealthCheck()
|
stopHealthCheck()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -149,6 +152,12 @@ const handleStorageChange = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理配置更新事件
|
||||||
|
const handleConfigUpdate = () => {
|
||||||
|
console.log('[App] 收到配置更新事件,重新加载配置')
|
||||||
|
loadConfig()
|
||||||
|
}
|
||||||
|
|
||||||
let healthCheckInterval = null
|
let healthCheckInterval = null
|
||||||
|
|
||||||
const startHealthCheck = () => {
|
const startHealthCheck = () => {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 5.4 KiB |
@@ -68,7 +68,7 @@
|
|||||||
<!-- 下拉菜单 -->
|
<!-- 下拉菜单 -->
|
||||||
<div v-if="showLevelDropdown"
|
<div v-if="showLevelDropdown"
|
||||||
class="absolute top-full left-4 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-50 p-3 w-72">
|
class="absolute top-full left-4 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-50 p-3 w-72">
|
||||||
<div class="text-xs text-gray-500 mb-2">选择接收的主播等级(不选则接收全部)</div>
|
<div class="text-xs text-gray-500 mb-2">选择接收的主播等级(不勾选则过滤掉)</div>
|
||||||
<div class="space-y-2 max-h-60 overflow-auto">
|
<div class="space-y-2 max-h-60 overflow-auto">
|
||||||
<div v-for="parent in LEVEL_OPTIONS" :key="parent.value"
|
<div v-for="parent in LEVEL_OPTIONS" :key="parent.value"
|
||||||
class="border border-gray-100 rounded p-2">
|
class="border border-gray-100 rounded p-2">
|
||||||
@@ -93,10 +93,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 pt-2 border-t border-gray-100 flex justify-between">
|
<div class="mt-2 pt-2 border-t border-gray-100 flex justify-between">
|
||||||
<button @click="updateLevelFilter(new Set())"
|
<div class="flex gap-2">
|
||||||
|
<button @click="selectAllLevels()"
|
||||||
class="text-xs text-gray-500 hover:text-gray-700">
|
class="text-xs text-gray-500 hover:text-gray-700">
|
||||||
清空选择
|
全选
|
||||||
</button>
|
</button>
|
||||||
|
<button @click="selectNoneLevels()"
|
||||||
|
class="text-xs text-gray-500 hover:text-gray-700">
|
||||||
|
全不选
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<button @click="showLevelDropdown = false"
|
<button @click="showLevelDropdown = false"
|
||||||
class="text-xs text-blue-600 hover:text-blue-700">
|
class="text-xs text-blue-600 hover:text-blue-700">
|
||||||
完成
|
完成
|
||||||
@@ -308,7 +314,7 @@ const filters = ref({
|
|||||||
minOnlineFans: '',
|
minOnlineFans: '',
|
||||||
maxOnlineFans: '',
|
maxOnlineFans: '',
|
||||||
})
|
})
|
||||||
const maxCount = ref(100)
|
const maxCount = ref()
|
||||||
const selectedLevels = ref(new Set())
|
const selectedLevels = ref(new Set())
|
||||||
const showLevelDropdown = ref(false)
|
const showLevelDropdown = ref(false)
|
||||||
|
|
||||||
@@ -418,10 +424,15 @@ const loadConfig = async () => {
|
|||||||
try {
|
try {
|
||||||
const config = await window.electronAPI.getAutomationConfig()
|
const config = await window.electronAPI.getAutomationConfig()
|
||||||
if (config?.filters?.maxAnchorCount !== undefined) {
|
if (config?.filters?.maxAnchorCount !== undefined) {
|
||||||
maxCount.value = config.filters.maxAnchorCount
|
// 如果后端返回 9999999,前端显示为空
|
||||||
|
maxCount.value = config.filters.maxAnchorCount === 9999999 ? '' : config.filters.maxAnchorCount
|
||||||
}
|
}
|
||||||
if (config?.filters?.hostsLevelList) {
|
if (config?.filters?.hostsLevelList) {
|
||||||
selectedLevels.value = new Set(config.filters.hostsLevelList)
|
// 计算反向等级列表:后端存储的是要过滤的等级,前端需要的是要显示的等级
|
||||||
|
const allLevels = LEVEL_OPTIONS.flatMap(parent => parent.children.map(child => child.value))
|
||||||
|
const excludedLevels = config.filters.hostsLevelList
|
||||||
|
const includedLevels = allLevels.filter(level => !excludedLevels.includes(level))
|
||||||
|
selectedLevels.value = new Set(includedLevels)
|
||||||
}
|
}
|
||||||
// 加载进阶票/普票过滤配置
|
// 加载进阶票/普票过滤配置
|
||||||
if (config?.filters?.gold !== undefined) {
|
if (config?.filters?.gold !== undefined) {
|
||||||
@@ -461,10 +472,21 @@ const updateLevelFilter = async (levels) => {
|
|||||||
selectedLevels.value = levels
|
selectedLevels.value = levels
|
||||||
if (!isElectron()) return
|
if (!isElectron()) return
|
||||||
try {
|
try {
|
||||||
|
// 计算反向等级列表:前端勾选的是要显示的,后端需要的是要过滤的(不显示的)
|
||||||
|
const allLevels = LEVEL_OPTIONS.flatMap(parent => parent.children.map(child => child.value))
|
||||||
|
const includedLevels = Array.from(levels)
|
||||||
|
|
||||||
|
// 当全不选时,传给后端的是空数组(不过滤任何等级)
|
||||||
|
// 当有选择时,传给后端的是未选择的等级(过滤这些等级)
|
||||||
|
let excludedLevels = []
|
||||||
|
if (includedLevels.length > 0) {
|
||||||
|
excludedLevels = allLevels.filter(level => !includedLevels.includes(level))
|
||||||
|
}
|
||||||
|
|
||||||
await window.electronAPI.updateAutomationConfig({
|
await window.electronAPI.updateAutomationConfig({
|
||||||
filters: { hostsLevelList: Array.from(levels) }
|
filters: { hostsLevelList: excludedLevels }
|
||||||
})
|
})
|
||||||
console.log('[HostListDialog] 等级过滤已更新:', Array.from(levels))
|
console.log('[HostListDialog] 等级过滤已更新:', excludedLevels)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('更新等级配置失败:', e)
|
console.error('更新等级配置失败:', e)
|
||||||
}
|
}
|
||||||
@@ -493,14 +515,27 @@ const toggleParentLevel = (parentValue) => {
|
|||||||
updateLevelFilter(newSet)
|
updateLevelFilter(newSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectAllLevels = () => {
|
||||||
|
// 全选所有等级
|
||||||
|
const allLevels = LEVEL_OPTIONS.flatMap(parent => parent.children.map(child => child.value))
|
||||||
|
updateLevelFilter(new Set(allLevels))
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectNoneLevels = () => {
|
||||||
|
// 全不选所有等级
|
||||||
|
updateLevelFilter(new Set())
|
||||||
|
}
|
||||||
|
|
||||||
const updateMaxCount = async (value) => {
|
const updateMaxCount = async (value) => {
|
||||||
// value is already updated via v-model
|
// value is already updated via v-model
|
||||||
if (!isElectron()) return
|
if (!isElectron()) return
|
||||||
try {
|
try {
|
||||||
|
// 如果不填写,传 9999999 表示无限制
|
||||||
|
const maxAnchorCount = value || 9999999
|
||||||
await window.electronAPI.updateAutomationConfig({
|
await window.electronAPI.updateAutomationConfig({
|
||||||
filters: { maxAnchorCount: value }
|
filters: { maxAnchorCount }
|
||||||
})
|
})
|
||||||
console.log('[HostListDialog] 主播数据上限已更新:', value)
|
console.log('[HostListDialog] 主播数据上限已更新:', maxAnchorCount)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('更新配置失败:', e)
|
console.error('更新配置失败:', e)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,18 +307,20 @@ const showInviteList = async () => {
|
|||||||
|
|
||||||
// 复制主播 ID
|
// 复制主播 ID
|
||||||
const copyAnchorId = (id) => {
|
const copyAnchorId = (id) => {
|
||||||
|
// 去除前面的 @ 符号
|
||||||
|
const cleanId = id.startsWith('@') ? id.substring(1) : id
|
||||||
if (navigator.clipboard && window.isSecureContext) {
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
// 现代浏览器使用 Clipboard API
|
// 现代浏览器使用 Clipboard API
|
||||||
navigator.clipboard.writeText(id).then(() => {
|
navigator.clipboard.writeText(cleanId).then(() => {
|
||||||
showCopySuccess()
|
showCopySuccess()
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error('复制失败:', err)
|
console.error('复制失败:', err)
|
||||||
// 回退到传统方法
|
// 回退到传统方法
|
||||||
fallbackCopyTextToClipboard(id)
|
fallbackCopyTextToClipboard(cleanId)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 传统方法
|
// 传统方法
|
||||||
fallbackCopyTextToClipboard(id)
|
fallbackCopyTextToClipboard(cleanId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="country">{{ item.country }}</div>
|
<div class="country">{{ item.country }}</div>
|
||||||
<div class="stat-item">
|
<div class="stat-item">
|
||||||
<img class="stat-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/gold.png" alt="" />
|
<img class="stat-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/gold.png"
|
||||||
|
alt="" />
|
||||||
<span>金币: <b>{{ item.coin }}K</b></span>
|
<span>金币: <b>{{ item.coin }}K</b></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-item">
|
<div class="stat-item">
|
||||||
<img class="stat-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/session.png" alt="" />
|
<img class="stat-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/session.png"
|
||||||
|
alt="" />
|
||||||
<span>场次: <b>{{ item.pkNumber }}场</b></span>
|
<span>场次: <b>{{ item.pkNumber }}场</b></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -66,35 +68,20 @@
|
|||||||
|
|
||||||
<!-- 国家 -->
|
<!-- 国家 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-select-v2
|
<el-select-v2 v-model="formData.country" :options="countryOptions" placeholder="请选择国家" filterable
|
||||||
v-model="formData.country"
|
style="width: 100%" />
|
||||||
:options="countryOptions"
|
|
||||||
placeholder="请选择国家"
|
|
||||||
filterable
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 性别 -->
|
<!-- 性别 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-select-v2
|
<el-select-v2 v-model="formData.gender" :options="genderOptions" placeholder="请选择性别"
|
||||||
v-model="formData.gender"
|
style="width: 100%" />
|
||||||
:options="genderOptions"
|
|
||||||
placeholder="请选择性别"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PK时间 -->
|
<!-- PK时间 -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<el-date-picker
|
<el-date-picker v-model="formData.pkTime" type="datetime" placeholder="请选择PK时间(北京时间)" style="width: 100%"
|
||||||
v-model="formData.pkTime"
|
:formatter="formatBeijingTime" :parser="parseBeijingTime" value-format="x" />
|
||||||
type="datetime"
|
|
||||||
placeholder="请选择PK时间"
|
|
||||||
style="width: 100%"
|
|
||||||
format="YYYY/MM/DD HH:mm"
|
|
||||||
value-format="x"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 金币和场次 -->
|
<!-- 金币和场次 -->
|
||||||
@@ -136,13 +123,8 @@
|
|||||||
<el-dialog v-model="showAnchorDialog" title="选择我的主播" width="800" align-center>
|
<el-dialog v-model="showAnchorDialog" title="选择我的主播" width="800" align-center>
|
||||||
<div class="anchor-dialog-content">
|
<div class="anchor-dialog-content">
|
||||||
<div class="anchor-list">
|
<div class="anchor-list">
|
||||||
<div
|
<div v-for="(item, index) in anchorLibrary" :key="index" class="anchor-item"
|
||||||
v-for="(item, index) in anchorLibrary"
|
:class="{ selected: selectedAnchor === item }" @click="selectedAnchor = item">
|
||||||
:key="index"
|
|
||||||
class="anchor-item"
|
|
||||||
:class="{ selected: selectedAnchor === item }"
|
|
||||||
@click="selectedAnchor = item"
|
|
||||||
>
|
|
||||||
<img class="anchor-avatar" :src="item.headerIcon" alt="" />
|
<img class="anchor-avatar" :src="item.headerIcon" alt="" />
|
||||||
<div class="anchor-info">
|
<div class="anchor-info">
|
||||||
<div class="anchor-name">{{ item.anchorId }}</div>
|
<div class="anchor-name">{{ item.anchorId }}</div>
|
||||||
@@ -167,12 +149,7 @@
|
|||||||
<el-dialog v-model="showTopDialog" title="置顶" width="500" align-center>
|
<el-dialog v-model="showTopDialog" title="置顶" width="500" align-center>
|
||||||
<div class="top-dialog-content">
|
<div class="top-dialog-content">
|
||||||
<p class="top-tip">置顶后,您的PK信息将在首页优先展示,可以获得更多曝光机会。</p>
|
<p class="top-tip">置顶后,您的PK信息将在首页优先展示,可以获得更多曝光机会。</p>
|
||||||
<el-select-v2
|
<el-select-v2 v-model="topDuration" :options="topDurationOptions" placeholder="请选择置顶时长" style="width: 100%" />
|
||||||
v-model="topDuration"
|
|
||||||
:options="topDurationOptions"
|
|
||||||
placeholder="请选择置顶时长"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<div class="dialog-btns">
|
<div class="dialog-btns">
|
||||||
<div class="reset-btn" @click="showTopDialog = false">取消</div>
|
<div class="reset-btn" @click="showTopDialog = false">取消</div>
|
||||||
<div class="confirm-btn" @click="confirmTop">确认置顶</div>
|
<div class="confirm-btn" @click="confirmTop">确认置顶</div>
|
||||||
@@ -194,7 +171,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import {
|
import {
|
||||||
getPkInfo,
|
getPkInfo,
|
||||||
releasePkInfo,
|
releasePkInfo,
|
||||||
@@ -227,6 +204,36 @@ const list = ref([])
|
|||||||
const page = ref(0)
|
const page = ref(0)
|
||||||
const formatTime = TimestamptolocalTime
|
const formatTime = TimestamptolocalTime
|
||||||
|
|
||||||
|
// 北京时间格式化函数
|
||||||
|
function formatBeijingTime(timestamp) {
|
||||||
|
// 创建一个UTC时间的Date对象
|
||||||
|
const utcDate = new Date(timestamp)
|
||||||
|
|
||||||
|
// 将UTC时间转换为北京时间(UTC+8)
|
||||||
|
const beijingDate = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000)
|
||||||
|
|
||||||
|
const year = beijingDate.getUTCFullYear()
|
||||||
|
const month = String(beijingDate.getUTCMonth() + 1).padStart(2, '0')
|
||||||
|
const day = String(beijingDate.getUTCDate()).padStart(2, '0')
|
||||||
|
const hours = String(beijingDate.getUTCHours()).padStart(2, '0')
|
||||||
|
const minutes = String(beijingDate.getUTCMinutes()).padStart(2, '0')
|
||||||
|
|
||||||
|
return `${year}/${month}/${day} ${hours}:${minutes}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析北京时间字符串为时间戳
|
||||||
|
function parseBeijingTime(dateString) {
|
||||||
|
const [datePart, timePart] = dateString.split(' ')
|
||||||
|
const [year, month, day] = datePart.split('/').map(Number)
|
||||||
|
const [hours, minutes] = timePart.split(':').map(Number)
|
||||||
|
|
||||||
|
// 创建一个UTC时间的Date对象,将北京时间的小时减去8小时
|
||||||
|
const utcDate = new Date(Date.UTC(year, month - 1, day, hours - 8, minutes, 0, 0))
|
||||||
|
|
||||||
|
// 返回UTC时间的时间戳(毫秒)
|
||||||
|
return utcDate.getTime()
|
||||||
|
}
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
anchorName: '',
|
anchorName: '',
|
||||||
@@ -567,7 +574,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-content:hover {
|
.card-content:hover {
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
transform: scale(1.02);
|
transform: scale(1.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,7 +773,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.confirm-btn:hover {
|
.confirm-btn:hover {
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
transform: scale(1.02);
|
transform: scale(1.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,7 +792,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.reset-btn:hover {
|
.reset-btn:hover {
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
transform: scale(1.02);
|
transform: scale(1.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,8 @@
|
|||||||
<PermissionMask permission-key="webAi" title="自动私信工作台未开通" description="您当前没有使用自动私信功能的权限"
|
<PermissionMask permission-key="webAi" title="自动私信工作台未开通" description="您当前没有使用自动私信功能的权限"
|
||||||
:placeholder-image="placeholderWebAi" :contacts="serviceContacts">
|
:placeholder-image="placeholderWebAi" :contacts="serviceContacts">
|
||||||
<div v-if="autoDmMode === 'config'" class="h-full w-full bg-slate-50 overflow-auto">
|
<div v-if="autoDmMode === 'config'" class="h-full w-full bg-slate-50 overflow-auto">
|
||||||
<ConfigPage @go-to-browser="handleGoToBrowser" @logout="$emit('logout')" />
|
<ConfigPage @go-to-browser="handleGoToBrowser" @logout="$emit('logout')"
|
||||||
|
@config-updated="handleConfigUpdated" />
|
||||||
</div>
|
</div>
|
||||||
<div v-show="autoDmMode === 'browser'" class="h-full w-full">
|
<div v-show="autoDmMode === 'browser'" class="h-full w-full">
|
||||||
<YoloBrowser v-bind="$attrs" :nav-sidebar-width="navSidebarWidth" @go-back="handleBackToConfig"
|
<YoloBrowser v-bind="$attrs" :nav-sidebar-width="navSidebarWidth" @go-back="handleBackToConfig"
|
||||||
@@ -256,6 +257,12 @@ const handleStopAll = () => {
|
|||||||
emit('stop-all')
|
emit('stop-all')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理配置更新事件
|
||||||
|
const handleConfigUpdated = () => {
|
||||||
|
// 触发自定义事件通知 YoloBrowser 重新加载配置
|
||||||
|
window.dispatchEvent(new CustomEvent('config-updated'))
|
||||||
|
}
|
||||||
|
|
||||||
// Watch for view changes to manage native Electron BrowserViews
|
// Watch for view changes to manage native Electron BrowserViews
|
||||||
watch(currentView, async (newVal, oldVal) => {
|
watch(currentView, async (newVal, oldVal) => {
|
||||||
// 懒加载 Web 端 iframe(仅非 Electron)
|
// 懒加载 Web 端 iframe(仅非 Electron)
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ import GreetingDialog from '../components/GreetingDialog.vue'
|
|||||||
import AIConfigDialog from '../components/AIConfigDialog.vue'
|
import AIConfigDialog from '../components/AIConfigDialog.vue'
|
||||||
import { isElectron } from '../utils/electronBridge'
|
import { isElectron } from '../utils/electronBridge'
|
||||||
|
|
||||||
const emit = defineEmits(['goToBrowser', 'logout'])
|
const emit = defineEmits(['goToBrowser', 'logout', 'configUpdated'])
|
||||||
|
|
||||||
const CONFIG_KEY = 'autoDm_runConfig'
|
const CONFIG_KEY = 'autoDm_runConfig'
|
||||||
|
|
||||||
@@ -793,6 +793,8 @@ const handleStart = async (specificGroupIndex) => {
|
|||||||
rotationStatus.value = status
|
rotationStatus.value = status
|
||||||
handleStatusChange(status)
|
handleStatusChange(status)
|
||||||
warmingUp.value = false //关闭遮罩
|
warmingUp.value = false //关闭遮罩
|
||||||
|
// 触发自定义事件通知配置已更新
|
||||||
|
emit('configUpdated')
|
||||||
emit('goToBrowser')
|
emit('goToBrowser')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,10 +109,42 @@ onMounted(() => {
|
|||||||
buildViewMap(props.accountGroups)
|
buildViewMap(props.accountGroups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听本地存储变化,当配置更新时重新加载
|
||||||
|
window.addEventListener('storage', handleStorageChange)
|
||||||
|
// 监听自定义配置更新事件
|
||||||
|
window.addEventListener('config-updated', handleConfigUpdate)
|
||||||
|
|
||||||
// Listeners specific to browser view
|
// Listeners specific to browser view
|
||||||
// ...
|
// ...
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 清理监听器
|
||||||
|
window.removeEventListener('storage', handleStorageChange)
|
||||||
|
window.removeEventListener('config-updated', handleConfigUpdate)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理本地存储变化
|
||||||
|
const handleStorageChange = (event) => {
|
||||||
|
if (event.key === CONFIG_KEY) {
|
||||||
|
loadConfig()
|
||||||
|
// 强制重新构建 viewAccountMap,确保使用最新的账号信息
|
||||||
|
if (props.accountGroups) {
|
||||||
|
buildViewMap(props.accountGroups)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理配置更新事件
|
||||||
|
const handleConfigUpdate = () => {
|
||||||
|
console.log('[YoloBrowser] 收到配置更新事件,重新加载配置')
|
||||||
|
loadConfig()
|
||||||
|
// 强制重新构建 viewAccountMap,确保使用最新的账号信息
|
||||||
|
if (props.accountGroups) {
|
||||||
|
buildViewMap(props.accountGroups)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Original loadConfig logic
|
// Original loadConfig logic
|
||||||
const loadConfig = () => {
|
const loadConfig = () => {
|
||||||
try {
|
try {
|
||||||
@@ -142,7 +174,7 @@ const buildViewMap = (groups) => {
|
|||||||
|
|
||||||
watch(() => props.accountGroups, (newVal) => {
|
watch(() => props.accountGroups, (newVal) => {
|
||||||
if (newVal) buildViewMap(newVal)
|
if (newVal) buildViewMap(newVal)
|
||||||
})
|
}, { deep: true })
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
const handleTabSwitch = async (tab) => {
|
const handleTabSwitch = async (tab) => {
|
||||||
@@ -166,6 +198,12 @@ const handleTabSwitch = async (tab) => {
|
|||||||
|
|
||||||
const handleViewSwitch = async (viewId) => {
|
const handleViewSwitch = async (viewId) => {
|
||||||
selectedViewId.value = viewId
|
selectedViewId.value = viewId
|
||||||
|
// 重新加载配置,确保获取最新的账号信息
|
||||||
|
loadConfig()
|
||||||
|
// 强制重新构建 viewAccountMap,确保使用最新的账号信息
|
||||||
|
if (props.accountGroups) {
|
||||||
|
buildViewMap(props.accountGroups)
|
||||||
|
}
|
||||||
if (isElectron()) {
|
if (isElectron()) {
|
||||||
await window.electronAPI.switchToView(viewId)
|
await window.electronAPI.switchToView(viewId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ async function loadPkList() {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('加载 PK 列表失败', e)
|
console.error('加载 PK 列表失败', e)
|
||||||
ElMessage.error('加载失败,请稍后重试')
|
// ElMessage.error('加载失败,请稍后重试')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// 数据加载完成后,使用 nextTick 强制重新计算滚动位置
|
// 数据加载完成后,使用 nextTick 强制重新计算滚动位置
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ const toggleFilter = (filterName) => {
|
|||||||
const resetTask = async () => {
|
const resetTask = async () => {
|
||||||
try {
|
try {
|
||||||
ElMessageBox.confirm(
|
ElMessageBox.confirm(
|
||||||
'确定要重置任务吗?这将重启 Python 服务并重新加载工作台数据,可能会中断当前正在进行的操作。',
|
'确定要重置任务吗?这将重启服务并中断当前正在进行的获取主播和大哥的任务。',
|
||||||
'重置任务',
|
'重置任务',
|
||||||
{
|
{
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
|
|||||||
Reference in New Issue
Block a user