mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-05-20 15:49:59 +08:00
Merge branch 'master' into feature/ui
This commit is contained in:
22
README.md
22
README.md
@@ -156,8 +156,8 @@ Boss不明原因已读不回?简历就是投不出去?
|
||||
一个岗位可以收到一堆简历投递,大部分简历最终的归宿都是人才库或者垃圾场
|
||||
|
||||
当然,如果运气好:
|
||||
- 好不容易过了 HR 面,到了 Offer 阶段,HR / 用人部门 几乎都在极限压缩用人成本,经常能被恶心到,但你又没有其它更好 Offer ,不敢贸然放弃这个烂 Offer
|
||||
- 终于你自我催眠(类似:“领导看我薪资低,所以一定会争取给我涨薪”、“领导看我薪资低,所以假设我加倍努力工作绩效一定会向我倾斜”、“领导画的饼很好,吃了一定能有好结果”),接了烂 Offer 入了职,然而经过一段时间的接触,最终结果完全不符合期望(诸如:“团队很难融入”、“协作方经常踢皮球”、“你需要做很多脏活累活,而且要帮前人擦屁股”、“领导希望用最小成本把你招来,这样裁员时可以最小成本把你打发走”、“团队需要新人来背C/M-/3.25/裁员指标”、“领导分配的工作和领导入职时画的诱人的饼完全不一致”)
|
||||
- 好不容易过了 HR 面,到了 Offer 阶段,HR / 用人部门 几乎都在极限压缩用人成本,经常能被恶心到,但你又没有其它更好 Offer ,不敢贸然放弃这个不满意的 Offer
|
||||
- 终于你自我催眠(类似:“领导看我薪资低,所以一定会争取给我涨薪”、“领导看我薪资低,所以假设我加倍努力工作绩效一定会向我倾斜”、“领导画的饼很好,吃了一定能有好结果”),接了不满意的 Offer 入了职,然而经过一段时间的接触,最终结果完全不符合期望(诸如:“团队很难融入”、“协作方经常踢皮球”、“你需要做很多脏活累活,而且要帮前人擦屁股”、“领导希望用最小成本把你招来,这样裁员时可以最小成本把你打发走”、“团队需要新人来背C/M-/3.25/裁员指标”、“领导分配的工作和领导入职时画的诱人的饼完全不一致”)
|
||||
|
||||
为了避免这种情况的发生,找工作时还是需要尽可能多的面试,多个选择。如果真的不慎遭遇了这些情况,让你认为在当前岗位继续做下去的收益不如离职换工作的收益,那就做好走的准备吧
|
||||
|
||||
@@ -170,7 +170,19 @@ Boss不明原因已读不回?简历就是投不出去?
|
||||
|
||||
人工筛选这些职位会有很大的心智负担,真的会吐……
|
||||
|
||||
因此,我在Boss炸弹代码中,加入了清理机制,将通过标记不合适的方式,尝试让这些不活跃职位、不合适职位消失;保证只开聊符合你口味的职位
|
||||
因此,我在Boss炸弹代码中,加入了清理机制,将通过标记不合适的方式,尝试让这些不活跃职位、不合适职位消失;保证只开聊符合你口味的职位。
|
||||
|
||||
## 使用必读及免责声明
|
||||
如下是使用必读及免责声明,请您务必逐条阅读;本程序首次启动时,您还会再看到一次;若您不接受如下提到的任何内容,请不要使用本程序。
|
||||
- 本程序从某种程度上说属于辅助工具,与《<a href="https://about.zhipin.com/agreement/?id=registerprotocol_30" rel="noreferer noopener" target="blank">Boss直聘用户协议</a>》(2023年3月版)相关条款相违背,您在注册Boss直聘时已签署过这一条款;根据该条款`七、用户的平台使用义务`、`八、违约责任` 章节,如果一些非正常用户行为被风控监测到,您需要承受包括不仅限于**账号被强制退出登录**、**账号被限制使用**、**账号被封禁**等对您不利的风险;因此使用本程序即意味着**您愿意接受以上风险**,且如果相关风险发生,您需要自行承担相关后果,**本程序概不负责** 。
|
||||
- 本程序会通过尽可能模仿用户行为来规避相关风险,但并不能保证可以完全规避。建议您使用本程序时**注意节制**,建议当天开聊次数用尽后,隔几天再使用。建议您**注册一个本程序专用的新的Boss直聘账号**进行求职。
|
||||
- 本程序原理是模拟用户在Boss直聘网页上进行点击操作;Boss直聘网站每过一段时间会发生改版,且有可能包含A/B实验,这将导致本程序相关脚本失效。如果您在使用过程中遇上程序未按照预期执行的情况,请[点击这里](https://github.com/geekgeekrun/geekgeekrun/issues/new)进行反馈。
|
||||
- 您的雇主可能会对您的计算机终端或网络进行监控,从而审计、跟踪您的行为;建议您**不要在您雇主提供的计算机终端或网络上使用本程序**。
|
||||
- 本程序需要存储您的登录凭据,即Cookie,来模拟您在Boss直聘上开聊Boss的行为;本程序仅会把您的Cookie存储在本地,并在您访问Boss直聘时将其传输到Boss直聘,**不会泄露给第三方**,也不会进行除自动开聊Boss以外的行为;**请勿向他人泄漏您的Cookie**。
|
||||
- 本程序**不会上报能够识别出您身份的信息**,**不会向您的雇主报告您的求职行为**。
|
||||
- 本程序**不对您的求职过程与结果负责**,为您开聊的职位均在Boss直聘上发布;请**自行甄别为您开聊的公司、认真决定是否参加面试、慎重选择Offer**。
|
||||
- 请在Boss直聘上自行**屏蔽您不期望投递的公司**。
|
||||
- 本程序经历过了多次测试,理论上来说大部分情况下可以正常运行;如果您有顾虑,建议通过VMWare WorkStation/Fusion、VirtualBox、Hyper-V/Windows沙盒等虚拟化技术运行本程序。如发生问题,请[点击这里](https://github.com/geekgeekrun/geekgeekrun/issues/new)进行反馈。
|
||||
|
||||
--------
|
||||
|
||||
@@ -180,10 +192,12 @@ Boss不明原因已读不回?简历就是投不出去?
|
||||
|
||||
祝你求职成功,事业顺利,事事顺心
|
||||
|
||||
## Star 数据 感谢支持
|
||||
## Star
|
||||
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=geekgeekrun/geekgeekrun&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=geekgeekrun/geekgeekrun&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=geekgeekrun/geekgeekrun&type=Date" />
|
||||
</picture>
|
||||
|
||||
感谢支持
|
||||
|
||||
@@ -16,9 +16,9 @@ import { calculateTotalCombinations, combineFiltersWithConstraintsGenerator } fr
|
||||
import { default as jobFilterConditions } from './internal-config/job-filter-conditions-20241002.json'
|
||||
import { default as rawIndustryFilterExemption } from './internal-config/job-filter-industry-filter-exemption-20241002.json'
|
||||
import { ChatStartupFrom } from '@geekgeekrun/sqlite-plugin/dist/entity/ChatStartupLog'
|
||||
import { MarkAsNotSuitReason, MarkAsNotSuitOp, StrategyScopeOptionWhenMarkJobNotMatch } from '@geekgeekrun/sqlite-plugin/dist/enums'
|
||||
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 => {
|
||||
@@ -86,6 +86,19 @@ const expectCityList = readConfigFile('boss.json').expectCityList ?? []
|
||||
|
||||
const strategyScopeOptionWhenMarkJobCityNotMatch = readConfigFile('boss.json').strategyScopeOptionWhenMarkJobCityNotMatch ?? StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||
|
||||
// salary
|
||||
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').expectSalaryNotMatchStrategy ?? MarkAsNotSuitOp.NO_OP
|
||||
const isSalaryFilterEnabled = expectSalaryLow || expectSalaryHigh
|
||||
const strategyScopeOptionWhenMarkSalaryNotMatch = readConfigFile('boss.json').strategyScopeOptionWhenMarkSalaryNotMatch ?? StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||
|
||||
// work exp
|
||||
const expectWorkExpList = readConfigFile('boss.json').expectWorkExpList ?? []
|
||||
const expectWorkExpNotMatchStrategy = readConfigFile('boss.json').expectWorkExpNotMatchStrategy ?? MarkAsNotSuitOp.NO_OP
|
||||
const strategyScopeOptionWhenMarkJobWorkExpNotMatch = readConfigFile('boss.json').strategyScopeOptionWhenMarkJobWorkExpNotMatch ?? StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||
|
||||
const markAsNotActiveSelectedTimeRange = (() => {
|
||||
let n = readConfigFile('boss.json').markAsNotActiveSelectedTimeRange
|
||||
if (
|
||||
@@ -189,19 +202,16 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
|
||||
}
|
||||
break
|
||||
}
|
||||
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
|
||||
const bossNotActiveOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title$="城市"]`)
|
||||
if (bossNotActiveOptionProxy) {
|
||||
await bossNotActiveOptionProxy.click()
|
||||
case MarkAsNotSuitReason.JOB_WORK_EXP_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="公司不感兴趣"]`))
|
||||
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="面试过/入职过"]`))
|
||||
if (opProxy) {
|
||||
await opProxy.click()
|
||||
isOptionChosen = true
|
||||
} else {
|
||||
const fallbackOptionProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title="同城距离远"]`))
|
||||
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="公司不感兴趣"]`))
|
||||
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="面试过/入职过"]`))
|
||||
if (fallbackOptionProxy) {
|
||||
await fallbackOptionProxy.click()
|
||||
isOptionChosen = true
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -539,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) {
|
||||
@@ -557,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) &&
|
||||
@@ -571,7 +620,7 @@ async function toRecommendPage (hooks) {
|
||||
:
|
||||
true
|
||||
) || (
|
||||
// enter job detail to mark as not suit
|
||||
// enter job detail to mark as not suit for city filter
|
||||
(
|
||||
Array.isArray(expectCityList) &&
|
||||
expectCityList.length &&
|
||||
@@ -581,6 +630,27 @@ async function toRecommendPage (hooks) {
|
||||
].includes(expectCityNotMatchStrategy) &&
|
||||
strategyScopeOptionWhenMarkJobCityNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
||||
) ? !expectCityList.includes(it.cityName) : false
|
||||
) || (
|
||||
// enter job detail to mark as not suit for work exp filter
|
||||
(
|
||||
Array.isArray(expectWorkExpList) &&
|
||||
expectWorkExpList.length &&
|
||||
[
|
||||
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
||||
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL
|
||||
].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
|
||||
)
|
||||
)
|
||||
})
|
||||
@@ -664,6 +734,186 @@ 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 {
|
||||
}
|
||||
}
|
||||
},
|
||||
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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#region
|
||||
// null
|
||||
// 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃
|
||||
@@ -674,122 +924,56 @@ 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)
|
||||
) {
|
||||
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
|
||||
}
|
||||
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
|
||||
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
|
||||
|
||||
@@ -4,6 +4,8 @@ export enum MarkAsNotSuitReason {
|
||||
USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON = 2,
|
||||
JOB_NOT_SUIT = 3,
|
||||
JOB_CITY_NOT_SUIT = 4,
|
||||
JOB_WORK_EXP_NOT_SUIT = 5,
|
||||
JOB_SALARY_NOT_SUIT = 6,
|
||||
}
|
||||
|
||||
export enum MarkAsNotSuitOp {
|
||||
@@ -19,5 +21,5 @@ export enum StrategyScopeOptionWhenMarkJobNotMatch {
|
||||
|
||||
export enum SalaryCalculateWay {
|
||||
MONTH_SALARY = 1,
|
||||
ANNUAL_PACKAGE = 2
|
||||
ANNUAL_PACKAGE = 2,
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "geekgeekrun-ui",
|
||||
"version": "0.7.1",
|
||||
"version": "0.8.0",
|
||||
"description": "Boss 炸弹 - 自动开聊Boss,助力每位打工人求职!",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "geekgeekrun",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "0.7.1",
|
||||
"buildVersion": 14,
|
||||
"buildTime": 1748459396794,
|
||||
"buildHash": "d479687b8ba13c6a7bb81dbade1c29317add46e7",
|
||||
"version": "0.8.0",
|
||||
"buildVersion": 15,
|
||||
"buildTime": 1749349412239,
|
||||
"buildHash": "9b64f05cb6205fc89bd3ad1c08a59993cd6ac127",
|
||||
"name": "geekgeekrun-ui"
|
||||
}
|
||||
@@ -11,8 +11,23 @@
|
||||
<div v-else>
|
||||
<div>当前未选择任何期望城市,将不会按照城市进行筛选</div>
|
||||
</div>
|
||||
<div>
|
||||
<el-button size="small" type="primary" @click="isDialogVisible = true">选择城市</el-button>
|
||||
<div
|
||||
line-height-1
|
||||
:style="{
|
||||
marginTop: modelValue?.length ? '10px' : ''
|
||||
}"
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="
|
||||
() => {
|
||||
isDialogVisible = true
|
||||
gtagRenderer('choose_city_entry_button_clicked')
|
||||
}
|
||||
"
|
||||
>选择城市</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="modelValue?.length"
|
||||
size="small"
|
||||
@@ -105,6 +120,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { PropType, ref } from 'vue'
|
||||
import cityGroupData from '../../../../../../common/constant/cityGroup.json'
|
||||
import { gtagRenderer } from '@renderer/utils/gtag'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@@ -136,23 +152,29 @@ for (const group of cityGroup) {
|
||||
function handleDialogOpen() {
|
||||
activeTabName.value = '热门城市'
|
||||
selectedCities.value = [...(props.modelValue ?? [])]
|
||||
gtagRenderer('choose_city_dialog_open')
|
||||
}
|
||||
|
||||
function handleCancelClicked() {
|
||||
gtagRenderer('choose_city_cancel_button_clicked')
|
||||
isDialogVisible.value = false
|
||||
}
|
||||
function handleConfirmClicked() {
|
||||
gtagRenderer('choose_city_confirm_button_clicked', { value: selectedCities.value.join(',') })
|
||||
isDialogVisible.value = false
|
||||
emits('update:modelValue', [...(selectedCities.value ?? [])])
|
||||
}
|
||||
function handleDialogClosed() {
|
||||
selectedCities.value = []
|
||||
gtagRenderer('choose_city_dialog_closed')
|
||||
}
|
||||
|
||||
function handleClearSelectedCitiesInModelValue() {
|
||||
emits('update:modelValue', [])
|
||||
gtagRenderer('clear_selected_cities_in_mv_clicked')
|
||||
}
|
||||
function handleClearSelectedCitiesInDialog() {
|
||||
selectedCities.value = []
|
||||
gtagRenderer('clear_selected_cities_in_dialog_clicked')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
</el-form-item>
|
||||
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||
<div mt16px>
|
||||
<div font-size-14px>工作地</div>
|
||||
<div font-size-14px mb8px>工作地</div>
|
||||
<div
|
||||
:style="{
|
||||
display: 'flex',
|
||||
@@ -100,15 +100,10 @@
|
||||
<div
|
||||
v-if="formContent.expectCityList?.length"
|
||||
:style="{
|
||||
backgroundColor: '#f0f0f0',
|
||||
width: '1px'
|
||||
}"
|
||||
></div>
|
||||
<div
|
||||
v-if="formContent.expectCityList?.length"
|
||||
:style="{
|
||||
flex: 1,
|
||||
minWidth: '400px'
|
||||
width: '400px',
|
||||
borderLeft: '1px solid #f0f0f0',
|
||||
paddingLeft: '10px',
|
||||
flex: `0 0 auto`
|
||||
}"
|
||||
>
|
||||
<el-form-item
|
||||
@@ -166,7 +161,7 @@
|
||||
</div>
|
||||
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||
<div mt16px>
|
||||
<div font-size-14px>
|
||||
<div font-size-14px mb8px>
|
||||
薪资(仅支持按月计算薪资的职位;非按月计算薪资职位(例如兼职职位、实习职位)将直接跳过)
|
||||
</div>
|
||||
<div
|
||||
@@ -338,15 +333,10 @@
|
||||
<div
|
||||
v-if="isShowSalaryMarkAsNotSuitStrategy"
|
||||
:style="{
|
||||
backgroundColor: '#f0f0f0',
|
||||
width: '1px'
|
||||
}"
|
||||
></div>
|
||||
<div
|
||||
v-if="isShowSalaryMarkAsNotSuitStrategy"
|
||||
:style="{
|
||||
flex: 1,
|
||||
minWidth: '400px'
|
||||
width: '400px',
|
||||
borderLeft: '1px solid #f0f0f0',
|
||||
paddingLeft: '10px',
|
||||
flex: `0 0 auto`
|
||||
}"
|
||||
>
|
||||
<el-form-item
|
||||
@@ -376,7 +366,7 @@
|
||||
[
|
||||
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
||||
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL
|
||||
].includes(formContent.expectCityNotMatchStrategy)
|
||||
].includes(formContent.expectSalaryNotMatchStrategy)
|
||||
"
|
||||
mb0
|
||||
:style="{
|
||||
@@ -404,7 +394,7 @@
|
||||
</div>
|
||||
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||
<div mt16px>
|
||||
<div font-size-14px>工作经验</div>
|
||||
<div font-size-14px mb8px>工作经验(暂不支持按日计算薪资的实习类职位)</div>
|
||||
<div
|
||||
:style="{
|
||||
display: 'flex',
|
||||
@@ -429,9 +419,14 @@
|
||||
@change="(value) => gtagRenderer('expect_work_exp_list_changed', { value })"
|
||||
>
|
||||
<template v-for="op in conditions.experienceList" :key="op.code">
|
||||
<el-option v-if="!!op.code" :label="op.name" :value="op.name">{{
|
||||
op.name
|
||||
}}</el-option>
|
||||
<el-option
|
||||
v-if="!!op.code"
|
||||
:label="op.name"
|
||||
:value="op.name"
|
||||
:disabled="op.code === 108 || op.name === '在校生'"
|
||||
>
|
||||
{{ op.name }}</el-option
|
||||
>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
@@ -439,15 +434,10 @@
|
||||
<div
|
||||
v-if="formContent.expectWorkExpList?.length"
|
||||
:style="{
|
||||
backgroundColor: '#f0f0f0',
|
||||
width: '1px'
|
||||
}"
|
||||
></div>
|
||||
<div
|
||||
v-if="formContent.expectWorkExpList?.length"
|
||||
:style="{
|
||||
flex: 1,
|
||||
minWidth: '400px'
|
||||
width: '400px',
|
||||
borderLeft: '1px solid #f0f0f0',
|
||||
paddingLeft: '10px',
|
||||
flex: `0 0 auto`
|
||||
}"
|
||||
>
|
||||
<el-form-item
|
||||
@@ -473,6 +463,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="
|
||||
[
|
||||
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
||||
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL
|
||||
].includes(formContent.expectWorkExpNotMatchStrategy)
|
||||
"
|
||||
mb0
|
||||
:style="{
|
||||
width: '100%'
|
||||
@@ -609,7 +605,7 @@
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div mb10px font-size-12px flex flex-justify-center>且</div>
|
||||
<div mb10px font-size-12px flex flex-justify-center fw-800>且</div>
|
||||
<el-form-item mb0 prop="expectJobTypeRegExpStr">
|
||||
<div font-size-12px>职位类型正则(推荐填写,不区分大小写)</div>
|
||||
<el-input
|
||||
@@ -621,7 +617,7 @@
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div mb10px font-size-12px flex flex-justify-center>且</div>
|
||||
<div mb10px font-size-12px flex flex-justify-center fw-800>且</div>
|
||||
<el-form-item mb0 prop="expectJobDescRegExpStr">
|
||||
<div font-size-12px>职位描述正则(不区分大小写)</div>
|
||||
<el-input
|
||||
@@ -634,32 +630,42 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="mt10px lh-2em font-size-12px">当前职位名称/类型/描述不符合投递条件时:</div>
|
||||
<div
|
||||
:style="{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1.25fr 0.75fr',
|
||||
gap: '10px 0',
|
||||
width: '100%',
|
||||
alignItems: 'end'
|
||||
}"
|
||||
<template
|
||||
v-if="
|
||||
formContent.expectJobNameRegExpStr?.trim() ||
|
||||
formContent.expectJobTypeRegExpStr?.trim() ||
|
||||
formContent.expectJobDescRegExpStr?.trim()
|
||||
"
|
||||
>
|
||||
<el-form-item mb0>
|
||||
<el-select
|
||||
v-model="formContent.jobNotMatchStrategy"
|
||||
@change="(value) => gtagRenderer('job_not_match_strategy_changed', { value })"
|
||||
>
|
||||
<el-option
|
||||
v-for="op in strategyOptionWhenCurrentJobNotMatch"
|
||||
:key="op.value"
|
||||
:label="op.name"
|
||||
:value="op.value"
|
||||
>{{ op.name }}</el-option
|
||||
<div class="mt10px lh-2em font-size-12px">
|
||||
当前职位名称/类型/描述不符合投递条件时:
|
||||
</div>
|
||||
<div
|
||||
:style="{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1.25fr 0.75fr',
|
||||
gap: '10px 0',
|
||||
width: '100%',
|
||||
alignItems: 'end'
|
||||
}"
|
||||
>
|
||||
<el-form-item mb0>
|
||||
<el-select
|
||||
v-model="formContent.jobNotMatchStrategy"
|
||||
@change="(value) => gtagRenderer('job_not_match_strategy_changed', { value })"
|
||||
>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div />
|
||||
</div>
|
||||
<el-option
|
||||
v-for="op in strategyOptionWhenCurrentJobNotMatch"
|
||||
:key="op.value"
|
||||
:label="op.name"
|
||||
:value="op.value"
|
||||
>{{ op.name }}</el-option
|
||||
>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||
<div mt16px>
|
||||
@@ -905,6 +911,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 =
|
||||
@@ -1139,7 +1148,7 @@ const strategyScopeOptionWhenMarkJobNotMatch = [
|
||||
value: StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
||||
},
|
||||
{
|
||||
name: '仅和“期望公司白名单”匹配的职位',
|
||||
name: '仅和“公司白名单”匹配的职位',
|
||||
value: StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||
}
|
||||
]
|
||||
|
||||
@@ -42,6 +42,14 @@
|
||||
<strong>{{ markReasonTopicMap[row.markReason] }}</strong>
|
||||
<pre class="m-0 of-auto">{{ formatMarkReason(row) }}</pre>
|
||||
</template>
|
||||
<template v-if="row.markReason === MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT">
|
||||
<strong>{{ markReasonTopicMap[row.markReason] }}</strong>
|
||||
<pre class="m-0 of-auto">{{ formatMarkReason(row) }}</pre>
|
||||
</template>
|
||||
<template v-if="row.markReason === MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT">
|
||||
<strong>{{ markReasonTopicMap[row.markReason] }}</strong>
|
||||
<pre class="m-0 of-auto">{{ formatMarkReason(row) }}</pre>
|
||||
</template>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn prop="experienceName" label="工作经验" />
|
||||
@@ -209,7 +217,9 @@ 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]: '工作经验不合适',
|
||||
[MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT]: '薪资不合适'
|
||||
}
|
||||
|
||||
function formatMarkReason(row: VMarkAsNotSuitLog) {
|
||||
@@ -241,6 +251,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 {
|
||||
@@ -253,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 ''
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user