diff --git a/packages/sqlite-plugin/src/handlers.ts b/packages/sqlite-plugin/src/handlers.ts new file mode 100644 index 0000000..ebfdfe2 --- /dev/null +++ b/packages/sqlite-plugin/src/handlers.ts @@ -0,0 +1,88 @@ +import { DataSource } from "typeorm"; +import { BossActiveStatusRecord } from "./entity/BossActiveStatusRecord"; +import { BossInfo } from "./entity/BossInfo"; +import { CompanyInfo } from "./entity/CompanyInfo"; +import { JobInfo } from "./entity/JobInfo"; +import { parseCompanyScale, parseSalary } from "./utils/parser"; + +export async function saveJobInfoFromRecommendPage(ds: DataSource, _jobInfo) { + const { bossInfo, brandComInfo, jobInfo } = _jobInfo; + + //#region boss + const boss = new BossInfo(); + boss.encryptBossId = jobInfo.encryptUserId; + boss.encryptCompanyId = brandComInfo.encryptBrandId; + boss.name = bossInfo.name; + boss.title = bossInfo.title; + boss.date = new Date(); + const bossInfoRepository = ds.getRepository(BossInfo); + await bossInfoRepository.save(boss); + //#endregion + + //#region company + const company = new CompanyInfo(); + company.encryptCompanyId = brandComInfo.encryptBrandId; + company.brandName = brandComInfo.brandName; + company.name = brandComInfo.customerBrandName; + company.industryName = brandComInfo.industryName; + company.stageName = brandComInfo.stageName; + const companyScale = parseCompanyScale(brandComInfo.scaleName); + company.scaleLow = companyScale[0]; + company.scaleHigh = companyScale[1]; + + const companyInfoRepository = ds.getRepository(CompanyInfo); + await companyInfoRepository.save(company); + //#endregion + + //#region job + const job = new JobInfo(); + const jobSalary = parseSalary(jobInfo.salaryDesc); + const jobUpdatePayload: JobInfo = { + address: jobInfo.address, + degreeName: jobInfo.degreeName, + description: jobInfo.postDescription, + encryptBossId: jobInfo.encryptUserId, + encryptCompanyId: brandComInfo.encryptBrandId, + encryptJobId: jobInfo.encryptId, + jobName: jobInfo.jobName, + positionName: jobInfo.positionName, + experienceName: jobInfo.experienceName, + salaryHigh: jobSalary.high, + salaryLow: jobSalary.low, + salaryMonth: jobSalary.month, + }; + + Object.assign(job, jobUpdatePayload); + + const jobInfoRepository = ds.getRepository(JobInfo); + await jobInfoRepository.save(job); + //#endregion + + //#region save boss active status + // look up if the lastActiveStatus of the newest one is equal to the current one. + // if equal, just update the updateDate + // else insert a new record + + const bossActiveStatusRecord = new BossActiveStatusRecord(); + bossActiveStatusRecord.encryptBossId = boss.encryptBossId; + bossActiveStatusRecord.updateDate = new Date(); + bossActiveStatusRecord.lastActiveStatus = bossInfo.activeTimeDesc; + + const bossActiveStatusRecordRepository = ds.getRepository( + BossActiveStatusRecord + ); + const existNewestRecordByBossId = + await bossActiveStatusRecordRepository.findOne({ + where: { encryptBossId: boss.encryptBossId }, + order: { updateDate: "DESC" }, + }); + if ( + existNewestRecordByBossId && + existNewestRecordByBossId.lastActiveStatus === bossInfo.activeTimeDesc + ) { + bossActiveStatusRecord.id = existNewestRecordByBossId.id; + } + await bossActiveStatusRecordRepository.save(bossActiveStatusRecord); + //#endregion + return; +} diff --git a/packages/sqlite-plugin/src/index.ts b/packages/sqlite-plugin/src/index.ts index 9eec959..3c8128d 100644 --- a/packages/sqlite-plugin/src/index.ts +++ b/packages/sqlite-plugin/src/index.ts @@ -1,6 +1,5 @@ import "reflect-metadata"; import { type DataSource } from "typeorm"; -import { parseCompanyScale, parseSalary } from "./utils/parser"; import { requireTypeorm } from "./utils/module-loader"; import { BossInfo } from "./entity/BossInfo"; @@ -16,6 +15,7 @@ import { VChatStartupLog } from "./entity/VChatStartupLog"; import sqlite3 from 'sqlite3'; import * as cliHighlight from 'cli-highlight'; +import { saveJobInfoFromRecommendPage } from "./handlers"; Boolean(cliHighlight); export function initDb(dbFilePath) { @@ -75,81 +75,8 @@ export default class SqlitePlugin { ); hooks.jobDetailIsGetFromRecommendList.tapPromise("SqlitePlugin", async (_jobInfo) => { - console.log(_jobInfo); const ds = await this.initPromise; - - const { bossInfo, brandComInfo, jobInfo } = _jobInfo; - - //#region boss - const boss = new BossInfo(); - boss.encryptBossId = jobInfo.encryptUserId; - boss.encryptCompanyId = brandComInfo.encryptBrandId; - boss.name = bossInfo.name; - boss.title = bossInfo.title; - boss.date = new Date(); - const bossInfoRepository = ds.getRepository(BossInfo); - await bossInfoRepository.save(boss); - //#endregion - - //#region company - const company = new CompanyInfo(); - company.encryptCompanyId = brandComInfo.encryptBrandId; - company.brandName = brandComInfo.brandName; - company.name = brandComInfo.customerBrandName; - company.industryName = brandComInfo.industryName; - company.stageName = brandComInfo.stageName; - const companyScale = parseCompanyScale(brandComInfo.scaleName) - company.scaleLow = companyScale[0] - company.scaleHigh = companyScale[1] - - const companyInfoRepository = ds.getRepository(CompanyInfo); - await companyInfoRepository.save(company); - //#endregion - - //#region job - const job = new JobInfo(); - const jobSalary = parseSalary(jobInfo.salaryDesc) - const jobUpdatePayload: JobInfo = { - address: jobInfo.address, - degreeName: jobInfo.degreeName, - description: jobInfo.postDescription, - encryptBossId: jobInfo.encryptUserId, - encryptCompanyId: brandComInfo.encryptBrandId, - encryptJobId: jobInfo.encryptId, - jobName: jobInfo.jobName, - positionName: jobInfo.positionName, - experienceName: jobInfo.experienceName, - salaryHigh: jobSalary.high, - salaryLow: jobSalary.low, - salaryMonth: jobSalary.month, - }; - - Object.assign(job, jobUpdatePayload); - - const jobInfoRepository = ds.getRepository(JobInfo); - await jobInfoRepository.save(job); - //#endregion - - //#region save boss active status - // look up if the lastActiveStatus of the newest one is equal to the current one. - // if equal, just update the updateDate - // else insert a new record - - const bossActiveStatusRecord = new BossActiveStatusRecord(); - bossActiveStatusRecord.encryptBossId = boss.encryptBossId; - bossActiveStatusRecord.updateDate = new Date(); - bossActiveStatusRecord.lastActiveStatus = bossInfo.activeTimeDesc; - - const bossActiveStatusRecordRepository = ds.getRepository(BossActiveStatusRecord); - const existNewestRecordByBossId = await bossActiveStatusRecordRepository.findOne( - { where: { encryptBossId: boss.encryptBossId }, order: { updateDate: 'DESC'} } - ) - if (existNewestRecordByBossId && existNewestRecordByBossId.lastActiveStatus === bossInfo.activeTimeDesc) { - bossActiveStatusRecord.id = existNewestRecordByBossId.id - } - await bossActiveStatusRecordRepository.save(bossActiveStatusRecord) - //#endregion - return + saveJobInfoFromRecommendPage(ds, _jobInfo); }); hooks.newChatStartup.tapPromise("SqlitePlugin", async (_jobInfo) => { diff --git a/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts b/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts index 29eec9b..4b5f10d 100644 --- a/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts +++ b/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts @@ -2,12 +2,16 @@ import { initPuppeteer } from '@geekgeekrun/geek-auto-start-chat-with-boss/index import extractZip from 'extract-zip' import { readStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' import { setDomainLocalStorage } from '@geekgeekrun/utils/puppeteer/local-storage.mjs' +import { saveJobInfoFromRecommendPage } from '@geekgeekrun/sqlite-plugin/dist/handlers' +import { initDb } from '@geekgeekrun/sqlite-plugin' +import { getPublicDbFilePath } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' import fs from 'node:fs' import os from 'node:os' import path from 'node:path' import url from 'url' import packageJson from '@geekgeekrun/launch-bosszhipin-login-page-with-preload-extension/package.json' assert { type: 'json' } +import { Target } from 'puppeteer' const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) const isRunFromUi = Boolean(process.env.MAIN_BOSSGEEKGO_UI_RUN_MODE) @@ -41,6 +45,32 @@ async function getEditThisCookieZipPath() { } return editThisCookieZipPath } +const dbInitPromise = initDb(getPublicDbFilePath()) + +const attachRequestsListener = async (target: Target) => { + const page = await target.page() + if (!page) { + return + } + + page.on('response', async (response) => { + if (response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/job/detail.json')) { + const data = await response.json() + + console.log(data) + if (data.code === 0) { + saveJobInfoFromRecommendPage(await dbInitPromise, data.zpData) + } + } + }) + + await page.waitForResponse((response) => { + if (response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/job/detail.json')) { + return true + } + return false + }) +} export async function launchBossSite() { if (!fs.existsSync(path.join(editThisCookieExtensionPath, 'manifest.json'))) { @@ -57,7 +87,7 @@ export async function launchBossSite() { headless: false, args: [`--load-extension=${editThisCookieExtensionPath}`] }) - const [page] = await browser.pages() + let [page] = await browser.pages() for (let i = 0; i < bossCookies.length; i++) { await page.setCookie(bossCookies[i]) } @@ -65,5 +95,11 @@ export async function launchBossSite() { const localStoragePageUrl = `https://www.zhipin.com/desktop/` await setDomainLocalStorage(browser, localStoragePageUrl, bossLocalStorage) + browser.on('targetcreated', (target) => { + attachRequestsListener(target) + }) + const newPage = await await browser.newPage() + await page.close() + page = newPage await page.goto('https://www.zhipin.com/web/user/') }