From ec47d9011e591122374db73bb9811ed7e2c130c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B2=A1=E5=A4=8D=E4=B9=A0?= <2353956224@qq.com>
Date: Mon, 12 Jan 2026 16:09:05 +0800
Subject: [PATCH] 3.6
---
src/views/HomeView.vue | 2 +-
src/views/VideoStream.vue | 133 +++++++++++++++++++++++++++++++++++---
2 files changed, 125 insertions(+), 10 deletions(-)
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index d181a81..577fc6a 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -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('3.3.0');
+let version = ref('3.6.0');
onMounted(() => {
diff --git a/src/views/VideoStream.vue b/src/views/VideoStream.vue
index 420c57d..7b64ba4 100644
--- a/src/views/VideoStream.vue
+++ b/src/views/VideoStream.vue
@@ -21,12 +21,16 @@
上传日志
- 监听爬虫
+
+ 设置
+ 剩余 {{ sseCrawlerRemaining }}/{{ sseCrawlerLimit }} 条
+ 设置
+ 剩余 {{ sseBossRemaining }}/{{ sseBossLimit }} 条
@@ -118,7 +122,7 @@
- 分钟换一次
+ 小时换一次
联盟号
@@ -287,18 +291,122 @@ const isLocked = (type) => !!runType.value && runType.value !== type
// —— SSE 开关(分别控制爬虫队列 & 大哥队列)——
const sseCrawlerEnabled = ref(JSON.parse(localStorage.getItem('SSE_CRAWLER_ENABLED') ?? 'true')) // q.tenant.*
const sseBossEnabled = ref(JSON.parse(localStorage.getItem('SSE_BOSS_ENABLED') ?? 'false')) // b.tenant.*
+const sseCrawlerLimit = ref(Number(localStorage.getItem('SSE_CRAWLER_LIMIT') ?? '500'))
+const sseBossLimit = ref(Number(localStorage.getItem('SSE_BOSS_LIMIT') ?? '500'))
+const sseCrawlerRemaining = ref(Number(localStorage.getItem('SSE_CRAWLER_REMAIN') ?? sseCrawlerLimit.value))
+const sseBossRemaining = ref(Number(localStorage.getItem('SSE_BOSS_REMAIN') ?? sseBossLimit.value))
+
+const normalizeSseLimit = (val, fallback) => {
+ const n = Number(val)
+ if (!Number.isFinite(n) || n <= 0) return fallback
+ return Math.floor(n)
+}
watch(sseCrawlerEnabled, v => {
localStorage.setItem('SSE_CRAWLER_ENABLED', JSON.stringify(v))
+ if (v && sseCrawlerRemaining.value <= 0) {
+ sseCrawlerEnabled.value = false
+ ElMessage.warning('请先设置监听爬虫条数')
+ }
})
watch(sseBossEnabled, v => {
localStorage.setItem('SSE_BOSS_ENABLED', JSON.stringify(v))
+ if (v && sseBossRemaining.value <= 0) {
+ sseBossEnabled.value = false
+ ElMessage.warning('请先设置监听大哥条数')
+ }
+})
+
+watch(sseCrawlerLimit, v => {
+ const next = normalizeSseLimit(v, 500)
+ if (next !== v) {
+ sseCrawlerLimit.value = next
+ return
+ }
+ localStorage.setItem('SSE_CRAWLER_LIMIT', String(next))
+})
+
+watch(sseBossLimit, v => {
+ const next = normalizeSseLimit(v, 500)
+ if (next !== v) {
+ sseBossLimit.value = next
+ return
+ }
+ localStorage.setItem('SSE_BOSS_LIMIT', String(next))
+})
+
+watch(sseCrawlerRemaining, v => {
+ const next = normalizeSseLimit(v, 0)
+ if (next !== v) {
+ sseCrawlerRemaining.value = next
+ return
+ }
+ localStorage.setItem('SSE_CRAWLER_REMAIN', String(next))
+})
+
+watch(sseBossRemaining, v => {
+ const next = normalizeSseLimit(v, 0)
+ if (next !== v) {
+ sseBossRemaining.value = next
+ return
+ }
+ localStorage.setItem('SSE_BOSS_REMAIN', String(next))
})
// 至少有一个开着才算启用 SSE
const sseAnyEnabled = computed(() => sseCrawlerEnabled.value || sseBossEnabled.value)
+const bumpSseCount = (type) => {
+ const isCrawler = type === 'crawler'
+ const remainingRef = isCrawler ? sseCrawlerRemaining : sseBossRemaining
+ if (remainingRef.value <= 0) {
+ if (isCrawler) {
+ sseCrawlerEnabled.value = false
+ } else {
+ sseBossEnabled.value = false
+ }
+ return false
+ }
+
+ remainingRef.value -= 1
+ if (remainingRef.value <= 0) {
+ if (isCrawler) {
+ sseCrawlerEnabled.value = false
+ } else {
+ sseBossEnabled.value = false
+ }
+ ElMessage.info(`监听${isCrawler ? '爬虫' : '大哥'}条数已用完,已自动关闭`)
+ }
+ return true
+}
+
+const setSseLimit = async (type) => {
+ const isCrawler = type === 'crawler'
+ const label = isCrawler ? '爬虫' : '大哥'
+ const limitRef = isCrawler ? sseCrawlerLimit : sseBossLimit
+ const remainingRef = isCrawler ? sseCrawlerRemaining : sseBossRemaining
+
+ try {
+ const { value } = await ElMessageBox.prompt(
+ `请输入监听${label}条数`,
+ '设置监听条数',
+ {
+ inputValue: String(limitRef.value || 0),
+ inputPattern: /^[1-9]\d*$/,
+ inputErrorMessage: '请输入正整数',
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ }
+ )
+ const next = normalizeSseLimit(value, limitRef.value || 500)
+ limitRef.value = next
+ remainingRef.value = next
+ } catch (e) {
+ // 用户取消
+ }
+}
+
// 互斥按钮的样式:激活=红,锁定=半透明且禁点
const ctrlStyle = (type) => {
const lockedByMode = isLocked(type)
@@ -797,6 +905,11 @@ onMounted(async () => {
// 2️⃣ 按开关过滤
if (fromCrawler && !sseCrawlerEnabled.value) return
if (fromBoss && !sseBossEnabled.value) return
+ if (fromCrawler) {
+ if (!bumpSseCount('crawler')) return
+ } else if (fromBoss) {
+ if (!bumpSseCount('boss')) return
+ }
if (isUnknown && !sseCrawlerEnabled.value) return // 老数据当爬虫看
// 3️⃣ 按来源取不同字段
@@ -1226,8 +1339,8 @@ function startScheduleLoop() {
const now = Date.now()
if (!lastInterruptTs) lastInterruptTs = now // 首次初始化
- // const due = now - lastInterruptTs >= interruptEveryMin.value * 60_000 * 60
- const due = now - lastInterruptTs >= interruptEveryMin.value * 60_000
+ const due = now - lastInterruptTs >= interruptEveryMin.value * 60_000 * 60
+ // const due = now - lastInterruptTs >= interruptEveryMin.value * 60_000
console.log(
'due=', due,
@@ -1658,11 +1771,13 @@ const markPendingForOffline = (ids) => {
};
const onToggleCrawler = (val) => {
- if (val) sseBossEnabled.value = false
-}
+ if (val) sseBossEnabled.value = false;
+};
+
const onToggleBoss = (val) => {
- if (val) sseCrawlerEnabled.value = false
-}
+ if (val) sseCrawlerEnabled.value = false;
+};
+
function timestampToTime(timestamp_ms) {
const date = new Date(timestamp_ms);