mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-05 15:38:46 +08:00
Merge branch 'feature/ui'
This commit is contained in:
@@ -699,7 +699,7 @@ async function toRecommendPage (hooks) {
|
|||||||
hooks.pageLoaded?.call()
|
hooks.pageLoaded?.call()
|
||||||
|
|
||||||
let userInfoResponse = await userInfoPromise
|
let userInfoResponse = await userInfoPromise
|
||||||
await hooks.userInfoResponse?.promise(userInfoResponse)
|
await hooks.userInfoResponse?.promise({ userInfoResponse, browser })
|
||||||
if (userInfoResponse?.code !== 0) {
|
if (userInfoResponse?.code !== 0) {
|
||||||
autoStartChatEventBus.emit('LOGIN_STATUS_INVALID', {
|
autoStartChatEventBus.emit('LOGIN_STATUS_INVALID', {
|
||||||
userInfoResponse
|
userInfoResponse
|
||||||
@@ -1713,7 +1713,7 @@ export async function mainLoop (hooks) {
|
|||||||
//set cookies
|
//set cookies
|
||||||
const bossCookies = readStorageFile('boss-cookies.json')
|
const bossCookies = readStorageFile('boss-cookies.json')
|
||||||
const bossLocalStorage = readStorageFile('boss-local-storage.json')
|
const bossLocalStorage = readStorageFile('boss-local-storage.json')
|
||||||
await hooks.cookieWillSet?.promise(bossCookies)
|
await hooks.cookieWillSet?.promise({ cookies: bossCookies, browser })
|
||||||
for(let i = 0; i < bossCookies.length; i++){
|
for(let i = 0; i < bossCookies.length; i++){
|
||||||
if (Object.hasOwn(bossCookies[i], 'sameSite')) {
|
if (Object.hasOwn(bossCookies[i], 'sameSite')) {
|
||||||
bossCookies[i].sameSite = 'unspecified'
|
bossCookies[i].sameSite = 'unspecified'
|
||||||
|
|||||||
+123
-114
@@ -1,125 +1,134 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { PuppeteerExtraPlugin } = require("puppeteer-extra-plugin");
|
const { PuppeteerExtraPlugin } = require("puppeteer-extra-plugin");
|
||||||
async function handle(p) {
|
|
||||||
await p.evaluateOnNewDocument(() => {
|
|
||||||
(() => {
|
|
||||||
"use strict";
|
|
||||||
/* -------------------------------------------------------
|
|
||||||
* 1. 保存原生 Function.prototype.toString
|
|
||||||
* ----------------------------------------------------- */
|
|
||||||
const nativeFunctionToString = Function.prototype.toString;
|
|
||||||
|
|
||||||
/* -------------------------------------------------------
|
// 定义脚本内容,避免重复定义
|
||||||
* 2. WeakMap:函数 → 伪原生源码
|
const stealthScript = () => {
|
||||||
* ----------------------------------------------------- */
|
"use strict";
|
||||||
const nativeSourceMap = new WeakMap();
|
/* -------------------------------------------------------
|
||||||
|
* 1. 保存原生 Function.prototype.toString
|
||||||
|
* ----------------------------------------------------- */
|
||||||
|
const nativeFunctionToString = Function.prototype.toString;
|
||||||
|
|
||||||
/* -------------------------------------------------------
|
/* -------------------------------------------------------
|
||||||
* 3. 注册伪原生源码
|
* 2. WeakMap:函数 → 伪原生源码
|
||||||
* ----------------------------------------------------- */
|
* ----------------------------------------------------- */
|
||||||
const registerNativeSource = (fn, source) => {
|
const nativeSourceMap = new WeakMap();
|
||||||
try {
|
|
||||||
nativeSourceMap.set(fn, source);
|
|
||||||
} catch (_) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* -------------------------------------------------------
|
/* -------------------------------------------------------
|
||||||
* 4. 劫持 Function.prototype.toString
|
* 3. 注册伪原生源码
|
||||||
* ----------------------------------------------------- */
|
* ----------------------------------------------------- */
|
||||||
Object.defineProperty(Function.prototype, "toString", {
|
const registerNativeSource = (fn, source) => {
|
||||||
configurable: true,
|
try {
|
||||||
writable: true,
|
nativeSourceMap.set(fn, source);
|
||||||
value: function toString() {
|
} catch (_) {}
|
||||||
if (nativeSourceMap.has(this)) {
|
};
|
||||||
return nativeSourceMap.get(this);
|
|
||||||
}
|
|
||||||
return nativeFunctionToString.call(this);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -------------------------------------------------------
|
/* -------------------------------------------------------
|
||||||
* 5. 伪装 Function.prototype.toString 自身
|
* 4. 劫持 Function.prototype.toString
|
||||||
* ----------------------------------------------------- */
|
* ----------------------------------------------------- */
|
||||||
registerNativeSource(
|
Object.defineProperty(Function.prototype, "toString", {
|
||||||
Function.prototype.toString,
|
configurable: true,
|
||||||
nativeFunctionToString.toString(),
|
writable: true,
|
||||||
);
|
value: function toString() {
|
||||||
|
if (nativeSourceMap.has(this)) {
|
||||||
/* -------------------------------------------------------
|
return nativeSourceMap.get(this);
|
||||||
* 6. stealthify:包装函数但保持“原生外观”
|
}
|
||||||
* ----------------------------------------------------- */
|
return nativeFunctionToString.call(this);
|
||||||
const stealthify = (obj, prop, handler) => {
|
},
|
||||||
const original = obj[prop];
|
|
||||||
if (typeof original !== "function") return;
|
|
||||||
|
|
||||||
const wrapped = function (...args) {
|
|
||||||
return handler.call(this, original, args);
|
|
||||||
};
|
|
||||||
const namePropertyDescriptor = Object.getOwnPropertyDescriptor(
|
|
||||||
wrapped,
|
|
||||||
"name",
|
|
||||||
);
|
|
||||||
// 处理函数 name 属性
|
|
||||||
Object.defineProperty(wrapped, "name", {
|
|
||||||
...namePropertyDescriptor,
|
|
||||||
value: prop,
|
|
||||||
});
|
|
||||||
// 保留 prototype(某些函数有)
|
|
||||||
try {
|
|
||||||
Object.setPrototypeOf(wrapped, Object.getPrototypeOf(original));
|
|
||||||
} catch (_) {}
|
|
||||||
|
|
||||||
// 注册伪原生源码(直接复用原函数的 native 表现)
|
|
||||||
registerNativeSource(wrapped, nativeFunctionToString.call(original));
|
|
||||||
|
|
||||||
// 用 defineProperty 保持 descriptor 接近原生
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(obj, prop);
|
|
||||||
Object.defineProperty(obj, prop, {
|
|
||||||
...desc,
|
|
||||||
value: wrapped,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/* -------------------------------------------------------
|
|
||||||
* 7. 示例:stealth console.log / debug / info
|
|
||||||
* ----------------------------------------------------- */
|
|
||||||
const filterConsoleArgs = (args) =>
|
|
||||||
args.map((arg) => {
|
|
||||||
if (arg && typeof arg === "object") {
|
|
||||||
// 防止 getter / Proxy / 大对象触发
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return arg;
|
|
||||||
});
|
|
||||||
|
|
||||||
[
|
|
||||||
"log",
|
|
||||||
"debug",
|
|
||||||
"info",
|
|
||||||
"warn",
|
|
||||||
"error",
|
|
||||||
"dir",
|
|
||||||
"table",
|
|
||||||
"debug",
|
|
||||||
].forEach((name) => {
|
|
||||||
stealthify(console, name, (original, args) => {
|
|
||||||
// ❗不传递原始对象,避免 DevTools / CDP 展开
|
|
||||||
return original.apply(console, filterConsoleArgs(args));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -------------------------------------------------------
|
|
||||||
* 8. 防御性补丁(可选但强烈建议)
|
|
||||||
* ----------------------------------------------------- */
|
|
||||||
|
|
||||||
// 防止检测 toString 被替换
|
|
||||||
registerNativeSource(
|
|
||||||
registerNativeSource,
|
|
||||||
"function registerNativeSource() { [native code] }",
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------------------
|
||||||
|
* 5. 伪装 Function.prototype.toString 自身
|
||||||
|
* ----------------------------------------------------- */
|
||||||
|
registerNativeSource(
|
||||||
|
Function.prototype.toString,
|
||||||
|
nativeFunctionToString.toString(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/* -------------------------------------------------------
|
||||||
|
* 6. stealthify:包装函数但保持"原生外观"
|
||||||
|
* ----------------------------------------------------- */
|
||||||
|
const stealthify = (obj, prop, handler) => {
|
||||||
|
const original = obj[prop];
|
||||||
|
if (typeof original !== "function") return;
|
||||||
|
|
||||||
|
const wrapped = function (...args) {
|
||||||
|
return handler.call(this, original, args);
|
||||||
|
};
|
||||||
|
const namePropertyDescriptor = Object.getOwnPropertyDescriptor(
|
||||||
|
wrapped,
|
||||||
|
"name",
|
||||||
|
);
|
||||||
|
// 处理函数 name 属性
|
||||||
|
Object.defineProperty(wrapped, "name", {
|
||||||
|
...namePropertyDescriptor,
|
||||||
|
value: prop,
|
||||||
|
});
|
||||||
|
// 保留 prototype(某些函数有)
|
||||||
|
try {
|
||||||
|
Object.setPrototypeOf(wrapped, Object.getPrototypeOf(original));
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
// 注册伪原生源码(直接复用原函数的 native 表现)
|
||||||
|
registerNativeSource(wrapped, nativeFunctionToString.call(original));
|
||||||
|
|
||||||
|
// 用 defineProperty 保持 descriptor 接近原生
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(obj, prop);
|
||||||
|
Object.defineProperty(obj, prop, {
|
||||||
|
...desc,
|
||||||
|
value: wrapped,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------
|
||||||
|
* 7. 示例:stealth console.log / debug / info
|
||||||
|
* ----------------------------------------------------- */
|
||||||
|
const filterConsoleArgs = (args) =>
|
||||||
|
args.map((arg) => {
|
||||||
|
if (arg && typeof arg === "object") {
|
||||||
|
// 防止 getter / Proxy / 大对象触发
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
});
|
||||||
|
|
||||||
|
[
|
||||||
|
"log",
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"warn",
|
||||||
|
"error",
|
||||||
|
"dir",
|
||||||
|
"table",
|
||||||
|
"debug",
|
||||||
|
].forEach((name) => {
|
||||||
|
stealthify(console, name, (original, args) => {
|
||||||
|
// ❗不传递原始对象,避免 DevTools / CDP 展开
|
||||||
|
return original.apply(console, filterConsoleArgs(args));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------------------
|
||||||
|
* 8. 防御性补丁(可选但强烈建议)
|
||||||
|
* ----------------------------------------------------- */
|
||||||
|
|
||||||
|
// 防止检测 toString 被替换
|
||||||
|
registerNativeSource(
|
||||||
|
registerNativeSource,
|
||||||
|
"function registerNativeSource() { [native code] }",
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handle(p) {
|
||||||
|
// 1. 立即执行一次(针对当前已有的文档,防止错过)
|
||||||
|
try {
|
||||||
|
await p.evaluate(stealthScript);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果当前页面还没准备好,忽略错误
|
||||||
|
}
|
||||||
|
// 2. 注册为新文档脚本(针对未来的导航)
|
||||||
|
await p.evaluateOnNewDocument(stealthScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Plugin extends PuppeteerExtraPlugin {
|
class Plugin extends PuppeteerExtraPlugin {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@geekgeekrun/puppeteer-extra-plugin-laodeng",
|
"name": "@geekgeekrun/puppeteer-extra-plugin-laodeng",
|
||||||
"version": "0.0.1",
|
"version": "0.0.2",
|
||||||
"description": "laodeng",
|
"description": "laodeng",
|
||||||
"main": "./index.js",
|
"main": "./index.js",
|
||||||
"author": "geekgeekrun",
|
"author": "geekgeekrun",
|
||||||
|
|||||||
+22
-1
@@ -103,7 +103,7 @@ const server = net.createServer((socket) => {
|
|||||||
|
|
||||||
// 处理消息
|
// 处理消息
|
||||||
function handleMessage(socket, message) {
|
function handleMessage(socket, message) {
|
||||||
console.log('收到消息:', message);
|
message.type !== 'get-status' && console.log('收到消息:', message);
|
||||||
const _callbackUuid = message._callbackUuid
|
const _callbackUuid = message._callbackUuid
|
||||||
if (message.type === 'ping') {
|
if (message.type === 'ping') {
|
||||||
sendResponse(socket, _callbackUuid, {
|
sendResponse(socket, _callbackUuid, {
|
||||||
@@ -143,6 +143,23 @@ function handleMessage(socket, message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
case 'worker-to-gui-message': {
|
case 'worker-to-gui-message': {
|
||||||
|
// 将 prerequisite step 状态写入 worker 的 runtimeStorage
|
||||||
|
if (
|
||||||
|
workerInfo &&
|
||||||
|
message.data?.type === 'prerequisite-step-by-step-check' &&
|
||||||
|
message.data?.step?.id
|
||||||
|
) {
|
||||||
|
workerInfo.runtimeStorage = workerInfo.runtimeStorage || {}
|
||||||
|
workerInfo.runtimeStorage.stepStatusMapByStepId =
|
||||||
|
workerInfo.runtimeStorage.stepStatusMapByStepId || {}
|
||||||
|
workerInfo.runtimeStorage.stepStatusMapByStepId[
|
||||||
|
message.data.step.id
|
||||||
|
] = {
|
||||||
|
step: message.data.step,
|
||||||
|
runRecordId: message.data.runRecordId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 转发工具进程消息到GUI客户端
|
// 转发工具进程消息到GUI客户端
|
||||||
broadcastToGUI({
|
broadcastToGUI({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
@@ -329,6 +346,9 @@ function startWorker({ workerId, command, args, env }, restartCount = 0) {
|
|||||||
status: 'running',
|
status: 'running',
|
||||||
startTime: Date.now(),
|
startTime: Date.now(),
|
||||||
restartCount, // 使用传入的重启次数
|
restartCount, // 使用传入的重启次数
|
||||||
|
runtimeStorage: {
|
||||||
|
stepStatusMapByStepId: {}
|
||||||
|
},
|
||||||
// socket: null, // 工具进程的TCP连接,稍后由工具进程注册
|
// socket: null, // 工具进程的TCP连接,稍后由工具进程注册
|
||||||
// lastHeartbeat: null,
|
// lastHeartbeat: null,
|
||||||
command,
|
command,
|
||||||
@@ -390,6 +410,7 @@ function getWorkersStatus() {
|
|||||||
status: workerInfo.status,
|
status: workerInfo.status,
|
||||||
uptime: Date.now() - workerInfo.startTime,
|
uptime: Date.now() - workerInfo.startTime,
|
||||||
restartCount: workerInfo.restartCount || 0,
|
restartCount: workerInfo.restartCount || 0,
|
||||||
|
runtimeStorage: workerInfo.runtimeStorage || {},
|
||||||
// connected: workerInfo.socket !== null && !workerInfo.socket.destroyed,
|
// connected: workerInfo.socket !== null && !workerInfo.socket.destroyed,
|
||||||
// lastHeartbeat: workerInfo.lastHeartbeat,
|
// lastHeartbeat: workerInfo.lastHeartbeat,
|
||||||
command: workerInfo.command,
|
command: workerInfo.command,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { AUTO_CHAT_ERROR_EXIT_CODE } from './enums.mjs'
|
|||||||
const rerunInterval = (() => {
|
const rerunInterval = (() => {
|
||||||
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
||||||
if (isNaN(v)) {
|
if (isNaN(v)) {
|
||||||
v = 3000
|
v = 5000
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const {
|
|||||||
const rerunInterval = (() => {
|
const rerunInterval = (() => {
|
||||||
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
||||||
if (isNaN(v)) {
|
if (isNaN(v)) {
|
||||||
v = 3000
|
v = 5000
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default class SqlitePlugin {
|
|||||||
)
|
)
|
||||||
hooks.userInfoResponse.tapPromise(
|
hooks.userInfoResponse.tapPromise(
|
||||||
"SqlitePlugin",
|
"SqlitePlugin",
|
||||||
async (userInfoResponse) => {
|
async ({ userInfoResponse } = {}) => {
|
||||||
if (!userInfoResponse || userInfoResponse.code !== 0) {
|
if (!userInfoResponse || userInfoResponse.code !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,14 +63,16 @@ export default defineConfig({
|
|||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: []
|
external: []
|
||||||
},
|
},
|
||||||
minify: process.env.NODE_ENV === 'development' ? undefined : 'terser'
|
minify: process.env.NODE_ENV === 'development' ? undefined : 'terser',
|
||||||
|
watch: process.env.NODE_ENV === 'development' ? {} : undefined
|
||||||
},
|
},
|
||||||
plugins: mainPlugins
|
plugins: mainPlugins
|
||||||
},
|
},
|
||||||
preload: {
|
preload: {
|
||||||
plugins: preloadPlugins,
|
plugins: preloadPlugins,
|
||||||
build: {
|
build: {
|
||||||
minify: process.env.NODE_ENV === 'development' ? undefined : 'terser'
|
minify: process.env.NODE_ENV === 'development' ? undefined : 'terser',
|
||||||
|
watch: process.env.NODE_ENV === 'development' ? {} : undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "geekgeekrun-ui",
|
"name": "geekgeekrun-ui",
|
||||||
"version": "0.17.3",
|
"version": "0.17.4",
|
||||||
"description": "BOSS 炸弹 - 自动开聊BOSS,助力每位打工人求职!",
|
"description": "BOSS 炸弹 - 自动开聊BOSS,助力每位打工人求职!",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "geekgeekrun",
|
"author": "geekgeekrun",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "0.17.3",
|
"version": "0.17.4",
|
||||||
"buildVersion": 40,
|
"buildVersion": 41,
|
||||||
"buildTime": 1775201731866,
|
"buildTime": 1777732024939,
|
||||||
"buildHash": "09a1b4b91804ebc8202c16d3e2976a91ab89d09d",
|
"buildHash": "9d3408d1f3fd5bba0e44736233408e2be2e48536",
|
||||||
"name": "geekgeekrun-ui"
|
"name": "geekgeekrun-ui"
|
||||||
}
|
}
|
||||||
@@ -3,17 +3,37 @@ import minimist from 'minimist'
|
|||||||
import { loginWithCookieAssistant } from './login-with-cookie-assistant'
|
import { loginWithCookieAssistant } from './login-with-cookie-assistant'
|
||||||
import { checkCookieListFormat } from '../../common/utils/cookie'
|
import { checkCookieListFormat } from '../../common/utils/cookie'
|
||||||
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
|
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
|
||||||
import { readStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
import {
|
||||||
|
readStorageFile,
|
||||||
|
writeStorageFile
|
||||||
|
} from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
||||||
|
|
||||||
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
|
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
|
||||||
export class CookieInvalidHandlePlugin {
|
export class CookieInvalidHandlePlugin {
|
||||||
apply(hooks) {
|
apply(hooks) {
|
||||||
hooks.cookieWillSet.tapPromise('CookieInvalidHandlePlugin', async (cookies) => {
|
hooks.cookieWillSet.tapPromise('CookieInvalidHandlePlugin', async ({ cookies, browser } = {}) => {
|
||||||
let isValid = checkCookieListFormat(cookies)
|
let isValid = checkCookieListFormat(cookies)
|
||||||
while (!isValid) {
|
while (!isValid) {
|
||||||
|
try {
|
||||||
|
browser && (await browser.close())
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`close browser failed`, err)
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// popup login dialog, then update login status
|
// popup login dialog, then update login status
|
||||||
await loginWithCookieAssistant()
|
let app
|
||||||
|
try {
|
||||||
|
app = (await import('electron')).app
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
// popup login dialog, then update login status
|
||||||
|
try {
|
||||||
|
await app?.dock?.show()
|
||||||
|
await loginWithCookieAssistant()
|
||||||
|
} finally {
|
||||||
|
await app?.dock?.hide()
|
||||||
|
}
|
||||||
await sleep(2000)
|
await sleep(2000)
|
||||||
const newCookies = readStorageFile('boss-cookies.json')
|
const newCookies = readStorageFile('boss-cookies.json')
|
||||||
isValid = checkCookieListFormat(newCookies)
|
isValid = checkCookieListFormat(newCookies)
|
||||||
@@ -27,8 +47,9 @@ export class CookieInvalidHandlePlugin {
|
|||||||
if (e?.message === 'USER_CANCELLED_LOGIN') {
|
if (e?.message === 'USER_CANCELLED_LOGIN') {
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'basic-cookie-check',
|
id: 'basic-cookie-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -42,8 +63,9 @@ export class CookieInvalidHandlePlugin {
|
|||||||
}
|
}
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'basic-cookie-check',
|
id: 'basic-cookie-check',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
@@ -52,12 +74,13 @@ export class CookieInvalidHandlePlugin {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
hooks.userInfoResponse.tapPromise('CookieInvalidHandlePlugin', async (userInfoResponse) => {
|
hooks.userInfoResponse.tapPromise('CookieInvalidHandlePlugin', async ({ userInfoResponse, browser } = {}) => {
|
||||||
if (userInfoResponse.code === 0) {
|
if (userInfoResponse.code === 0) {
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'login-status-check',
|
id: 'login-status-check',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
@@ -67,15 +90,34 @@ export class CookieInvalidHandlePlugin {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
browser && (await browser.close())
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`close browser failed`, err)
|
||||||
|
}
|
||||||
|
await writeStorageFile('boss-cookies.json', [])
|
||||||
try {
|
try {
|
||||||
// popup login dialog, then update login status
|
// popup login dialog, then update login status
|
||||||
await loginWithCookieAssistant()
|
let app
|
||||||
|
try {
|
||||||
|
app = (await import('electron')).app
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
// popup login dialog, then update login status
|
||||||
|
try {
|
||||||
|
await app?.dock?.show()
|
||||||
|
await loginWithCookieAssistant()
|
||||||
|
} finally {
|
||||||
|
await app?.dock?.hide()
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e?.message === 'USER_CANCELLED_LOGIN') {
|
if (e?.message === 'USER_CANCELLED_LOGIN') {
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'login-status-check',
|
id: 'login-status-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ process.on('SIGTERM', () => {
|
|||||||
const rerunInterval = (() => {
|
const rerunInterval = (() => {
|
||||||
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
||||||
if (isNaN(v)) {
|
if (isNaN(v)) {
|
||||||
v = 3000
|
v = 5000
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
@@ -66,8 +66,9 @@ const runAutoChat = async () => {
|
|||||||
})
|
})
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'puppeteer-executable-check',
|
id: 'puppeteer-executable-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -80,8 +81,9 @@ const runAutoChat = async () => {
|
|||||||
}
|
}
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'puppeteer-executable-check',
|
id: 'puppeteer-executable-check',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
@@ -183,8 +185,9 @@ export const waitForProcessHandShakeAndRunAutoChat = async () => {
|
|||||||
)
|
)
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'worker-launch',
|
id: 'worker-launch',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ const onlyRemindBossWithoutBlockCompanyName =
|
|||||||
readConfigFile('boss.json').autoReminder?.onlyRemindBossWithoutBlockCompanyName ??
|
readConfigFile('boss.json').autoReminder?.onlyRemindBossWithoutBlockCompanyName ??
|
||||||
!!blockCompanyNameRegExp
|
!!blockCompanyNameRegExp
|
||||||
|
|
||||||
const openContentSource = readConfigFile('boss.json').autoReminder?.openContentSource ?? OPEN_CONTENT_SOURCE.CONSTANT_CONTENT
|
const openContentSource =
|
||||||
|
readConfigFile('boss.json').autoReminder?.openContentSource ??
|
||||||
|
OPEN_CONTENT_SOURCE.CONSTANT_CONTENT
|
||||||
const constantOpenContent = (() => {
|
const constantOpenContent = (() => {
|
||||||
let constantOpenContent = readConfigFile('boss.json').autoReminder?.constantOpenContent ?? ''
|
let constantOpenContent = readConfigFile('boss.json').autoReminder?.constantOpenContent ?? ''
|
||||||
if (constantOpenContent?.trim?.()) {
|
if (constantOpenContent?.trim?.()) {
|
||||||
@@ -303,7 +305,17 @@ const mainLoop = async () => {
|
|||||||
let cookieCheckResult = checkCookieListFormat(bossCookies)
|
let cookieCheckResult = checkCookieListFormat(bossCookies)
|
||||||
while (!cookieCheckResult) {
|
while (!cookieCheckResult) {
|
||||||
try {
|
try {
|
||||||
await loginWithCookieAssistant()
|
browser && (await browser.close())
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`close browser failed`, err)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
await app.dock?.show()
|
||||||
|
await loginWithCookieAssistant()
|
||||||
|
} finally {
|
||||||
|
await app.dock?.hide()
|
||||||
|
}
|
||||||
bossCookies = readStorageFile('boss-cookies.json')
|
bossCookies = readStorageFile('boss-cookies.json')
|
||||||
cookieCheckResult = checkCookieListFormat(bossCookies)
|
cookieCheckResult = checkCookieListFormat(bossCookies)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -314,8 +326,9 @@ const mainLoop = async () => {
|
|||||||
})
|
})
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'basic-cookie-check',
|
id: 'basic-cookie-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -328,8 +341,9 @@ const mainLoop = async () => {
|
|||||||
}
|
}
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'basic-cookie-check',
|
id: 'basic-cookie-check',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
@@ -356,8 +370,17 @@ const mainLoop = async () => {
|
|||||||
if (currentPageUrl.startsWith('https://www.zhipin.com/web/user/')) {
|
if (currentPageUrl.startsWith('https://www.zhipin.com/web/user/')) {
|
||||||
writeStorageFile('boss-cookies.json', [])
|
writeStorageFile('boss-cookies.json', [])
|
||||||
try {
|
try {
|
||||||
// popup login dialog, then update login status
|
browser && (await browser.close())
|
||||||
await loginWithCookieAssistant()
|
} catch (err) {
|
||||||
|
console.log(`close browser failed`, err)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
await app.dock?.show()
|
||||||
|
await loginWithCookieAssistant()
|
||||||
|
} finally {
|
||||||
|
await app.dock?.hide()
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await dialog.showMessageBox({
|
await dialog.showMessageBox({
|
||||||
type: `error`,
|
type: `error`,
|
||||||
@@ -366,8 +389,9 @@ const mainLoop = async () => {
|
|||||||
})
|
})
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'login-status-check',
|
id: 'login-status-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -385,8 +409,9 @@ const mainLoop = async () => {
|
|||||||
) {
|
) {
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'login-status-check',
|
id: 'login-status-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -418,8 +443,9 @@ const mainLoop = async () => {
|
|||||||
await storeStorage(pageMapByName.boss)
|
await storeStorage(pageMapByName.boss)
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'login-status-check',
|
id: 'login-status-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -432,8 +458,9 @@ const mainLoop = async () => {
|
|||||||
}
|
}
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'login-status-check',
|
id: 'login-status-check',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
@@ -656,7 +683,7 @@ const mainLoop = async () => {
|
|||||||
const rerunInterval = (() => {
|
const rerunInterval = (() => {
|
||||||
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
|
||||||
if (isNaN(v)) {
|
if (isNaN(v)) {
|
||||||
v = 3000
|
v = 5000
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
@@ -681,8 +708,9 @@ export async function runEntry() {
|
|||||||
)
|
)
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'worker-launch',
|
id: 'worker-launch',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
@@ -707,8 +735,9 @@ export async function runEntry() {
|
|||||||
})
|
})
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'puppeteer-executable-check',
|
id: 'puppeteer-executable-check',
|
||||||
status: 'rejected'
|
status: 'rejected'
|
||||||
@@ -720,8 +749,9 @@ export async function runEntry() {
|
|||||||
}
|
}
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
|
workerId: process.env.GEEKGEEKRUND_WORKER_ID,
|
||||||
data: {
|
data: {
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
type: 'prerequisite-step-by-step-check',
|
||||||
step: {
|
step: {
|
||||||
id: 'puppeteer-executable-check',
|
id: 'puppeteer-executable-check',
|
||||||
status: 'fulfilled'
|
status: 'fulfilled'
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// import { useTaskManagerStore } from '@renderer/store'
|
import { useTaskManagerStore } from '@renderer/store'
|
||||||
import { getAutoStartChatSteps } from '../../../../common/prerequisite-step-by-step-check'
|
import { getAutoStartChatSteps } from '../../../../common/prerequisite-step-by-step-check'
|
||||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||||
import {
|
import {
|
||||||
@@ -71,12 +71,12 @@ const props = defineProps({
|
|||||||
type: Number
|
type: Number
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// const taskManagerStore = useTaskManagerStore()
|
const taskManagerStore = useTaskManagerStore()
|
||||||
// const runningTaskInfo = computed(() => {
|
const runningTaskInfo = computed(() => {
|
||||||
// return taskManagerStore.runningTasks?.find((it) => {
|
return taskManagerStore.runningTasks?.find((it) => {
|
||||||
// return it.workerId === props.workerId
|
return it.workerId === props.workerId
|
||||||
// })
|
})
|
||||||
// })
|
})
|
||||||
const steps = ref([])
|
const steps = ref([])
|
||||||
const stepsForRender = computed(() => {
|
const stepsForRender = computed(() => {
|
||||||
const clonedSteps = JSON.parse(JSON.stringify(steps.value))
|
const clonedSteps = JSON.parse(JSON.stringify(steps.value))
|
||||||
@@ -101,9 +101,43 @@ function fillEmptySteps() {
|
|||||||
steps.value = arr
|
steps.value = arr
|
||||||
currentRunningStatus.value = RUNNING_STATUS_ENUM.RUNNING
|
currentRunningStatus.value = RUNNING_STATUS_ENUM.RUNNING
|
||||||
}
|
}
|
||||||
watch(() => props.runRecordId, fillEmptySteps, {
|
|
||||||
immediate: true
|
function applyRuntimeStepStatus() {
|
||||||
})
|
const task = runningTaskInfo.value
|
||||||
|
if (!task?.runtimeStorage?.stepStatusMapByStepId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const stepMap = task.runtimeStorage.stepStatusMapByStepId
|
||||||
|
steps.value = getAutoStartChatSteps().map((step) => {
|
||||||
|
const saved = stepMap[step.id]
|
||||||
|
if (!saved || !saved.step) {
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...step,
|
||||||
|
status: saved.step.status
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.runRecordId,
|
||||||
|
() => {
|
||||||
|
fillEmptySteps()
|
||||||
|
applyRuntimeStepStatus()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => taskManagerStore.runningTasks,
|
||||||
|
() => {
|
||||||
|
applyRuntimeStepStatus()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
watch(
|
watch(
|
||||||
() => stepsForRender.value,
|
() => stepsForRender.value,
|
||||||
(v) => {
|
(v) => {
|
||||||
@@ -121,10 +155,7 @@ watch(
|
|||||||
|
|
||||||
const { ipcRenderer } = electron
|
const { ipcRenderer } = electron
|
||||||
function messageHandler(ev, { data }) {
|
function messageHandler(ev, { data }) {
|
||||||
if (
|
if (data.type !== 'prerequisite-step-by-step-check' || data.runRecordId !== props.runRecordId) {
|
||||||
data.type !== 'prerequisite-step-by-step-checkstep-by-step-check' ||
|
|
||||||
data.runRecordId !== props.runRecordId
|
|
||||||
) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { id: stepId, status: stepStatus } = data.step
|
const { id: stepId, status: stepStatus } = data.step
|
||||||
|
|||||||
@@ -1681,7 +1681,7 @@
|
|||||||
>
|
>
|
||||||
<RunningOverlay
|
<RunningOverlay
|
||||||
ref="runningOverlayRef"
|
ref="runningOverlayRef"
|
||||||
worker-id="geekAutoStartWithBossMain"
|
:worker-id="CURRENT_WORKER_ID"
|
||||||
:run-record-id="runRecordId"
|
:run-record-id="runRecordId"
|
||||||
>
|
>
|
||||||
<template #op-buttons="{ currentRunningStatus }">
|
<template #op-buttons="{ currentRunningStatus }">
|
||||||
@@ -1714,7 +1714,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onBeforeUnmount, ref, watch, nextTick, onUnmounted } from 'vue'
|
import { computed, onBeforeUnmount, ref, watch, onUnmounted, onMounted } from 'vue'
|
||||||
import { ElForm, ElMessage } from 'element-plus'
|
import { ElForm, ElMessage } from 'element-plus'
|
||||||
import { QuestionFilled, ArrowDown } from '@element-plus/icons-vue'
|
import { QuestionFilled, ArrowDown } from '@element-plus/icons-vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@@ -1742,6 +1742,7 @@ import JobSourceDragOrderer from '../../../features/JobSourceDragOrderer/index.v
|
|||||||
import expectJobFilterTemplateList from './expectJobFilterTemplateList'
|
import expectJobFilterTemplateList from './expectJobFilterTemplateList'
|
||||||
import RunningOverlay from '@renderer/features/RunningOverlay/index.vue'
|
import RunningOverlay from '@renderer/features/RunningOverlay/index.vue'
|
||||||
import { RUNNING_STATUS_ENUM } from '../../../../../common/enums/auto-start-chat'
|
import { RUNNING_STATUS_ENUM } from '../../../../../common/enums/auto-start-chat'
|
||||||
|
import { useTaskManagerStore } from '@renderer/store'
|
||||||
import {
|
import {
|
||||||
getJobDetailRegExpMatchLogicConfig,
|
getJobDetailRegExpMatchLogicConfig,
|
||||||
isJobDetailRegExpEmpty,
|
isJobDetailRegExpEmpty,
|
||||||
@@ -2084,6 +2085,24 @@ const formRules = {
|
|||||||
const formRef = ref<InstanceType<typeof ElForm>>()
|
const formRef = ref<InstanceType<typeof ElForm>>()
|
||||||
const runRecordId = ref(null)
|
const runRecordId = ref(null)
|
||||||
const runningOverlayRef = ref(null)
|
const runningOverlayRef = ref(null)
|
||||||
|
const taskManagerStore = useTaskManagerStore()
|
||||||
|
const CURRENT_WORKER_ID = 'geekAutoStartWithBossMain'
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await taskManagerStore.getRunningTasks()
|
||||||
|
const existingWorker = taskManagerStore.runningTasks?.find(
|
||||||
|
(it) => it.workerId === CURRENT_WORKER_ID
|
||||||
|
)
|
||||||
|
if (existingWorker) {
|
||||||
|
runRecordId.value = existingWorker.runtimeStorage?.stepStatusMapByStepId
|
||||||
|
? Object.values(existingWorker.runtimeStorage.stepStatusMapByStepId)[0]?.runRecordId
|
||||||
|
: null
|
||||||
|
if (runRecordId.value) {
|
||||||
|
runningOverlayRef.value?.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
gtagRenderer('save_config_and_launch_clicked', {
|
gtagRenderer('save_config_and_launch_clicked', {
|
||||||
has_dingtalk_robot_token: !!formContent.value?.dingtalkRobotAccessToken,
|
has_dingtalk_robot_token: !!formContent.value?.dingtalkRobotAccessToken,
|
||||||
|
|||||||
@@ -318,7 +318,7 @@
|
|||||||
>
|
>
|
||||||
<RunningOverlay
|
<RunningOverlay
|
||||||
ref="runningOverlayRef"
|
ref="runningOverlayRef"
|
||||||
worker-id="readNoReplyAutoReminderMain"
|
:worker-id="CURRENT_WORKER_ID"
|
||||||
:run-record-id="runRecordId"
|
:run-record-id="runRecordId"
|
||||||
>
|
>
|
||||||
<template #op-buttons="{ currentRunningStatus }">
|
<template #op-buttons="{ currentRunningStatus }">
|
||||||
@@ -351,7 +351,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
|
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
import { dayjs, ElForm, ElMessage, ElMessageBox, ElSelect, ElOption } from 'element-plus'
|
import { dayjs, ElForm, ElMessage, ElMessageBox, ElSelect, ElOption } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import {
|
import {
|
||||||
@@ -366,6 +366,7 @@ import mittBus from '../../utils/mitt'
|
|||||||
import { QuestionFilled } from '@element-plus/icons-vue'
|
import { QuestionFilled } from '@element-plus/icons-vue'
|
||||||
import RunningOverlay from '@renderer/features/RunningOverlay/index.vue'
|
import RunningOverlay from '@renderer/features/RunningOverlay/index.vue'
|
||||||
import { DEFAULT_CONSTANT_OPEN_CONTENT_SEGS } from '../../../../common/constant'
|
import { DEFAULT_CONSTANT_OPEN_CONTENT_SEGS } from '../../../../common/constant'
|
||||||
|
import { useTaskManagerStore } from '@renderer/store'
|
||||||
const gtagRenderer = (name, params?: object) => {
|
const gtagRenderer = (name, params?: object) => {
|
||||||
return baseGtagRenderer(name, {
|
return baseGtagRenderer(name, {
|
||||||
scene: 'rnrr-config',
|
scene: 'rnrr-config',
|
||||||
@@ -607,6 +608,24 @@ async function checkIsCanRun() {
|
|||||||
}
|
}
|
||||||
const runRecordId = ref(null)
|
const runRecordId = ref(null)
|
||||||
const runningOverlayRef = ref(null)
|
const runningOverlayRef = ref(null)
|
||||||
|
const taskManagerStore = useTaskManagerStore()
|
||||||
|
const CURRENT_WORKER_ID = 'readNoReplyAutoReminderMain'
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await taskManagerStore.getRunningTasks()
|
||||||
|
const existingWorker = taskManagerStore.runningTasks?.find(
|
||||||
|
(it) => it.workerId === CURRENT_WORKER_ID
|
||||||
|
)
|
||||||
|
if (existingWorker) {
|
||||||
|
runRecordId.value = existingWorker.runtimeStorage?.stepStatusMapByStepId
|
||||||
|
? Object.values(existingWorker.runtimeStorage.stepStatusMapByStepId)[0]?.runRecordId
|
||||||
|
: null
|
||||||
|
if (runRecordId.value) {
|
||||||
|
runningOverlayRef.value?.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
gtagRenderer('run_read_no_reply_reminder_clicked', {
|
gtagRenderer('run_read_no_reply_reminder_clicked', {
|
||||||
throttle_interval_minutes: formContent.value.autoReminder.throttleIntervalMinutes,
|
throttle_interval_minutes: formContent.value.autoReminder.throttleIntervalMinutes,
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ export const useUpdateStore = defineStore('update', () => {
|
|||||||
|
|
||||||
export const useTaskManagerStore = defineStore('taskManager', () => {
|
export const useTaskManagerStore = defineStore('taskManager', () => {
|
||||||
const runningTasks = ref<unknown[]>([])
|
const runningTasks = ref<unknown[]>([])
|
||||||
function getRunningTasks() {
|
async function getRunningTasks() {
|
||||||
const { ipcRenderer } = electron
|
const { ipcRenderer } = electron
|
||||||
ipcRenderer.invoke('get-task-manager-list').then(res => {
|
const res = await ipcRenderer.invoke('get-task-manager-list')
|
||||||
runningTasks.value = res.workers ?? []
|
runningTasks.value = res.workers ?? []
|
||||||
})
|
|
||||||
}
|
}
|
||||||
const throttledGetRunningTasks = throttle(getRunningTasks, 2000)
|
const throttledGetRunningTasks = throttle(getRunningTasks, 2000)
|
||||||
setInterval(throttledGetRunningTasks, 2 * 1000)
|
setInterval(throttledGetRunningTasks, 2 * 1000)
|
||||||
|
getRunningTasks()
|
||||||
return { runningTasks, getRunningTasks: throttledGetRunningTasks }
|
return { runningTasks, getRunningTasks: throttledGetRunningTasks }
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user