mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-08 00:47:15 +08:00
migrate cookie assistant logic to standalone window make it promisify, and call it with ghosting remainder; disable pre-check when program start run.
This commit is contained in:
@@ -1,17 +1,18 @@
|
|||||||
export const getAutoStartChatSteps = () => [{
|
export const getAutoStartChatSteps = () => [
|
||||||
id: 'worker-launch',
|
{
|
||||||
describe: '启动子进程',
|
id: 'worker-launch',
|
||||||
},
|
describe: '启动子进程'
|
||||||
// {
|
},
|
||||||
// id: 'basic-cookie-check',
|
{
|
||||||
// describe: 'Cookie 格式检查',
|
id: 'puppeteer-executable-check',
|
||||||
// },
|
describe: 'Puppeteer 可执行程序检查'
|
||||||
{
|
},
|
||||||
id: 'puppeteer-executable-check',
|
{
|
||||||
describe: 'Puppeteer 可执行程序检查',
|
id: 'basic-cookie-check',
|
||||||
},
|
describe: 'Cookie 格式检查'
|
||||||
{
|
},
|
||||||
id: 'login-status-check',
|
{
|
||||||
describe: '登录状态检查',
|
id: 'login-status-check',
|
||||||
}
|
describe: '登录状态检查'
|
||||||
]
|
}
|
||||||
|
]
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { ipcMain } from 'electron'
|
||||||
|
import { createCookieAssistantWindow, cookieAssistantWindow } from '../window/cookieAssistantWindow';
|
||||||
|
|
||||||
|
export async function loginWithCookieAssistant({ windowOption } = {}) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
createCookieAssistantWindow({ ...windowOption })
|
||||||
|
|
||||||
|
let processDone = false
|
||||||
|
ipcMain.once('cookie-saved', function handler() {
|
||||||
|
processDone = true
|
||||||
|
cookieAssistantWindow.close()
|
||||||
|
})
|
||||||
|
cookieAssistantWindow.once('closed', () => {
|
||||||
|
if (processDone) {
|
||||||
|
resolve(true)
|
||||||
|
} else {
|
||||||
|
reject(new Error('User cancelled login'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -3,12 +3,10 @@ import path from 'path'
|
|||||||
import * as childProcess from 'node:child_process'
|
import * as childProcess from 'node:child_process'
|
||||||
import {
|
import {
|
||||||
ensureConfigFileExist,
|
ensureConfigFileExist,
|
||||||
ensureStorageFileExist,
|
|
||||||
configFileNameList,
|
configFileNameList,
|
||||||
readConfigFile,
|
readConfigFile,
|
||||||
writeConfigFile,
|
writeConfigFile,
|
||||||
readStorageFile,
|
readStorageFile,
|
||||||
writeStorageFile,
|
|
||||||
storageFilePath
|
storageFilePath
|
||||||
} from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
} from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
||||||
import { ChildProcess } from 'child_process'
|
import { ChildProcess } from 'child_process'
|
||||||
@@ -54,6 +52,7 @@ import { checkUpdateForUi } from '../../../features/updater'
|
|||||||
import gtag from '../../../utils/gtag'
|
import gtag from '../../../utils/gtag'
|
||||||
import { daemonEE, sendToDaemon } from '../connect-to-daemon'
|
import { daemonEE, sendToDaemon } from '../connect-to-daemon'
|
||||||
import { runCommon } from '../../../features/run-common'
|
import { runCommon } from '../../../features/run-common'
|
||||||
|
import { loginWithCookieAssistant } from '../../../features/login-with-cookie-assistant'
|
||||||
|
|
||||||
export default function initIpc() {
|
export default function initIpc() {
|
||||||
ipcMain.handle('fetch-config-file-content', async () => {
|
ipcMain.handle('fetch-config-file-content', async () => {
|
||||||
@@ -189,17 +188,6 @@ export default function initIpc() {
|
|||||||
return await Promise.all(promiseArr)
|
return await Promise.all(promiseArr)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('read-storage-file', async (ev, payload) => {
|
|
||||||
ensureStorageFileExist()
|
|
||||||
return await readStorageFile(payload.fileName)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.handle('write-storage-file', async (ev, payload) => {
|
|
||||||
ensureStorageFileExist()
|
|
||||||
|
|
||||||
return await writeStorageFile(payload.fileName, JSON.parse(payload.data))
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.handle('run-geek-auto-start-chat-with-boss', async (ev) => {
|
ipcMain.handle('run-geek-auto-start-chat-with-boss', async (ev) => {
|
||||||
const mode = 'geekAutoStartWithBossMain'
|
const mode = 'geekAutoStartWithBossMain'
|
||||||
const { runRecordId } = await runCommon({ mode })
|
const { runRecordId } = await runCommon({ mode })
|
||||||
@@ -395,56 +383,6 @@ export default function initIpc() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
let subProcessOfBossZhipinLoginPageWithPreloadExtension: ChildProcess | null = null
|
|
||||||
ipcMain.on('launch-bosszhipin-login-page-with-preload-extension', async () => {
|
|
||||||
try {
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension?.kill()
|
|
||||||
} catch {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
const subProcessEnv = {
|
|
||||||
...process.env,
|
|
||||||
PUPPETEER_EXECUTABLE_PATH: (await getAnyAvailablePuppeteerExecutable())!.executablePath
|
|
||||||
}
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension = childProcess.spawn(
|
|
||||||
process.argv[0],
|
|
||||||
[process.argv[1], `--mode=launchBossZhipinLoginPageWithPreloadExtension`],
|
|
||||||
{
|
|
||||||
env: subProcessEnv,
|
|
||||||
stdio: [null, null, null, 'pipe', 'ipc']
|
|
||||||
}
|
|
||||||
)
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension!.stdio[3]!.pipe(JSONStream.parse()).on(
|
|
||||||
'data',
|
|
||||||
(raw) => {
|
|
||||||
const data = raw
|
|
||||||
switch (data.type) {
|
|
||||||
case 'BOSS_ZHIPIN_COOKIE_COLLECTED': {
|
|
||||||
mainWindow?.webContents.send(data.type, data)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension!.once('exit', () => {
|
|
||||||
mainWindow?.webContents.send('BOSS_ZHIPIN_LOGIN_PAGE_CLOSED')
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension = null
|
|
||||||
})
|
|
||||||
})
|
|
||||||
ipcMain.on('kill-bosszhipin-login-page-with-preload-extension', async () => {
|
|
||||||
try {
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension?.kill()
|
|
||||||
} catch {
|
|
||||||
//
|
|
||||||
} finally {
|
|
||||||
subProcessOfBossZhipinLoginPageWithPreloadExtension = null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.handle('check-boss-zhipin-cookie-file', () => {
|
ipcMain.handle('check-boss-zhipin-cookie-file', () => {
|
||||||
const cookies = readStorageFile('boss-cookies.json')
|
const cookies = readStorageFile('boss-cookies.json')
|
||||||
return checkCookieListFormat(cookies)
|
return checkCookieListFormat(cookies)
|
||||||
@@ -666,6 +604,15 @@ export default function initIpc() {
|
|||||||
const newRelease = await checkUpdateForUi()
|
const newRelease = await checkUpdateForUi()
|
||||||
return newRelease
|
return newRelease
|
||||||
})
|
})
|
||||||
|
ipcMain.handle('login-with-cookie-assistant', async () => {
|
||||||
|
return await loginWithCookieAssistant({
|
||||||
|
windowOption: {
|
||||||
|
parent: mainWindow!,
|
||||||
|
modal: true,
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
ipcMain.handle('exit-app-immediately', () => {
|
ipcMain.handle('exit-app-immediately', () => {
|
||||||
app.exit(0)
|
app.exit(0)
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import { setDomainLocalStorage } from '@geekgeekrun/utils/puppeteer/local-storag
|
|||||||
|
|
||||||
const localStoragePageUrl = `https://www.zhipin.com/desktop/`
|
const localStoragePageUrl = `https://www.zhipin.com/desktop/`
|
||||||
const bossChatUiUrl = `https://www.zhipin.com/web/geek/chat`
|
const bossChatUiUrl = `https://www.zhipin.com/web/geek/chat`
|
||||||
const bossCookies = readStorageFile('boss-cookies.json')
|
|
||||||
const bossLocalStorage = readStorageFile('boss-local-storage.json')
|
|
||||||
|
|
||||||
export async function bootstrap() {
|
export async function bootstrap() {
|
||||||
const { puppeteer } = await initPuppeteer()
|
const { puppeteer } = await initPuppeteer()
|
||||||
@@ -28,6 +26,8 @@ export async function bootstrap() {
|
|||||||
|
|
||||||
export async function launchBoss(browser: Browser) {
|
export async function launchBoss(browser: Browser) {
|
||||||
const page = (await browser.pages())[0]
|
const page = (await browser.pages())[0]
|
||||||
|
const bossCookies = readStorageFile('boss-cookies.json')
|
||||||
|
const bossLocalStorage = readStorageFile('boss-local-storage.json')
|
||||||
//set cookies
|
//set cookies
|
||||||
for (let i = 0; i < bossCookies.length; i++) {
|
for (let i = 0; i < bossCookies.length; i++) {
|
||||||
await page.setCookie(bossCookies[i])
|
await page.setCookie(bossCookies[i])
|
||||||
|
|||||||
@@ -16,19 +16,29 @@ import {
|
|||||||
getJobHireStatusRecord,
|
getJobHireStatusRecord,
|
||||||
saveJobHireStatusRecord
|
saveJobHireStatusRecord
|
||||||
} from '@geekgeekrun/sqlite-plugin/dist/handlers'
|
} from '@geekgeekrun/sqlite-plugin/dist/handlers'
|
||||||
import { writeStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
import {
|
||||||
|
writeStorageFile,
|
||||||
|
readStorageFile
|
||||||
|
} from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
||||||
import { BossInfo } from '@geekgeekrun/sqlite-plugin/dist/entity/BossInfo'
|
import { BossInfo } from '@geekgeekrun/sqlite-plugin/dist/entity/BossInfo'
|
||||||
import { messageForSaveFilter } from '../../../common/utils/chat-list'
|
import { messageForSaveFilter } from '../../../common/utils/chat-list'
|
||||||
import { AUTO_CHAT_ERROR_EXIT_CODE, RECHAT_CONTENT_SOURCE, RECHAT_LLM_FALLBACK } from '../../../common/enums/auto-start-chat'
|
import {
|
||||||
|
AUTO_CHAT_ERROR_EXIT_CODE,
|
||||||
|
RECHAT_CONTENT_SOURCE,
|
||||||
|
RECHAT_LLM_FALLBACK
|
||||||
|
} from '../../../common/enums/auto-start-chat'
|
||||||
import gtag from '../../utils/gtag'
|
import gtag from '../../utils/gtag'
|
||||||
import { JobHireStatus } from '@geekgeekrun/sqlite-plugin/dist/enums';
|
import { JobHireStatus } from '@geekgeekrun/sqlite-plugin/dist/enums';
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import cheerio from 'cheerio'
|
import cheerio from 'cheerio'
|
||||||
import { connectToDaemon, sendToDaemon } from '../OPEN_SETTING_WINDOW/connect-to-daemon'
|
import { connectToDaemon, sendToDaemon } from '../OPEN_SETTING_WINDOW/connect-to-daemon'
|
||||||
import { pushCurrentPageScreenshot, SCREENSHOT_INTERVAL_MS } from '../../utils/screenshot'
|
// import { pushCurrentPageScreenshot, SCREENSHOT_INTERVAL_MS } from '../../utils/screenshot'
|
||||||
import { checkShouldExit } from '../../utils/worker'
|
import { checkShouldExit } from '../../utils/worker'
|
||||||
import { getAnyAvailablePuppeteerExecutable } from '../CHECK_AND_DOWNLOAD_DEPENDENCIES/utils/puppeteer-executable'
|
import { getAnyAvailablePuppeteerExecutable } from '../CHECK_AND_DOWNLOAD_DEPENDENCIES/utils/puppeteer-executable'
|
||||||
import minimist from 'minimist'
|
import minimist from 'minimist'
|
||||||
|
import { checkCookieListFormat } from '../../../common/utils/cookie'
|
||||||
|
import { loginWithCookieAssistant } from '../../features/login-with-cookie-assistant'
|
||||||
|
import initPublicIpc from '../../utils/initPublicIpc'
|
||||||
|
|
||||||
const throttleIntervalMinutes =
|
const throttleIntervalMinutes =
|
||||||
readConfigFile('boss.json').autoReminder?.throttleIntervalMinutes ?? 10
|
readConfigFile('boss.json').autoReminder?.throttleIntervalMinutes ?? 10
|
||||||
@@ -232,6 +242,39 @@ const mainLoop = async () => {
|
|||||||
browser = null
|
browser = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let bossCookies = readStorageFile('boss-cookies.json')
|
||||||
|
let cookieCheckResult = checkCookieListFormat(bossCookies)
|
||||||
|
while (!cookieCheckResult) {
|
||||||
|
try {
|
||||||
|
await loginWithCookieAssistant()
|
||||||
|
bossCookies = readStorageFile('boss-cookies.json')
|
||||||
|
cookieCheckResult = checkCookieListFormat(bossCookies)
|
||||||
|
} catch (err) {
|
||||||
|
sendToDaemon({
|
||||||
|
type: 'worker-to-gui-message',
|
||||||
|
data: {
|
||||||
|
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
||||||
|
step: {
|
||||||
|
id: 'basic-cookie-check',
|
||||||
|
status: 'rejected'
|
||||||
|
},
|
||||||
|
runRecordId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
throw new Error('LOGIN_STATUS_INVALID')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendToDaemon({
|
||||||
|
type: 'worker-to-gui-message',
|
||||||
|
data: {
|
||||||
|
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
||||||
|
step: {
|
||||||
|
id: 'basic-cookie-check',
|
||||||
|
status: 'fulfilled'
|
||||||
|
},
|
||||||
|
runRecordId
|
||||||
|
}
|
||||||
|
})
|
||||||
const canNotConfirmIfHasReadMsgTemplateList = [
|
const canNotConfirmIfHasReadMsgTemplateList = [
|
||||||
'Boss还没查看你的消息',
|
'Boss还没查看你的消息',
|
||||||
'你与该职位竞争者PK情况',
|
'你与该职位竞争者PK情况',
|
||||||
@@ -250,17 +293,6 @@ const mainLoop = async () => {
|
|||||||
// #region
|
// #region
|
||||||
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', [])
|
||||||
sendToDaemon({
|
|
||||||
type: 'worker-to-gui-message',
|
|
||||||
data: {
|
|
||||||
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
|
||||||
step: {
|
|
||||||
id: 'login-status-check',
|
|
||||||
status: 'rejected'
|
|
||||||
},
|
|
||||||
runRecordId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
throw new Error('LOGIN_STATUS_INVALID')
|
throw new Error('LOGIN_STATUS_INVALID')
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@@ -526,6 +558,8 @@ const rerunInterval = (() => {
|
|||||||
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
|
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
|
||||||
export async function runEntry() {
|
export async function runEntry() {
|
||||||
app.dock?.hide()
|
app.dock?.hide()
|
||||||
|
await app.whenReady()
|
||||||
|
initPublicIpc()
|
||||||
await connectToDaemon()
|
await connectToDaemon()
|
||||||
await sendToDaemon({
|
await sendToDaemon({
|
||||||
type: 'ping'
|
type: 'ping'
|
||||||
@@ -588,13 +622,29 @@ export async function runEntry() {
|
|||||||
// handle error
|
// handle error
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
if (err.message.includes('LOGIN_STATUS_INVALID')) {
|
if (err.message.includes('LOGIN_STATUS_INVALID')) {
|
||||||
await dialog.showMessageBox({
|
try {
|
||||||
type: `error`,
|
// popup login dialog, then update login status
|
||||||
message: `登录状态无效`,
|
await loginWithCookieAssistant()
|
||||||
detail: `请重新登录Boss直聘`
|
} catch (err) {
|
||||||
})
|
await dialog.showMessageBox({
|
||||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID)
|
type: `error`,
|
||||||
break
|
message: `登录状态无效`,
|
||||||
|
detail: `请重新登录Boss直聘`
|
||||||
|
})
|
||||||
|
sendToDaemon({
|
||||||
|
type: 'worker-to-gui-message',
|
||||||
|
data: {
|
||||||
|
type: 'prerequisite-step-by-step-checkstep-by-step-check',
|
||||||
|
step: {
|
||||||
|
id: 'login-status-check',
|
||||||
|
status: 'rejected'
|
||||||
|
},
|
||||||
|
runRecordId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LOGIN_STATUS_INVALID)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (err.message.includes('ERR_INTERNET_DISCONNECTED')) {
|
if (err.message.includes('ERR_INTERNET_DISCONNECTED')) {
|
||||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ERR_INTERNET_DISCONNECTED)
|
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ERR_INTERNET_DISCONNECTED)
|
||||||
@@ -656,3 +706,8 @@ async function storeStorage(page) {
|
|||||||
writeStorageFile('boss-local-storage.json', localStorage)
|
writeStorageFile('boss-local-storage.json', localStorage)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.on('SIGTERM', () => {
|
||||||
|
console.log('收到SIGTERM信号,正在退出')
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ import { BrowserWindow, ipcMain, shell } from 'electron'
|
|||||||
import gtag from './gtag'
|
import gtag from './gtag'
|
||||||
import buildInfo from '../../common/build-info.json'
|
import buildInfo from '../../common/build-info.json'
|
||||||
import os from 'node:os'
|
import os from 'node:os'
|
||||||
|
import {
|
||||||
|
ensureStorageFileExist,
|
||||||
|
readStorageFile,
|
||||||
|
writeStorageFile
|
||||||
|
} from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
|
||||||
|
|
||||||
export default function initPublicIpc() {
|
export default function initPublicIpc() {
|
||||||
ipcMain.on(
|
ipcMain.on(
|
||||||
@@ -56,4 +61,14 @@ export default function initPublicIpc() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('read-storage-file', async (ev, payload) => {
|
||||||
|
ensureStorageFileExist()
|
||||||
|
return await readStorageFile(payload.fileName)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('write-storage-file', async (ev, payload) => {
|
||||||
|
ensureStorageFileExist()
|
||||||
|
return await writeStorageFile(payload.fileName, JSON.parse(payload.data))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import { ChildProcess } from 'child_process'
|
||||||
|
import { BrowserWindow, ipcMain } from 'electron'
|
||||||
|
import path from 'path'
|
||||||
|
import { getAnyAvailablePuppeteerExecutable } from '../flow/CHECK_AND_DOWNLOAD_DEPENDENCIES/utils/puppeteer-executable'
|
||||||
|
import * as childProcess from 'node:child_process'
|
||||||
|
import * as JSONStream from 'JSONStream'
|
||||||
|
|
||||||
|
export let cookieAssistantWindow: BrowserWindow | null = null
|
||||||
|
export function createCookieAssistantWindow(
|
||||||
|
opt?: Electron.BrowserWindowConstructorOptions
|
||||||
|
): BrowserWindow {
|
||||||
|
// Create the browser window.
|
||||||
|
if (cookieAssistantWindow) {
|
||||||
|
cookieAssistantWindow!.show()
|
||||||
|
}
|
||||||
|
cookieAssistantWindow = new BrowserWindow({
|
||||||
|
width: 960,
|
||||||
|
height: 720,
|
||||||
|
resizable: true,
|
||||||
|
show: false,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, '../preload/index.js'),
|
||||||
|
sandbox: false
|
||||||
|
},
|
||||||
|
...opt
|
||||||
|
})
|
||||||
|
|
||||||
|
cookieAssistantWindow.on('ready-to-show', () => {
|
||||||
|
cookieAssistantWindow!.show()
|
||||||
|
})
|
||||||
|
|
||||||
|
// HMR for renderer base on electron-vite cli.
|
||||||
|
// Load the remote URL for development or the local html file for production.
|
||||||
|
if (process.env.NODE_ENV === 'development' && process.env['ELECTRON_RENDERER_URL']) {
|
||||||
|
cookieAssistantWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/cookieAssistant')
|
||||||
|
} else {
|
||||||
|
cookieAssistantWindow.loadURL(
|
||||||
|
'file://' + path.join(__dirname, '../renderer/index.html') + '#/cookieAssistant'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cookieAssistantWindow!.once('closed', () => {
|
||||||
|
cookieAssistantWindow = null
|
||||||
|
})
|
||||||
|
|
||||||
|
let subProcessOfBossZhipinLoginPageWithPreloadExtension: ChildProcess | null = null
|
||||||
|
const launchHandler = async () => {
|
||||||
|
try {
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension?.kill()
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
const subProcessEnv = {
|
||||||
|
...process.env,
|
||||||
|
PUPPETEER_EXECUTABLE_PATH: (await getAnyAvailablePuppeteerExecutable())!.executablePath
|
||||||
|
}
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension = childProcess.spawn(
|
||||||
|
process.argv[0],
|
||||||
|
[process.argv[1], `--mode=launchBossZhipinLoginPageWithPreloadExtension`],
|
||||||
|
{
|
||||||
|
env: subProcessEnv,
|
||||||
|
stdio: [null, null, null, 'pipe', 'ipc']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension!.stdio[3]!.pipe(JSONStream.parse()).on(
|
||||||
|
'data',
|
||||||
|
(raw) => {
|
||||||
|
const data = raw
|
||||||
|
switch (data.type) {
|
||||||
|
case 'BOSS_ZHIPIN_COOKIE_COLLECTED': {
|
||||||
|
cookieAssistantWindow?.webContents.send(data.type, data)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension!.once('exit', () => {
|
||||||
|
cookieAssistantWindow?.webContents.send('BOSS_ZHIPIN_LOGIN_PAGE_CLOSED')
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ipcMain.on('launch-bosszhipin-login-page-with-preload-extension', launchHandler)
|
||||||
|
|
||||||
|
const killHandler = async () => {
|
||||||
|
try {
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension?.kill()
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
} finally {
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipcMain.on('kill-bosszhipin-login-page-with-preload-extension', killHandler)
|
||||||
|
cookieAssistantWindow.on('closed', () => {
|
||||||
|
subProcessOfBossZhipinLoginPageWithPreloadExtension?.kill()
|
||||||
|
ipcMain.off('launch-bosszhipin-login-page-with-preload-extension', launchHandler)
|
||||||
|
ipcMain.off('kill-bosszhipin-login-page-with-preload-extension', killHandler)
|
||||||
|
})
|
||||||
|
|
||||||
|
return cookieAssistantWindow!
|
||||||
|
}
|
||||||
@@ -4,56 +4,48 @@
|
|||||||
<img
|
<img
|
||||||
class="block"
|
class="block"
|
||||||
:class="{
|
:class="{
|
||||||
'animate__animated animate__bounce animate__repeat-3':
|
'animate__animated animate__bounce animate__repeat-3': true
|
||||||
Object.values(checkDependenciesResult).includes(false)
|
|
||||||
}"
|
}"
|
||||||
:width="256"
|
:width="256"
|
||||||
src="@renderer/../../../resources/icon.png"
|
src="@renderer/../../../resources/icon.png"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div mt24px>愿你薪想事成</div>
|
<div mt24px>愿你薪想事成</div>
|
||||||
<div class="h60px mt14px">
|
|
||||||
<RouterView
|
|
||||||
class="h100%"
|
|
||||||
:dependencies-status="checkDependenciesResult"
|
|
||||||
:process-waitee="downloadProcessWaitee"
|
|
||||||
></RouterView>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
|
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
|
||||||
import { gtagRenderer } from '@renderer/utils/gtag'
|
import { gtagRenderer } from '@renderer/utils/gtag'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const checkDependenciesResult = ref({})
|
// const checkDependenciesResult = ref({})
|
||||||
const downloadProcessWaitee = ref(null)
|
// const downloadProcessWaitee = ref(null)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
gtagRenderer('bootstrap_mounted')
|
gtagRenderer('bootstrap_mounted')
|
||||||
checkDependenciesResult.value = await electron.ipcRenderer.invoke('check-dependencies')
|
// checkDependenciesResult.value = await electron.ipcRenderer.invoke('check-dependencies')
|
||||||
downloadProcessWaitee.value = Promise.withResolvers()
|
// downloadProcessWaitee.value = Promise.withResolvers()
|
||||||
|
|
||||||
if (Object.values(checkDependenciesResult.value).includes(false)) {
|
// if (Object.values(checkDependenciesResult.value).includes(false)) {
|
||||||
gtagRenderer('dependencies_need_download')
|
// gtagRenderer('dependencies_need_download')
|
||||||
router.replace('/downloadingDependencies')
|
// router.replace('/downloadingDependencies')
|
||||||
} else {
|
// } else {
|
||||||
downloadProcessWaitee.value!.resolve()
|
// downloadProcessWaitee.value!.resolve()
|
||||||
}
|
// }
|
||||||
|
|
||||||
downloadProcessWaitee.value!.promise.then(async () => {
|
// downloadProcessWaitee.value!.promise.then(async () => {
|
||||||
const isCookieFileValid = await electron.ipcRenderer.invoke('check-boss-zhipin-cookie-file')
|
// const isCookieFileValid = await electron.ipcRenderer.invoke('check-boss-zhipin-cookie-file')
|
||||||
if (!isCookieFileValid) {
|
// if (!isCookieFileValid) {
|
||||||
gtagRenderer('found_cookie_invalid_when_bootstrap')
|
// gtagRenderer('found_cookie_invalid_when_bootstrap')
|
||||||
router.replace('/cookieAssistant')
|
// router.replace('/cookieAssistant')
|
||||||
} else {
|
// } else {
|
||||||
await sleep(1000)
|
await sleep(2000)
|
||||||
router.replace('/main-layout')
|
router.replace('/main-layout')
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="h-screen flex flex-col flex-items-center flex-justify-center">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="block"
|
||||||
|
:class="{
|
||||||
|
'animate__animated animate__bounce animate__repeat-3':
|
||||||
|
Object.values(checkDependenciesResult).includes(false)
|
||||||
|
}"
|
||||||
|
:width="256"
|
||||||
|
src="@renderer/../../../resources/icon.png"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div mt24px>愿你薪想事成</div>
|
||||||
|
<div class="h60px mt14px">
|
||||||
|
<RouterView
|
||||||
|
class="h100%"
|
||||||
|
:dependencies-status="checkDependenciesResult"
|
||||||
|
:process-waitee="downloadProcessWaitee"
|
||||||
|
></RouterView>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
|
||||||
|
import { gtagRenderer } from '@renderer/utils/gtag'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const checkDependenciesResult = ref({})
|
||||||
|
const downloadProcessWaitee = ref(null)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
checkDependenciesResult.value = await electron.ipcRenderer.invoke('check-dependencies')
|
||||||
|
downloadProcessWaitee.value = Promise.withResolvers()
|
||||||
|
|
||||||
|
if (Object.values(checkDependenciesResult.value).includes(false)) {
|
||||||
|
gtagRenderer('dependencies_need_download')
|
||||||
|
router.replace('/downloadingDependencies')
|
||||||
|
} else {
|
||||||
|
downloadProcessWaitee.value!.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadProcessWaitee.value!.promise.then(async () => {
|
||||||
|
const isCookieFileValid = await electron.ipcRenderer.invoke('check-boss-zhipin-cookie-file')
|
||||||
|
if (!isCookieFileValid) {
|
||||||
|
gtagRenderer('found_cookie_invalid_when_bootstrap')
|
||||||
|
router.replace('/cookieAssistant')
|
||||||
|
} else {
|
||||||
|
await sleep(1000)
|
||||||
|
router.replace('/main-layout')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -201,7 +201,7 @@ const handleEditThisCookieExtensionStoreLinkClick = () => {
|
|||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
gtagRenderer('cancel_clicked')
|
gtagRenderer('cancel_clicked')
|
||||||
router.replace('/main-layout')
|
window.close()
|
||||||
}
|
}
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
gtagRenderer('save_clicked')
|
gtagRenderer('save_clicked')
|
||||||
@@ -212,7 +212,8 @@ const handleSubmit = async () => {
|
|||||||
})
|
})
|
||||||
ElMessage.success('Boss直聘 Cookie 保存成功')
|
ElMessage.success('Boss直聘 Cookie 保存成功')
|
||||||
gtagRenderer('save_cookie_done')
|
gtagRenderer('save_cookie_done')
|
||||||
router.replace('/main-layout')
|
|
||||||
|
window.electron.ipcRenderer.send('cookie-saved')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBossZhipinLoginPageClosed = () => {
|
const handleBossZhipinLoginPageClosed = () => {
|
||||||
|
|||||||
@@ -1001,7 +1001,7 @@
|
|||||||
pr50px
|
pr50px
|
||||||
pb30px
|
pb30px
|
||||||
class="no-active-definition-text-slider"
|
class="no-active-definition-text-slider"
|
||||||
|
|
||||||
:format-tooltip="
|
:format-tooltip="
|
||||||
(v) =>
|
(v) =>
|
||||||
typeof noActiveDefinitionMarks[v] === 'string'
|
typeof noActiveDefinitionMarks[v] === 'string'
|
||||||
@@ -1535,9 +1535,17 @@ const normalizeExpectCompanies = () => {
|
|||||||
.join(',')
|
.join(',')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClickLaunchLogin = () => {
|
const handleClickLaunchLogin = async () => {
|
||||||
gtagRenderer('launch_login_clicked')
|
gtagRenderer('launch_login_clicked')
|
||||||
router.replace('/cookieAssistant')
|
try {
|
||||||
|
await electron.ipcRenderer.invoke('login-with-cookie-assistant')
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: 'Cookie 保存成功'
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const expectCompanyTemplateList = [
|
const expectCompanyTemplateList = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -526,9 +526,17 @@ const restoreDefaultTemplate = async () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClickLaunchLogin = () => {
|
const handleClickLaunchLogin = async () => {
|
||||||
gtagRenderer('launch_login_clicked')
|
gtagRenderer('launch_login_clicked')
|
||||||
router.replace('/cookieAssistant')
|
try {
|
||||||
|
await electron.ipcRenderer.invoke('login-with-cookie-assistant')
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: 'Cookie 保存成功'
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
//
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentStamp = ref(new Date())
|
const currentStamp = ref(new Date())
|
||||||
|
|||||||
@@ -164,28 +164,12 @@ onUnmounted(() => {
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const goToCheckBossZhipinCookieFile = () => router.replace('/cookieAssistant')
|
|
||||||
onMounted(() => {
|
|
||||||
electron.ipcRenderer.on('check-boss-zhipin-cookie-file', goToCheckBossZhipinCookieFile)
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
electron.ipcRenderer.removeListener(
|
|
||||||
'check-boss-zhipin-cookie-file',
|
|
||||||
goToCheckBossZhipinCookieFile
|
|
||||||
)
|
|
||||||
})
|
|
||||||
;(async () => {
|
;(async () => {
|
||||||
const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies')
|
const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies')
|
||||||
if (Object.values(checkDependenciesResult).includes(false)) {
|
if (Object.values(checkDependenciesResult).includes(false)) {
|
||||||
router.replace('/')
|
router.replace('/')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const isCookieFileValid = await electron.ipcRenderer.invoke('check-boss-zhipin-cookie-file')
|
|
||||||
if (!isCookieFileValid) {
|
|
||||||
router.replace('/cookieAssistant')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})()
|
})()
|
||||||
|
|
||||||
const { buildInfo } = useBuildInfo()
|
const { buildInfo } = useBuildInfo()
|
||||||
|
|||||||
@@ -17,6 +17,22 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
title: 'Boss 登录助手'
|
title: 'Boss 登录助手'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/browserAssistant',
|
||||||
|
component: () => import('@renderer/page/BrowserAssistant/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '浏览器助手'
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/downloadingDependencies',
|
||||||
|
component: () => import('@renderer/page/BrowserAssistant/page/DownloadingDependencies.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '正在下载核心组件'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/llmConfig',
|
path: '/llmConfig',
|
||||||
component: () => import('@renderer/page/LlmConfig/index.vue'),
|
component: () => import('@renderer/page/LlmConfig/index.vue'),
|
||||||
@@ -136,16 +152,7 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: BootstrapSplash,
|
component: BootstrapSplash,
|
||||||
meta: {
|
meta: {
|
||||||
title: '薪想事成'
|
title: '薪想事成'
|
||||||
},
|
}
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/downloadingDependencies',
|
|
||||||
component: () => import('@renderer/page/BootstrapSplash/page/DownloadingDependencies.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '正在下载核心组件'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user