From 2f3a557fb5cc9fd1090d2cf29c9672760d3a21dc Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 31 May 2025 15:52:15 +0800 Subject: [PATCH 1/9] update element-plus --- packages/ui/package.json | 2 +- pnpm-lock.yaml | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/ui/package.json b/packages/ui/package.json index 276ca1d..48306f9 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -66,7 +66,7 @@ "electron": "28.2.0", "electron-builder": "^24.9.1", "electron-vite": "^2.0.0", - "element-plus": "^2.5.5", + "element-plus": "^2.8.4", "eslint": "^8.56.0", "eslint-plugin-vue": "^9.20.1", "find-chrome-bin": "^2.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4402ddd..dd40f09 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -209,8 +209,8 @@ importers: specifier: ^2.0.0 version: 2.0.0(vite@5.1.1) element-plus: - specifier: ^2.5.5 - version: 2.5.5(vue@3.4.15) + specifier: ^2.8.4 + version: 2.8.4(vue@3.4.15) eslint: specifier: ^8.56.0 version: 8.56.0 @@ -3085,6 +3085,11 @@ packages: /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false + + /dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + dev: true /de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} @@ -3360,8 +3365,8 @@ packages: transitivePeerDependencies: - supports-color - /element-plus@2.5.5(vue@3.4.15): - resolution: {integrity: sha512-yGU/MruLOWI0ImQPFCyFM4cXtHtILJNAi0hhLImcxjRukjgQLYNkvcvbwqNgBUt808KSeKF9MyxENFyBQLTg+Q==} + /element-plus@2.8.4(vue@3.4.15): + resolution: {integrity: sha512-ZlVAdUOoJliv4kW3ntWnnSHMT+u/Os7mXJjk2xzOlqNeHaI2/ozlF+R58ZCEak8ZnDi6+5A2viWEYRsq64IuiA==} peerDependencies: vue: ^3.2.0 dependencies: @@ -3373,7 +3378,7 @@ packages: '@types/lodash-es': 4.17.12 '@vueuse/core': 9.13.0(vue@3.4.15) async-validator: 4.2.5 - dayjs: 1.11.10 + dayjs: 1.11.13 escape-html: 1.0.3 lodash: 4.17.21 lodash-es: 4.17.21 From 8dc8ca825d6aff49882f046a06f16961ead05de6 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sun, 1 Jun 2025 21:41:09 +0800 Subject: [PATCH 2/9] add salary filter ui --- packages/sqlite-plugin/src/enums.ts | 5 + .../flow/OPEN_SETTING_WINDOW/ipc/index.ts | 17 + packages/ui/src/main/window/mainWindow.ts | 2 +- .../GeekAutoStartChatWithBoss/index.vue | 401 +++++++++++++++--- 4 files changed, 376 insertions(+), 49 deletions(-) diff --git a/packages/sqlite-plugin/src/enums.ts b/packages/sqlite-plugin/src/enums.ts index 10f3bf7..b887896 100644 --- a/packages/sqlite-plugin/src/enums.ts +++ b/packages/sqlite-plugin/src/enums.ts @@ -16,3 +16,8 @@ export enum StrategyScopeOptionWhenMarkJobNotMatch { ALL_JOB = 1, ONLY_COMPANY_MATCHED_JOB = 2 } + +export enum SalaryCalculateWay { + MONTH_SALARY = 1, + ANNUAL_PACKAGE = 2 +} \ 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 d0f39f9..14691be 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 @@ -117,6 +117,23 @@ export default function initIpc() { bossConfig.strategyScopeOptionWhenMarkJobCityNotMatch = payload.strategyScopeOptionWhenMarkJobCityNotMatch } + if (hasOwn(payload, 'expectSalaryCalculateWay')) { + bossConfig.expectSalaryCalculateWay = payload.expectSalaryCalculateWay + } + if (hasOwn(payload, 'expectSalaryNotMatchStrategy')) { + bossConfig.expectSalaryNotMatchStrategy = payload.expectSalaryNotMatchStrategy + } + if (hasOwn(payload, 'strategyScopeOptionWhenMarkSalaryNotMatch')) { + bossConfig.strategyScopeOptionWhenMarkSalaryNotMatch = + payload.strategyScopeOptionWhenMarkSalaryNotMatch + } + if (hasOwn(payload, 'expectSalaryLow')) { + bossConfig.expectSalaryLow = payload.expectSalaryLow + } + if (hasOwn(payload, 'expectSalaryHigh')) { + bossConfig.expectSalaryHigh = payload.expectSalaryHigh + } + promiseArr.push(writeConfigFile('boss.json', bossConfig)) if (hasOwn(payload, 'expectCompanies')) { diff --git a/packages/ui/src/main/window/mainWindow.ts b/packages/ui/src/main/window/mainWindow.ts index fbe6031..79797a2 100644 --- a/packages/ui/src/main/window/mainWindow.ts +++ b/packages/ui/src/main/window/mainWindow.ts @@ -10,7 +10,7 @@ export function createMainWindow(): BrowserWindow { mainWindow = new BrowserWindow({ width: 1280, height: 720, - minWidth: 1024, + minWidth: 1280, show: false, autoHideMenuBar: true, ...(process.platform === 'linux' diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue index caf5cc4..278c31c 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue @@ -38,7 +38,7 @@ }" >
- 期望公司白名单(以逗号分隔,不区分大小写;输入框留空表示不筛选) 期望公司信息位置图示公司信息UI位置图示
期望公司模板 公司列表模板 diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue index e4f87ab..5bf5370 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue @@ -376,7 +376,7 @@ [ MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS, MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL - ].includes(formContent.expectCityNotMatchStrategy) + ].includes(formContent.expectSalaryNotMatchStrategy) " mb0 :style="{ @@ -473,6 +473,12 @@ {{ markReasonTopicMap[row.markReason] }}
{{ formatMarkReason(row) }}
+ @@ -209,7 +213,8 @@ const markReasonTopicMap = { [MarkAsNotSuitReason.BOSS_INACTIVE]: 'Boss不活跃', [MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON]: '手动标记不合适', [MarkAsNotSuitReason.JOB_NOT_SUIT]: '职位不合适', - [MarkAsNotSuitReason.JOB_CITY_NOT_SUIT]: '工作地不合适' + [MarkAsNotSuitReason.JOB_CITY_NOT_SUIT]: '工作地不合适', + [MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT]: '工作经验不合适' } function formatMarkReason(row: VMarkAsNotSuitLog) { @@ -241,6 +246,7 @@ function formatMarkReason(row: VMarkAsNotSuitLog) { .filter(Boolean) .join('\n') } + case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT: case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: { const extInfo = (() => { try { From 48f1232f7d562c3af9ea3dd9b807777dc109d660 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Mon, 2 Jun 2025 21:53:12 +0800 Subject: [PATCH 6/9] adjust priority of mark as not suit strategy when a job match more than one condition --- .../geek-auto-start-chat-with-boss/index.mjs | 304 ++++++++++-------- 1 file changed, 169 insertions(+), 135 deletions(-) diff --git a/packages/geek-auto-start-chat-with-boss/index.mjs b/packages/geek-auto-start-chat-with-boss/index.mjs index 461c793..827e20d 100644 --- a/packages/geek-auto-start-chat-with-boss/index.mjs +++ b/packages/geek-auto-start-chat-with-boss/index.mjs @@ -684,6 +684,149 @@ async function toRecommendPage (hooks) { // save the job detail info await hooks.jobDetailIsGetFromRecommendList?.promise(targetJobData) + //#region collect not suit reasons + const notSuitReasonIdToStrategyMap = {} + const notSuitConditionHandleMap = { + async active() { + blockBossNotActive.add(targetJobData.jobInfo.encryptUserId) + if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { + try { + const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.BOSS_INACTIVE) + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.BOSS_INACTIVE, + extInfo: { + bossActiveTimeDesc: targetJobData.bossInfo.activeTimeDesc, + chosenReasonInUi + }, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS + } + ) + } catch { + } + } + else if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { + try { + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.BOSS_INACTIVE, + extInfo: null, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL + } + ) + } catch { + } + } + }, + async city() { + blockJobNotSuit.add(targetJobData.jobInfo.encryptId) + if (expectCityNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { + try { + const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_CITY_NOT_SUIT) + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_CITY_NOT_SUIT, + extInfo: { + chosenReasonInUi + }, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS + } + ) + } catch { + } + } + else if (expectCityNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { + try { + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_CITY_NOT_SUIT, + extInfo: null, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL + } + ) + } catch { + } + } + }, + async workExp() { + blockJobNotSuit.add(targetJobData.jobInfo.encryptId) + if (expectWorkExpNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { + try { + const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT) + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT, + extInfo: { + chosenReasonInUi + }, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS + } + ) + } catch { + } + } + else if (expectWorkExpNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { + try { + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT, + extInfo: null, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL + } + ) + } catch { + } + } + }, + async jobDetail() { + blockJobNotSuit.add(targetJobData.jobInfo.encryptId) + if (jobNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { + 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 + }, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS + } + ) + } catch { + } + } + else if (jobNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { + try { + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_NOT_SUIT, + extInfo: null, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL + } + ) + } catch { + } + } + } + } + //#region // null // 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃 @@ -694,159 +837,50 @@ async function toRecommendPage (hooks) { markAsNotActiveSelectedTimeRange > 0 && indexOfActiveText > 0 && indexOfActiveText <= markAsNotActiveSelectedTimeRange ) { - blockBossNotActive.add(targetJobData.jobInfo.encryptUserId) // click prevent recommend button - if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { - try { - const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.BOSS_INACTIVE) - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.BOSS_INACTIVE, - extInfo: { - bossActiveTimeDesc: targetJobData.bossInfo.activeTimeDesc, - chosenReasonInUi - }, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS - } - ) - } catch { - } - } - else if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { - try { - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.BOSS_INACTIVE, - extInfo: null, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL - } - ) - } catch { - } - } - continue continueFind + notSuitReasonIdToStrategyMap.active = jobNotActiveStrategy } if ( (Array.isArray(expectCityList) && expectCityList.length) && !expectCityList.includes(selectedJobData.cityName) ) { - blockJobNotSuit.add(targetJobData.jobInfo.encryptId) - if (expectCityNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { - try { - const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_CITY_NOT_SUIT) - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.JOB_CITY_NOT_SUIT, - extInfo: { - chosenReasonInUi - }, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS - } - ) - } catch { - } - } - else if (expectCityNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { - try { - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.JOB_CITY_NOT_SUIT, - extInfo: null, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL - } - ) - } catch { - } - } - continue continueFind + notSuitReasonIdToStrategyMap.city = expectCityNotMatchStrategy } if ( (Array.isArray(expectWorkExpList) && expectWorkExpList.length) && !expectWorkExpList.includes(selectedJobData.jobExperience) ) { - blockJobNotSuit.add(targetJobData.jobInfo.encryptId) - if (expectWorkExpNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { - try { - const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT) - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT, - extInfo: { - chosenReasonInUi - }, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS - } - ) - } catch { - } - } - else if (expectWorkExpNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { - try { - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT, - extInfo: null, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL - } - ) - } catch { - } - } - continue continueFind + notSuitReasonIdToStrategyMap.workExp = expectWorkExpNotMatchStrategy } if ( !testIfJobTitleOrDescriptionSuit(targetJobData.jobInfo) ) { - blockJobNotSuit.add(targetJobData.jobInfo.encryptId) - if (jobNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { - 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 - }, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS - } - ) - } catch { - } - } - else if (jobNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { - try { - await hooks.jobMarkedAsNotSuit.promise( - targetJobData, - { - markFrom: ChatStartupFrom.AutoFromRecommendList, - markReason: MarkAsNotSuitReason.JOB_NOT_SUIT, - extInfo: null, - markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL - } - ) - } catch { - } - } + notSuitReasonIdToStrategyMap.jobDetail = jobNotMatchStrategy + } + // #endregion + + // #region execute mark logic + // 1. find the one mark on Boss + const markOnBossCondition = Object.keys(notSuitReasonIdToStrategyMap).find(k => notSuitReasonIdToStrategyMap[k] === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) + if (markOnBossCondition) { + await notSuitConditionHandleMap[markOnBossCondition]() continue continueFind } - // test company again - when allow list not include target company, just skip + // 2. if there is no condition to mark Boss, then find the one mark on local db + const markOnLocalDbCondition = Object.keys(notSuitReasonIdToStrategyMap).find(k => notSuitReasonIdToStrategyMap[k] === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) + if (markOnLocalDbCondition) { + await notSuitConditionHandleMap[markOnBossCondition]() + continue continueFind + } + // #endregion if ( + // test company again - when allow list not include target company, just skip enableCompanyAllowList && ![...expectCompanySet].find( name => selectedJobData.brandName?.toLowerCase?.()?.includes(name.toLowerCase()) - ) + ) || + // check if job has been marked as not suit or not active + [ + ...blockJobNotSuit, + ...blockBossNotActive + ].includes(targetJobData.jobInfo.encryptId) ) { // just skip continue continueFind From 699bdd26411f923ade6108ed1705b9bd41eb4075 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Tue, 3 Jun 2025 00:55:44 +0800 Subject: [PATCH 7/9] add filter logic of job salary in script --- .../geek-auto-start-chat-with-boss/index.mjs | 105 +++++++++++++++++- packages/sqlite-plugin/src/enums.ts | 3 +- .../page/MainLayout/MarkAsNotSuitRecord.vue | 22 +++- 3 files changed, 122 insertions(+), 8 deletions(-) diff --git a/packages/geek-auto-start-chat-with-boss/index.mjs b/packages/geek-auto-start-chat-with-boss/index.mjs index 827e20d..f433826 100644 --- a/packages/geek-auto-start-chat-with-boss/index.mjs +++ b/packages/geek-auto-start-chat-with-boss/index.mjs @@ -18,7 +18,7 @@ import { default as rawIndustryFilterExemption } from './internal-config/job-fil import { ChatStartupFrom } from '@geekgeekrun/sqlite-plugin/dist/entity/ChatStartupLog' import { MarkAsNotSuitReason, MarkAsNotSuitOp, StrategyScopeOptionWhenMarkJobNotMatch, SalaryCalculateWay } from '@geekgeekrun/sqlite-plugin/dist/enums' import { activeDescList } from './constant.mjs' - +import { parseSalary } from "@geekgeekrun/sqlite-plugin/dist/utils/parser" const jobFilterConditionsMapByCode = {} Object.values(jobFilterConditions).forEach(arr => { arr.forEach(option => { @@ -90,7 +90,7 @@ const strategyScopeOptionWhenMarkJobCityNotMatch = readConfigFile('boss.json').s const expectSalaryLow = parseFloat(readConfigFile('boss.json').expectSalaryLow) || null const expectSalaryHigh = parseFloat(readConfigFile('boss.json').expectSalaryHigh) || null const expectSalaryCalculateWay = readConfigFile('boss.json').expectSalaryCalculateWay ?? SalaryCalculateWay.MONTH_SALARY -const expectSalaryNotMatchStrategy = readConfigFile('boss.json').expectSalaryCalculateWay ?? MarkAsNotSuitOp.NO_OP +const expectSalaryNotMatchStrategy = readConfigFile('boss.json').expectSalaryNotMatchStrategy ?? MarkAsNotSuitOp.NO_OP const isSalaryFilterEnabled = expectSalaryLow || expectSalaryHigh const strategyScopeOptionWhenMarkSalaryNotMatch = readConfigFile('boss.json').strategyScopeOptionWhenMarkSalaryNotMatch ?? StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB @@ -203,7 +203,8 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) { break } case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT: - case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: { + case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: + case MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT: { const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title$="城市"]`)) ?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="同城距离远"]`)) ?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="公司不感兴趣"]`)) @@ -548,10 +549,29 @@ async function toRecommendPage (hooks) { // due to city can get from list immediately // so just set those job which city is not suit to blockJobNotSuit // to skip view detail + + // skip invalid salaryData (兼职、日结、实习 etc) + jobListData.forEach(it => { + const salaryData = parseSalary(it.salaryDesc) + if (!salaryData.high || !salaryData.low) { + blockJobNotSuit.add(it.encryptJobId) + } + }) if ( - expectCityNotMatchStrategy === MarkAsNotSuitOp.NO_OP && - Array.isArray(expectCityList) && - expectCityList.length + ( + expectCityNotMatchStrategy === MarkAsNotSuitOp.NO_OP && + Array.isArray(expectCityList) && + expectCityList.length + ) || + ( + expectWorkExpNotMatchStrategy === MarkAsNotSuitOp.NO_OP && + Array.isArray(expectWorkExpList) && + expectWorkExpList.length + ) || + ( + strategyScopeOptionWhenMarkSalaryNotMatch === MarkAsNotSuitOp.NO_OP && + isSalaryFilterEnabled + ) ) { console.log(`add job city not suit into blockJobNotSuit set`) for (const it of jobListData) { @@ -566,6 +586,26 @@ async function toRecommendPage (hooks) { let hasReachLastPage = false let targetJobIndex = -1 let targetJobData, selectedJobData // they show be same; one is from list, another is from detail + function checkIfSalarySuit(salaryDesc) { + const salaryData = parseSalary(salaryDesc) + if (expectSalaryCalculateWay === SalaryCalculateWay.MONTH_SALARY) { + if (expectSalaryHigh && salaryData.high > expectSalaryHigh) { + return false + } + if (expectSalaryLow && salaryData.low < expectSalaryLow) { + return false + } + } else if (expectSalaryCalculateWay === SalaryCalculateWay.ANNUAL_PACKAGE) { + const salaryDataMonth = salaryData.month || 12 + if (expectSalaryHigh && (salaryData.high * salaryDataMonth) / 10 > expectSalaryHigh) { + return false + } + if (expectSalaryLow && (salaryData.low * salaryDataMonth) / 10 < expectSalaryLow) { + return false + } + } + return true + } function getTempTargetJobIndexToCheckDetail () { return jobListData.findIndex(it => { return !blockBossNotNewChat.has(it.encryptBossId) && @@ -601,6 +641,16 @@ async function toRecommendPage (hooks) { ].includes(expectWorkExpNotMatchStrategy) && strategyScopeOptionWhenMarkJobWorkExpNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB ) ? !expectWorkExpList.includes(it.jobExperience) : false + ) || ( + // enter job detail to mark as not suit for salary filter + ( + isSalaryFilterEnabled && + [ + MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS, + MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL + ].includes(expectSalaryNotMatchStrategy) && + strategyScopeOptionWhenMarkSalaryNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB + ) ? !checkIfSalarySuit(it.salaryDesc) : false ) ) }) @@ -824,6 +874,43 @@ async function toRecommendPage (hooks) { } catch { } } + }, + async salary() { + blockJobNotSuit.add(targetJobData.jobInfo.encryptId) + if (expectSalaryNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) { + try { + const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT) + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT, + extInfo: { + salaryDesc: selectedJobData.salaryDesc, + chosenReasonInUi + }, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS + } + ) + } catch { + } + } + else if (expectSalaryNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL) { + try { + await hooks.jobMarkedAsNotSuit.promise( + targetJobData, + { + markFrom: ChatStartupFrom.AutoFromRecommendList, + markReason: MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT, + extInfo: { + salaryDesc: selectedJobData.salaryDesc, + }, + markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL + } + ) + } catch { + } + } } } @@ -855,7 +942,13 @@ async function toRecommendPage (hooks) { ) { notSuitReasonIdToStrategyMap.jobDetail = jobNotMatchStrategy } + if ( + !checkIfSalarySuit(selectedJobData.salaryDesc) + ) { + notSuitReasonIdToStrategyMap.salary = expectSalaryNotMatchStrategy + } // #endregion + console.log('not suit reason and related strategy: ', notSuitReasonIdToStrategyMap) // #region execute mark logic // 1. find the one mark on Boss diff --git a/packages/sqlite-plugin/src/enums.ts b/packages/sqlite-plugin/src/enums.ts index 644fbad..ddab6c5 100644 --- a/packages/sqlite-plugin/src/enums.ts +++ b/packages/sqlite-plugin/src/enums.ts @@ -5,6 +5,7 @@ export enum MarkAsNotSuitReason { JOB_NOT_SUIT = 3, JOB_CITY_NOT_SUIT = 4, JOB_WORK_EXP_NOT_SUIT = 5, + JOB_SALARY_NOT_SUIT = 6, } export enum MarkAsNotSuitOp { @@ -20,5 +21,5 @@ export enum StrategyScopeOptionWhenMarkJobNotMatch { export enum SalaryCalculateWay { MONTH_SALARY = 1, - ANNUAL_PACKAGE = 2 + ANNUAL_PACKAGE = 2, } \ No newline at end of file diff --git a/packages/ui/src/renderer/src/page/MainLayout/MarkAsNotSuitRecord.vue b/packages/ui/src/renderer/src/page/MainLayout/MarkAsNotSuitRecord.vue index 042206d..3c85806 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/MarkAsNotSuitRecord.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/MarkAsNotSuitRecord.vue @@ -46,6 +46,10 @@ {{ markReasonTopicMap[row.markReason] }}
{{ formatMarkReason(row) }}
+
@@ -214,7 +218,8 @@ const markReasonTopicMap = { [MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON]: '手动标记不合适', [MarkAsNotSuitReason.JOB_NOT_SUIT]: '职位不合适', [MarkAsNotSuitReason.JOB_CITY_NOT_SUIT]: '工作地不合适', - [MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT]: '工作经验不合适' + [MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT]: '工作经验不合适', + [MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT]: '薪资不合适' } function formatMarkReason(row: VMarkAsNotSuitLog) { @@ -259,6 +264,21 @@ function formatMarkReason(row: VMarkAsNotSuitLog) { .filter(Boolean) .join('\n') } + case MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT: { + const extInfo = (() => { + try { + return JSON.parse(row.extInfo) + } catch { + return null + } + })() + return [ + extInfo?.salaryDesc && `薪资:${extInfo.salaryDesc}`, + extInfo?.chosenReasonInUi?.text && `Boss选项内容:${extInfo.chosenReasonInUi.text}` + ] + .filter(Boolean) + .join('\n') + } default: { return '' } From 2dad39c8e430f350dfbf755e0d611218621e24ae Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Tue, 3 Jun 2025 00:50:08 +0800 Subject: [PATCH 8/9] =?UTF-8?q?disable=20`=E5=9C=A8=E6=A0=A1=E7=94=9F`=20o?= =?UTF-8?q?ption=20of=20work=20exp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GeekAutoStartChatWithBoss/index.vue | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue index 5bf5370..0e487bb 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue @@ -404,7 +404,7 @@
-
工作经验
+
工作经验(暂不支持按日计算薪资的实习类职位)
gtagRenderer('expect_work_exp_list_changed', { value })" >
@@ -911,6 +916,9 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => { res.config['boss.json'].expectWorkExpList.length ? res.config['boss.json'].expectWorkExpList : [] + const s = new Set([...(formContent.value?.expectWorkExpList ?? [])]) + s.delete('在校生') + formContent.value.expectWorkExpList = [...s] formContent.value.expectWorkExpNotMatchStrategy = res.config['boss.json'].expectWorkExpNotMatchStrategy ?? MarkAsNotSuitOp.NO_OP formContent.value.strategyScopeOptionWhenMarkJobWorkExpNotMatch = From eefb25a3dae474cbde8a92adf06b5ed80e59280a Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sun, 8 Jun 2025 10:20:07 +0800 Subject: [PATCH 9/9] enhance ui appearance --- .../components/CityChooser.vue | 7 +- .../GeekAutoStartChatWithBoss/index.vue | 109 +++++++++--------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/components/CityChooser.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/components/CityChooser.vue index 2e1893e..b07f057 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/components/CityChooser.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/components/CityChooser.vue @@ -11,7 +11,12 @@
当前未选择任何期望城市,将不会按照城市进行筛选
-
+
-
工作地
+
工作地
-
-
+
薪资(仅支持按月计算薪资的职位;非按月计算薪资职位(例如兼职职位、实习职位)将直接跳过)
-
-
工作经验(暂不支持按日计算薪资的实习类职位)
+
工作经验(暂不支持按日计算薪资的实习类职位)
-
-
+
职位类型正则(推荐填写,不区分大小写)
-
+
职位描述正则(不区分大小写)
-
当前职位名称/类型/描述不符合投递条件时:
-
- - - {{ op.name }} + 当前职位名称/类型/描述不符合投递条件时: +
+
+ + - - -
-
+ {{ op.name }} + + +
+
+
@@ -1153,7 +1148,7 @@ const strategyScopeOptionWhenMarkJobNotMatch = [ value: StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB }, { - name: '仅和“期望公司白名单”匹配的职位', + name: '仅和“公司白名单”匹配的职位', value: StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB } ]