add screenshot show

This commit is contained in:
geekgeekrun
2026-01-15 12:46:16 +08:00
parent 69ec879967
commit 860847963b
7 changed files with 119 additions and 24 deletions
@@ -17,6 +17,7 @@ import SqlitePluginModule from '@geekgeekrun/sqlite-plugin'
import gtag from '../../utils/gtag'
import GtagPlugin from '../../utils/gtag/GtagPlugin'
import { connectToDaemon, sendToDaemon } from '../OPEN_SETTING_WINDOW/connect-to-daemon'
import { PeriodPushCurrentPageScreenshotPlugin } from '../../utils/screenshot'
const { default: SqlitePlugin } = SqlitePluginModule
const rerunInterval = (() => {
@@ -34,6 +35,7 @@ const initPlugins = (hooks) => {
new DingtalkPlugin(dingTalkAccessToken).apply(hooks)
new SqlitePlugin(getPublicDbFilePath()).apply(hooks)
new GtagPlugin().apply(hooks)
new PeriodPushCurrentPageScreenshotPlugin().apply(hooks)
}
async function checkShouldExit () {
@@ -91,7 +93,8 @@ const runAutoChat = async () => {
}
const hooks = {
puppeteerLaunched: new SyncHook(),
puppeteerLaunched: new SyncHook(['browser']),
pageGotten: new SyncHook(['page']),
pageLoaded: new SyncHook(),
cookieWillSet: new SyncHook(['cookies']),
userInfoResponse: new AsyncSeriesHook(['userInfo']),
@@ -25,6 +25,7 @@ import { JobHireStatus } from '@geekgeekrun/sqlite-plugin/dist/enums';
import dayjs from 'dayjs'
import cheerio from 'cheerio'
import { connectToDaemon, sendToDaemon } from '../OPEN_SETTING_WINDOW/connect-to-daemon'
import { pushCurrentPageScreenshot, SCREENSHOT_INTERVAL_MS } from '../../utils/screenshot'
const throttleIntervalMinutes =
readConfigFile('boss.json').autoReminder?.throttleIntervalMinutes ?? 10
@@ -48,6 +49,16 @@ export const pageMapByName: {
boss?: Page | null
} = {}
async function periodPushCurrentPageScreenshot () {
try {
await pushCurrentPageScreenshot(pageMapByName.boss)
setTimeout(periodPushCurrentPageScreenshot, SCREENSHOT_INTERVAL_MS)
}
catch {}
}
periodPushCurrentPageScreenshot()
async function saveCurrentChatRecord(page) {
const userInfo = await page.evaluate(
'document.querySelector(".main-wrap").__vue__.$store.state.userInfo'
+55
View File
@@ -0,0 +1,55 @@
import { sendToDaemon } from "../flow/OPEN_SETTING_WINDOW/connect-to-daemon"
export const SCREENSHOT_INTERVAL_MS = 2500
export async function pushCurrentPageScreenshot (page) {
try {
if (!page) {
return
}
// 尝试截图当前页面(压缩为 jpeg + base64,避免文件写盘)
const screenshotBase64 = await page.screenshot({
type: 'jpeg',
quality: 60,
encoding: 'base64',
fullPage: false
})
const screenshotAt = Date.now()
await sendToDaemon({
type: 'worker-screenshot',
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
data: {
screenshot: `data:image/jpeg;base64,${screenshotBase64}`,
screenshotAt,
pageUrl: page.url?.() ?? null
}
})
} catch (err) {
// 截图失败不应影响主流程
console.warn('[READ_NO_REPLY_AUTO_REMINDER] pushCurrentPageScreenshot error', err)
}
}
export class PeriodPushCurrentPageScreenshotPlugin {
apply(hooks) {
hooks.pageGotten.tap(
'PeriodPushCurrentPageScreenshotPlugin',
(page) => {
async function periodPushCurrentPageScreenshot () {
try {
if (!page) {
return
}
if (page.isClosed()) {
return
}
await pushCurrentPageScreenshot(page)
setTimeout(periodPushCurrentPageScreenshot, SCREENSHOT_INTERVAL_MS)
}
catch {}
}
periodPushCurrentPageScreenshot()
}
)
}
}
@@ -1,9 +1,20 @@
<template>
<div class="task-item" flex>
<el-card class="task-item">
<div>
<img height="160" width="256" />
<div flex flex-col position-relative>
<div>
<el-button type="danger" size="small" @click="stopTask(task.workerId)">结束任务</el-button>
</div>
<img block :src="task.screenshot" height="190" width="360" />
<div position-absolute bottom-0 right-0 font-size-12px :style="{
backgroundColor: 'rgba(0,0,0,0.7)',
color: '#fff',
padding: '2px 4px 2px 6px',
borderRadius: '8px 0 0 0'
}">{{ task.screenshotAt ? dayjs(task.screenshotAt).format('YYYY-MM-DD HH:mm:ss') : ' - ' }}</div>
</div>
</div>
<div ml-40px>
<div ml-30px>
<dl>
<dt>workerId</dt>
<dd>{{ task.workerId }}</dd>
@@ -28,12 +39,12 @@
<dt>PID</dt>
<dd>{{ task.pid }}</dd>
</dl>
<el-button type="danger" @click="stopTask(task.workerId)">结束任务</el-button>
</div>
</div>
</el-card>
</template>
<script lang="ts" setup>
import dayjs from 'dayjs'
import { PropType } from 'vue'
defineProps({
@@ -50,8 +61,13 @@ const stopTask = async (workerId: string) => {
<style lang="scss" scoped>
.task-item {
width: 1000px;
margin: 0 auto;
font-size: 14px;
overflow: hidden;
::v-deep(.el-card__body) {
display: flex;
}
dl {
margin: 0;
display: flex;
@@ -63,6 +79,7 @@ const stopTask = async (workerId: string) => {
flex: 0 0 6em;
}
dd {
word-break: break-all;
}
}
}