From 4e28fdd56ebacd3fa2b3a3b934cfec8c75ab3d7b Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Wed, 25 Dec 2024 02:47:59 +0800 Subject: [PATCH] add the expectJobRegExpStr field to make it can filter unrelated job --- .../default-config-file/boss.json | 3 +- .../geek-auto-start-chat-with-boss/index.mjs | 93 ++++++++++++++++--- packages/sqlite-plugin/src/enums.ts | 3 +- .../flow/OPEN_SETTING_WINDOW/ipc/index.ts | 3 +- .../GeekAutoStartChatWithBoss.vue | 11 ++- .../Configuration/MarkAsNotSuitRecord.vue | 6 +- 6 files changed, 100 insertions(+), 19 deletions(-) diff --git a/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json b/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json index 4fb1eec..e4af7f2 100644 --- a/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json +++ b/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json @@ -5,5 +5,6 @@ "degreeList": [], "scaleList": [], "industryList": [] - } + }, + "expectJobRegExpStr": "" } \ No newline at end of file diff --git a/packages/geek-auto-start-chat-with-boss/index.mjs b/packages/geek-auto-start-chat-with-boss/index.mjs index f71f069..bad5d00 100644 --- a/packages/geek-auto-start-chat-with-boss/index.mjs +++ b/packages/geek-auto-start-chat-with-boss/index.mjs @@ -78,6 +78,7 @@ const bossLocalStorage = readStorageFile('boss-local-storage.json') const targetCompanyList = readConfigFile('target-company-list.json').filter(it => !!it.trim()); const anyCombineRecommendJobFilter = readConfigFile('boss.json').anyCombineRecommendJobFilter +const expectJobRegExpStr = readConfigFile('boss.json').expectJobRegExpStr const localStoragePageUrl = `https://www.zhipin.com/desktop/` const recommendJobPageUrl = `https://www.zhipin.com/web/geek/job-recommend` @@ -96,8 +97,9 @@ let page const blockBossNotNewChat = new Set() const blockBossNotActive = new Set() +const blockJobNotSuit = new Set() -async function markJobAsNotSuitInRecommendPage () { +async function markJobAsNotSuitInRecommendPage (reasonCode) { /** * @type {{chosenReasonInUi?: { code: number, text: string}}} */ @@ -127,15 +129,29 @@ async function markJobAsNotSuitInRecommendPage () { })() let isOptionChosen = false if (chooseReasonDialogProxy) { - const bossNotActiveOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title="BOSS活跃度低"]`) - if (bossNotActiveOptionProxy) { - await bossNotActiveOptionProxy.click() - isOptionChosen = true - } else { - const recruitStoppedOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title="职位停招/招满"]`) - if (recruitStoppedOptionProxy) { - await recruitStoppedOptionProxy.click() - isOptionChosen = true + switch (reasonCode) { + case MarkAsNotSuitReason.BOSS_INACTIVE: { + const bossNotActiveOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title="BOSS活跃度低"]`) + if (bossNotActiveOptionProxy) { + await bossNotActiveOptionProxy.click() + isOptionChosen = true + } else { + const recruitStoppedOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title="职位停招/招满"]`) + if (recruitStoppedOptionProxy) { + await recruitStoppedOptionProxy.click() + isOptionChosen = true + } + } + break + } + case MarkAsNotSuitReason.JOB_NOT_SUIT: + default: { + const jobNotSuitOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title="面试过/入职过"]`) + if (jobNotSuitOptionProxy) { + await jobNotSuitOptionProxy.click() + isOptionChosen = true + } + break } } @@ -175,6 +191,24 @@ async function markJobAsNotSuitInRecommendPage () { return result } +export function testIfJobTitleOrDescriptionSuit (jobInfo, regExpStr) { + if (!regExpStr) { + return true + } + try { + const regExp = new RegExp(regExpStr, 'i') + if ( + !regExp.test(jobInfo.jobName) + && !regExp.test(jobInfo.positionName) + && !regExp.test(jobInfo.postDescription) + ) { + return false + } + } catch { + } + return true +} + async function setFilterCondition (selectedFilters) { const { salaryList = [], @@ -434,9 +468,14 @@ async function toRecommendPage (hooks) { continueFind: while (targetJobIndex < 0 && !hasReachLastPage) { // when disable company allow list, we will believe that the first one in the list is your expect job. let tempTargetJobIndexToCheckDetail = enableCompanyAllowList ? jobListData.findIndex( - it => !blockBossNotNewChat.has(it.encryptBossId) && !blockBossNotActive.has(it.encryptBossId) && [...expectCompanySet].find(name => it.brandName.includes(name)) + it => !blockBossNotNewChat.has(it.encryptBossId) + && !blockBossNotActive.has(it.encryptBossId) + && [...expectCompanySet].find( + name => it.brandName.includes(name) + ) + && !blockJobNotSuit.has(it.encryptJobId) ) : jobListData.findIndex( - it => !blockBossNotNewChat.has(it.encryptBossId) && !blockBossNotActive.has(it.encryptBossId) + it => !blockBossNotNewChat.has(it.encryptBossId) && !blockBossNotActive.has(it.encryptBossId) && !blockJobNotSuit.has(it.encryptJobId) ) while (tempTargetJobIndexToCheckDetail < 0 && !hasReachLastPage) { // fetch new @@ -472,7 +511,11 @@ async function toRecommendPage (hooks) { document.querySelector('.job-recommend-main')?.__vue__?.jobList ` ) - tempTargetJobIndexToCheckDetail = jobListData.findIndex(it => !blockBossNotNewChat.has(it.encryptBossId) && !blockBossNotActive.has(it.encryptBossId) && [...expectCompanySet].find(name => it.brandName.includes(name))) + tempTargetJobIndexToCheckDetail = jobListData.findIndex(it => + !blockBossNotNewChat.has(it.encryptBossId) && + !blockBossNotActive.has(it.encryptBossId) && + [...expectCompanySet].find(name => it.brandName.includes(name))) && + !blockJobNotSuit.has(it.encryptJobId) } if (tempTargetJobIndexToCheckDetail < 0 && hasReachLastPage) { @@ -533,7 +576,7 @@ async function toRecommendPage (hooks) { blockBossNotActive.add(targetJobData.jobInfo.encryptUserId) // click prevent recommend button try { - const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage() + const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.BOSS_INACTIVE) await hooks.jobMarkedAsNotSuit.promise( targetJobData, { @@ -549,6 +592,28 @@ async function toRecommendPage (hooks) { } continue continueFind } + if ( + !testIfJobTitleOrDescriptionSuit(targetJobData.jobInfo, expectJobRegExpStr) + ) { + blockJobNotSuit.add(targetJobData.jobInfo.encryptId) + try { + const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_NOT_SUIT) + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_NOT_SUIT, + extInfo: { + bossActiveTimeDesc: targetJobData.bossInfo.activeTimeDesc, + chosenReasonInUi + } + } + ) + } catch { + } + debugger + continue continueFind + } const startChatButtonInnerHTML = await page.evaluate('document.querySelector(".job-detail-box .op-btn.op-btn-chat")?.innerHTML.trim()') if (startChatButtonInnerHTML !== '立即沟通') { blockBossNotNewChat.add(targetJobData.jobInfo.encryptUserId) diff --git a/packages/sqlite-plugin/src/enums.ts b/packages/sqlite-plugin/src/enums.ts index da32553..a791d00 100644 --- a/packages/sqlite-plugin/src/enums.ts +++ b/packages/sqlite-plugin/src/enums.ts @@ -1,5 +1,6 @@ export enum MarkAsNotSuitReason { UNKNOWN = 0, BOSS_INACTIVE = 1, - USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON = 2 + USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON = 2, + JOB_NOT_SUIT = 3, } \ No newline at end of file diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts index 6aa6bf5..d117d7e 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts @@ -60,11 +60,12 @@ export default function initIpc() { const bossConfig = readConfigFile('boss.json') bossConfig.anyCombineRecommendJobFilter = payload.anyCombineRecommendJobFilter + bossConfig.expectJobRegExpStr = payload.expectJobRegExpStr return await Promise.all([ writeConfigFile('dingtalk.json', dingtalkConfig), writeConfigFile('target-company-list.json', payload.expectCompanies.split(',')), - writeConfigFile('boss.json', bossConfig), + writeConfigFile('boss.json', bossConfig) ]) }) diff --git a/packages/ui/src/renderer/src/page/Configuration/GeekAutoStartChatWithBoss.vue b/packages/ui/src/renderer/src/page/Configuration/GeekAutoStartChatWithBoss.vue index 66bf157..cb8343f 100644 --- a/packages/ui/src/renderer/src/page/Configuration/GeekAutoStartChatWithBoss.vue +++ b/packages/ui/src/renderer/src/page/Configuration/GeekAutoStartChatWithBoss.vue @@ -12,6 +12,12 @@ > + + + { @@ -86,12 +93,14 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => { scaleList: [], industryList: [] } + formContent.value.expectJobRegExpStr = res.config['boss.json']?.expectJobRegExpStr ?? '' }) const formRules = {} const formRef = ref>() const handleSubmit = async () => { + formContent.value.expectJobRegExpStr = (formContent.value.expectJobRegExpStr || '').trim() await formRef.value!.validate() await electron.ipcRenderer.invoke('save-config-file-from-ui', JSON.stringify(formContent.value)) diff --git a/packages/ui/src/renderer/src/page/Configuration/MarkAsNotSuitRecord.vue b/packages/ui/src/renderer/src/page/Configuration/MarkAsNotSuitRecord.vue index 416ee0e..3a68b73 100644 --- a/packages/ui/src/renderer/src/page/Configuration/MarkAsNotSuitRecord.vue +++ b/packages/ui/src/renderer/src/page/Configuration/MarkAsNotSuitRecord.vue @@ -33,6 +33,9 @@ {{ markReasonTopicMap[row.markReason] }}
{{ formatMarkReason(row) }}
+ @@ -168,7 +171,8 @@ function handleViewJobSnapshotButtonClick(record: VMarkAsNotSuitLog) { const markReasonTopicMap = { [MarkAsNotSuitReason.BOSS_INACTIVE]: 'Boss不活跃', - [MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON]: '手动标记不合适' + [MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON]: '手动标记不合适', + [MarkAsNotSuitReason.JOB_NOT_SUIT]: '职位不合适' } function formatMarkReason(row: VMarkAsNotSuitLog) {