2.5.3
This commit is contained in:
@@ -269,19 +269,14 @@
|
|||||||
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
|
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
|
||||||
import { isElectron } from '../utils/electronBridge'
|
import { isElectron } from '../utils/electronBridge'
|
||||||
import { getPermissions } from '@/utils/storage'
|
import { getPermissions } from '@/utils/storage'
|
||||||
import { usePythonBridge } from '@/utils/pythonBridge'
|
|
||||||
import { ensureHostListGateMonitorRunning, stopHostListGateMonitor, syncHostListGateDecision } from '@/utils/hostListGateMonitor'
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: { type: Boolean, required: true }
|
visible: { type: Boolean, required: true }
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['close', 'save'])
|
const emit = defineEmits(['close', 'save'])
|
||||||
const { controlCheckTask } = usePythonBridge()
|
|
||||||
|
|
||||||
const HOST_LIST_MIN_COUNT_KEY = 'host_list_dialog_min_count'
|
const HOST_LIST_MIN_COUNT_KEY = 'host_list_dialog_min_count'
|
||||||
const HOST_LIST_GATE_ENABLED_SESSION_KEY = 'host_list_dialog_gate_enabled_session'
|
const HOST_LIST_GATE_ENABLED_SESSION_KEY = 'host_list_dialog_gate_enabled_session'
|
||||||
const HOST_LIST_GATE_STATE_SESSION_KEY = 'host_list_dialog_gate_state_session'
|
|
||||||
const HOST_LIST_MONITOR_INTERVAL_MS = 30000
|
|
||||||
|
|
||||||
// Level Options
|
// Level Options
|
||||||
const LEVEL_OPTIONS = [
|
const LEVEL_OPTIONS = [
|
||||||
@@ -337,7 +332,6 @@ const filters = ref({
|
|||||||
const gateEnabled = ref(false)
|
const gateEnabled = ref(false)
|
||||||
const minCount = ref(5)
|
const minCount = ref(5)
|
||||||
const maxCount = ref()
|
const maxCount = ref()
|
||||||
const checkTaskGateState = ref(null)
|
|
||||||
const selectedLevels = ref(new Set())
|
const selectedLevels = ref(new Set())
|
||||||
const showLevelDropdown = ref(false)
|
const showLevelDropdown = ref(false)
|
||||||
|
|
||||||
@@ -404,7 +398,6 @@ watch(() => props.visible, (newVal) => {
|
|||||||
if (newVal) {
|
if (newVal) {
|
||||||
document.body.style.overflow = 'hidden'
|
document.body.style.overflow = 'hidden'
|
||||||
loadLocalGateConfig()
|
loadLocalGateConfig()
|
||||||
if (gateEnabled.value) ensureHostListGateMonitorRunning()
|
|
||||||
loadHosts()
|
loadHosts()
|
||||||
loadConfig()
|
loadConfig()
|
||||||
} else {
|
} else {
|
||||||
@@ -414,7 +407,6 @@ watch(() => props.visible, (newVal) => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadLocalGateConfig()
|
loadLocalGateConfig()
|
||||||
if (gateEnabled.value) ensureHostListGateMonitorRunning()
|
|
||||||
loadConfig()
|
loadConfig()
|
||||||
|
|
||||||
if (props.visible) {
|
if (props.visible) {
|
||||||
@@ -422,9 +414,6 @@ onMounted(() => {
|
|||||||
loadHosts()
|
loadHosts()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gateEnabled.value) {
|
|
||||||
void syncHostListGateDecision(true)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@@ -441,7 +430,6 @@ watch(() => filters.value, async (newFilters) => {
|
|||||||
ordinary: newFilters.ordinary,
|
ordinary: newFilters.ordinary,
|
||||||
minOnlineFans: newFilters.minOnlineFans ? parseInt(newFilters.minOnlineFans) : 0,
|
minOnlineFans: newFilters.minOnlineFans ? parseInt(newFilters.minOnlineFans) : 0,
|
||||||
maxOnlineFans: newFilters.maxOnlineFans ? parseInt(newFilters.maxOnlineFans) : 0,
|
maxOnlineFans: newFilters.maxOnlineFans ? parseInt(newFilters.maxOnlineFans) : 0,
|
||||||
maxAnchorCount: resolveRestrictedMaxAnchorCount(maxCount.value || 9999999),
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log('[HostListDialog] 过滤配置已同步:', newFilters)
|
console.log('[HostListDialog] 过滤配置已同步:', newFilters)
|
||||||
@@ -471,6 +459,15 @@ const loadConfig = async () => {
|
|||||||
// 如果后端返回 9999999,前端显示为空
|
// 如果后端返回 9999999,前端显示为空
|
||||||
maxCount.value = config.filters.maxAnchorCount === 9999999 ? '' : config.filters.maxAnchorCount
|
maxCount.value = config.filters.maxAnchorCount === 9999999 ? '' : config.filters.maxAnchorCount
|
||||||
}
|
}
|
||||||
|
if (config?.filters?.hostListGateEnabled !== undefined) {
|
||||||
|
gateEnabled.value = Boolean(config.filters.hostListGateEnabled)
|
||||||
|
}
|
||||||
|
if (config?.filters?.hostListGateMinCount !== undefined) {
|
||||||
|
const parsedGateMinCount = Number(config.filters.hostListGateMinCount)
|
||||||
|
if (Number.isFinite(parsedGateMinCount) && parsedGateMinCount >= 0) {
|
||||||
|
minCount.value = parsedGateMinCount
|
||||||
|
}
|
||||||
|
}
|
||||||
if (config?.filters?.hostsLevelList) {
|
if (config?.filters?.hostsLevelList) {
|
||||||
// 计算反向等级列表:后端存储的是要过滤的等级,前端需要的是要显示的等级
|
// 计算反向等级列表:后端存储的是要过滤的等级,前端需要的是要显示的等级
|
||||||
const allLevels = LEVEL_OPTIONS.flatMap(parent => parent.children.map(child => child.value))
|
const allLevels = LEVEL_OPTIONS.flatMap(parent => parent.children.map(child => child.value))
|
||||||
@@ -512,14 +509,6 @@ const loadLocalGateConfig = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const savedGateState = sessionStorage.getItem(HOST_LIST_GATE_STATE_SESSION_KEY)
|
|
||||||
if (savedGateState === 'true') {
|
|
||||||
checkTaskGateState.value = true
|
|
||||||
} else if (savedGateState === 'false') {
|
|
||||||
checkTaskGateState.value = false
|
|
||||||
} else {
|
|
||||||
checkTaskGateState.value = null
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[HostListDialog] 读取本地门控配置失败:', e)
|
console.error('[HostListDialog] 读取本地门控配置失败:', e)
|
||||||
}
|
}
|
||||||
@@ -546,57 +535,6 @@ const persistMinCount = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const persistGateState = (value) => {
|
|
||||||
try {
|
|
||||||
if (value === null || value === undefined) {
|
|
||||||
sessionStorage.removeItem(HOST_LIST_GATE_STATE_SESSION_KEY)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionStorage.setItem(HOST_LIST_GATE_STATE_SESSION_KEY, String(value))
|
|
||||||
} catch (e) {
|
|
||||||
console.error('[HostListDialog] 保存门控状态失败:', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const syncControlCheckTaskGate = async (forceSync = false) => {
|
|
||||||
if (!isElectron()) return
|
|
||||||
if (!gateEnabled.value) return
|
|
||||||
|
|
||||||
const hostCount = filteredHosts.value.length
|
|
||||||
const upperLimit = Number(maxCount.value)
|
|
||||||
const lowerLimit = Number(minCount.value)
|
|
||||||
|
|
||||||
let nextState = null
|
|
||||||
|
|
||||||
if (Number.isFinite(upperLimit) && upperLimit >= 0 && hostCount >= upperLimit) {
|
|
||||||
nextState = false
|
|
||||||
} else if (Number.isFinite(lowerLimit) && lowerLimit >= 0 && hostCount < lowerLimit) {
|
|
||||||
nextState = true
|
|
||||||
} else if (checkTaskGateState.value !== null) {
|
|
||||||
nextState = checkTaskGateState.value
|
|
||||||
} else if (forceSync) {
|
|
||||||
nextState = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextState === null) return
|
|
||||||
if (!forceSync && checkTaskGateState.value === nextState) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await controlCheckTask(nextState, true)
|
|
||||||
if (result?.success === false) {
|
|
||||||
console.error('[HostListDialog] controlCheckTask 调用失败:', result.error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
checkTaskGateState.value = nextState
|
|
||||||
persistGateState(nextState)
|
|
||||||
console.log('[HostListDialog] 主播库门控状态已更新:', nextState, '当前数量:', hostCount)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('[HostListDialog] controlCheckTask 异常:', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
const getAllChildLevels = (parentValue) => {
|
const getAllChildLevels = (parentValue) => {
|
||||||
const parent = LEVEL_OPTIONS.find(p => p.value === parentValue)
|
const parent = LEVEL_OPTIONS.find(p => p.value === parentValue)
|
||||||
@@ -687,32 +625,29 @@ const updateMaxCount = async (value) => {
|
|||||||
|
|
||||||
watch(minCount, () => {
|
watch(minCount, () => {
|
||||||
persistMinCount()
|
persistMinCount()
|
||||||
|
|
||||||
|
if (!isElectron()) return
|
||||||
|
|
||||||
|
void window.electronAPI.updateAutomationConfig({
|
||||||
|
filters: {
|
||||||
|
hostListGateMinCount: Number.isFinite(Number(minCount.value)) ? Number(minCount.value) : 5
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(gateEnabled, async (enabled) => {
|
watch(gateEnabled, async (enabled) => {
|
||||||
persistGateEnabled()
|
persistGateEnabled()
|
||||||
|
|
||||||
if (enabled) {
|
if (isElectron()) {
|
||||||
ensureHostListGateMonitorRunning()
|
await window.electronAPI.updateAutomationConfig({
|
||||||
void syncHostListGateDecision(true)
|
filters: {
|
||||||
void syncControlCheckTaskGate(true)
|
hostListGateEnabled: enabled,
|
||||||
return
|
hostListGateMinCount: Number.isFinite(Number(minCount.value)) ? Number(minCount.value) : 5
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTaskGateState.value = null
|
if (enabled) return
|
||||||
persistGateState(null)
|
|
||||||
stopHostListGateMonitor()
|
|
||||||
|
|
||||||
if (!isElectron()) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await controlCheckTask(true, false)
|
|
||||||
if (result?.success === false) {
|
|
||||||
console.error('[HostListDialog] 关闭上下限模式时恢复放行失败:', result.error)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('[HostListDialog] 关闭上下限模式时恢复放行异常:', e)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const filteredHosts = computed(() => {
|
const filteredHosts = computed(() => {
|
||||||
@@ -732,15 +667,6 @@ const filteredHosts = computed(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
|
||||||
[() => filteredHosts.value.length, minCount, maxCount, gateEnabled],
|
|
||||||
() => {
|
|
||||||
if (gateEnabled.value) ensureHostListGateMonitorRunning()
|
|
||||||
void syncHostListGateDecision()
|
|
||||||
void syncControlCheckTaskGate()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const selectedCount = computed(() => selected.value.size)
|
const selectedCount = computed(() => selected.value.size)
|
||||||
|
|
||||||
const toggleSelect = (id) => {
|
const toggleSelect = (id) => {
|
||||||
|
|||||||
@@ -383,9 +383,6 @@ const defaultConfig = {
|
|||||||
switchMinutes: 60,
|
switchMinutes: 60,
|
||||||
prologueList: {},
|
prologueList: {},
|
||||||
needTranslate: false,
|
needTranslate: false,
|
||||||
filters: {
|
|
||||||
maxAnchorCount: 99999
|
|
||||||
},
|
|
||||||
lang: 'en'
|
lang: 'en'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -704,9 +701,6 @@ const handleStart = async (specificGroupIndex) => {
|
|||||||
inviteThreshold: config.value.inviteThreshold,
|
inviteThreshold: config.value.inviteThreshold,
|
||||||
prologueList,
|
prologueList,
|
||||||
needTranslate: config.value.needTranslate, // 添加翻译开关配置
|
needTranslate: config.value.needTranslate, // 添加翻译开关配置
|
||||||
filters: {
|
|
||||||
maxAnchorCount: config.value.filters?.maxAnchorCount !== undefined ? config.value.filters.maxAnchorCount : 100
|
|
||||||
},
|
|
||||||
rotationEnabled: config.value.rotateEnabled,
|
rotationEnabled: config.value.rotateEnabled,
|
||||||
rotationIntervalMinutes: config.value.switchMinutes,
|
rotationIntervalMinutes: config.value.switchMinutes,
|
||||||
currentActiveGroup: activeGroupName,
|
currentActiveGroup: activeGroupName,
|
||||||
|
|||||||
3
src/types/electron.d.ts
vendored
3
src/types/electron.d.ts
vendored
@@ -31,6 +31,9 @@ export interface AutomationConfig {
|
|||||||
hostsLevelList: number[]
|
hostsLevelList: number[]
|
||||||
gold: boolean
|
gold: boolean
|
||||||
ordinary: boolean
|
ordinary: boolean
|
||||||
|
maxAnchorCount?: number
|
||||||
|
hostListGateEnabled?: boolean
|
||||||
|
hostListGateMinCount?: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user