mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-07 08:27:13 +08:00
Merge branch 'feature/ui'
This commit is contained in:
@@ -16,9 +16,9 @@ import { calculateTotalCombinations, combineFiltersWithConstraintsGenerator } fr
|
|||||||
import { default as jobFilterConditions } from './internal-config/job-filter-conditions-20241002.json'
|
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 { default as rawIndustryFilterExemption } from './internal-config/job-filter-industry-filter-exemption-20241002.json'
|
||||||
import { ChatStartupFrom } from '@geekgeekrun/sqlite-plugin/dist/entity/ChatStartupLog'
|
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 { activeDescList } from './constant.mjs'
|
||||||
|
import { parseSalary } from "@geekgeekrun/sqlite-plugin/dist/utils/parser"
|
||||||
const jobFilterConditionsMapByCode = {}
|
const jobFilterConditionsMapByCode = {}
|
||||||
Object.values(jobFilterConditions).forEach(arr => {
|
Object.values(jobFilterConditions).forEach(arr => {
|
||||||
arr.forEach(option => {
|
arr.forEach(option => {
|
||||||
@@ -86,6 +86,19 @@ const expectCityList = readConfigFile('boss.json').expectCityList ?? []
|
|||||||
|
|
||||||
const strategyScopeOptionWhenMarkJobCityNotMatch = readConfigFile('boss.json').strategyScopeOptionWhenMarkJobCityNotMatch ?? StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
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 = (() => {
|
const markAsNotActiveSelectedTimeRange = (() => {
|
||||||
let n = readConfigFile('boss.json').markAsNotActiveSelectedTimeRange
|
let n = readConfigFile('boss.json').markAsNotActiveSelectedTimeRange
|
||||||
if (
|
if (
|
||||||
@@ -189,19 +202,16 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
|
case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT:
|
||||||
const bossNotActiveOptionProxy = await chooseReasonDialogProxy.$(`.zp-type-item[title$="城市"]`)
|
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT:
|
||||||
if (bossNotActiveOptionProxy) {
|
case MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT: {
|
||||||
await bossNotActiveOptionProxy.click()
|
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
|
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
|
break
|
||||||
}
|
}
|
||||||
@@ -539,10 +549,29 @@ async function toRecommendPage (hooks) {
|
|||||||
// due to city can get from list immediately
|
// due to city can get from list immediately
|
||||||
// so just set those job which city is not suit to blockJobNotSuit
|
// so just set those job which city is not suit to blockJobNotSuit
|
||||||
// to skip view detail
|
// 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 (
|
if (
|
||||||
expectCityNotMatchStrategy === MarkAsNotSuitOp.NO_OP &&
|
(
|
||||||
Array.isArray(expectCityList) &&
|
expectCityNotMatchStrategy === MarkAsNotSuitOp.NO_OP &&
|
||||||
expectCityList.length
|
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`)
|
console.log(`add job city not suit into blockJobNotSuit set`)
|
||||||
for (const it of jobListData) {
|
for (const it of jobListData) {
|
||||||
@@ -557,6 +586,26 @@ async function toRecommendPage (hooks) {
|
|||||||
let hasReachLastPage = false
|
let hasReachLastPage = false
|
||||||
let targetJobIndex = -1
|
let targetJobIndex = -1
|
||||||
let targetJobData, selectedJobData // they show be same; one is from list, another is from detail
|
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 () {
|
function getTempTargetJobIndexToCheckDetail () {
|
||||||
return jobListData.findIndex(it => {
|
return jobListData.findIndex(it => {
|
||||||
return !blockBossNotNewChat.has(it.encryptBossId) &&
|
return !blockBossNotNewChat.has(it.encryptBossId) &&
|
||||||
@@ -571,7 +620,7 @@ async function toRecommendPage (hooks) {
|
|||||||
:
|
:
|
||||||
true
|
true
|
||||||
) || (
|
) || (
|
||||||
// enter job detail to mark as not suit
|
// enter job detail to mark as not suit for city filter
|
||||||
(
|
(
|
||||||
Array.isArray(expectCityList) &&
|
Array.isArray(expectCityList) &&
|
||||||
expectCityList.length &&
|
expectCityList.length &&
|
||||||
@@ -581,6 +630,27 @@ async function toRecommendPage (hooks) {
|
|||||||
].includes(expectCityNotMatchStrategy) &&
|
].includes(expectCityNotMatchStrategy) &&
|
||||||
strategyScopeOptionWhenMarkJobCityNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
strategyScopeOptionWhenMarkJobCityNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
||||||
) ? !expectCityList.includes(it.cityName) : false
|
) ? !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
|
// save the job detail info
|
||||||
await hooks.jobDetailIsGetFromRecommendList?.promise(targetJobData)
|
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
|
//#region
|
||||||
// null
|
// null
|
||||||
// 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃
|
// 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃
|
||||||
@@ -674,122 +924,56 @@ async function toRecommendPage (hooks) {
|
|||||||
markAsNotActiveSelectedTimeRange > 0 &&
|
markAsNotActiveSelectedTimeRange > 0 &&
|
||||||
indexOfActiveText > 0 && indexOfActiveText <= markAsNotActiveSelectedTimeRange
|
indexOfActiveText > 0 && indexOfActiveText <= markAsNotActiveSelectedTimeRange
|
||||||
) {
|
) {
|
||||||
blockBossNotActive.add(targetJobData.jobInfo.encryptUserId)
|
|
||||||
// click prevent recommend button
|
// click prevent recommend button
|
||||||
if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) {
|
notSuitReasonIdToStrategyMap.active = jobNotActiveStrategy
|
||||||
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
|
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(Array.isArray(expectCityList) && expectCityList.length) && !expectCityList.includes(selectedJobData.cityName)
|
(Array.isArray(expectCityList) && expectCityList.length) && !expectCityList.includes(selectedJobData.cityName)
|
||||||
) {
|
) {
|
||||||
blockJobNotSuit.add(targetJobData.jobInfo.encryptId)
|
notSuitReasonIdToStrategyMap.city = expectCityNotMatchStrategy
|
||||||
if (expectCityNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) {
|
}
|
||||||
try {
|
if (
|
||||||
const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_CITY_NOT_SUIT)
|
(Array.isArray(expectWorkExpList) && expectWorkExpList.length) && !expectWorkExpList.includes(selectedJobData.jobExperience)
|
||||||
await hooks.jobMarkedAsNotSuit.promise(
|
) {
|
||||||
targetJobData,
|
notSuitReasonIdToStrategyMap.workExp = expectWorkExpNotMatchStrategy
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!testIfJobTitleOrDescriptionSuit(targetJobData.jobInfo)
|
!testIfJobTitleOrDescriptionSuit(targetJobData.jobInfo)
|
||||||
) {
|
) {
|
||||||
blockJobNotSuit.add(targetJobData.jobInfo.encryptId)
|
notSuitReasonIdToStrategyMap.jobDetail = jobNotMatchStrategy
|
||||||
if (jobNotMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) {
|
}
|
||||||
try {
|
if (
|
||||||
const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.JOB_NOT_SUIT)
|
!checkIfSalarySuit(selectedJobData.salaryDesc)
|
||||||
await hooks.jobMarkedAsNotSuit.promise(
|
) {
|
||||||
targetJobData,
|
notSuitReasonIdToStrategyMap.salary = expectSalaryNotMatchStrategy
|
||||||
{
|
}
|
||||||
markFrom: ChatStartupFrom.AutoFromRecommendList,
|
// #endregion
|
||||||
markReason: MarkAsNotSuitReason.JOB_NOT_SUIT,
|
console.log('not suit reason and related strategy: ', notSuitReasonIdToStrategyMap)
|
||||||
extInfo: {
|
|
||||||
bossActiveTimeDesc: targetJobData.bossInfo.activeTimeDesc,
|
// #region execute mark logic
|
||||||
chosenReasonInUi
|
// 1. find the one mark on Boss
|
||||||
},
|
const markOnBossCondition = Object.keys(notSuitReasonIdToStrategyMap).find(k => notSuitReasonIdToStrategyMap[k] === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS)
|
||||||
markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
if (markOnBossCondition) {
|
||||||
}
|
await notSuitConditionHandleMap[markOnBossCondition]()
|
||||||
)
|
|
||||||
} 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 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue continueFind
|
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 (
|
if (
|
||||||
|
// test company again - when allow list not include target company, just skip
|
||||||
enableCompanyAllowList && ![...expectCompanySet].find(
|
enableCompanyAllowList && ![...expectCompanySet].find(
|
||||||
name => selectedJobData.brandName?.toLowerCase?.()?.includes(name.toLowerCase())
|
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
|
// just skip
|
||||||
continue continueFind
|
continue continueFind
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ export enum MarkAsNotSuitReason {
|
|||||||
USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON = 2,
|
USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON = 2,
|
||||||
JOB_NOT_SUIT = 3,
|
JOB_NOT_SUIT = 3,
|
||||||
JOB_CITY_NOT_SUIT = 4,
|
JOB_CITY_NOT_SUIT = 4,
|
||||||
|
JOB_WORK_EXP_NOT_SUIT = 5,
|
||||||
|
JOB_SALARY_NOT_SUIT = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MarkAsNotSuitOp {
|
export enum MarkAsNotSuitOp {
|
||||||
@@ -16,3 +18,8 @@ export enum StrategyScopeOptionWhenMarkJobNotMatch {
|
|||||||
ALL_JOB = 1,
|
ALL_JOB = 1,
|
||||||
ONLY_COMPANY_MATCHED_JOB = 2
|
ONLY_COMPANY_MATCHED_JOB = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SalaryCalculateWay {
|
||||||
|
MONTH_SALARY = 1,
|
||||||
|
ANNUAL_PACKAGE = 2,
|
||||||
|
}
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
"electron": "28.2.0",
|
"electron": "28.2.0",
|
||||||
"electron-builder": "^24.9.1",
|
"electron-builder": "^24.9.1",
|
||||||
"electron-vite": "^2.0.0",
|
"electron-vite": "^2.0.0",
|
||||||
"element-plus": "^2.5.5",
|
"element-plus": "^2.8.4",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-plugin-vue": "^9.20.1",
|
"eslint-plugin-vue": "^9.20.1",
|
||||||
"find-chrome-bin": "^2.0.1",
|
"find-chrome-bin": "^2.0.1",
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ export default function initIpc() {
|
|||||||
if (hasOwn(payload, 'autoReminder')) {
|
if (hasOwn(payload, 'autoReminder')) {
|
||||||
bossConfig.autoReminder = payload.autoReminder
|
bossConfig.autoReminder = payload.autoReminder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// city
|
||||||
if (hasOwn(payload, 'expectCityList')) {
|
if (hasOwn(payload, 'expectCityList')) {
|
||||||
bossConfig.expectCityList = payload.expectCityList
|
bossConfig.expectCityList = payload.expectCityList
|
||||||
}
|
}
|
||||||
@@ -117,6 +119,37 @@ export default function initIpc() {
|
|||||||
bossConfig.strategyScopeOptionWhenMarkJobCityNotMatch =
|
bossConfig.strategyScopeOptionWhenMarkJobCityNotMatch =
|
||||||
payload.strategyScopeOptionWhenMarkJobCityNotMatch
|
payload.strategyScopeOptionWhenMarkJobCityNotMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// salary
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// work exp
|
||||||
|
if (hasOwn(payload, 'expectWorkExpList')) {
|
||||||
|
bossConfig.expectWorkExpList = payload.expectWorkExpList
|
||||||
|
}
|
||||||
|
if (hasOwn(payload, 'expectWorkExpNotMatchStrategy')) {
|
||||||
|
bossConfig.expectWorkExpNotMatchStrategy = payload.expectWorkExpNotMatchStrategy
|
||||||
|
}
|
||||||
|
if (hasOwn(payload, 'strategyScopeOptionWhenMarkJobWorkExpNotMatch')) {
|
||||||
|
bossConfig.strategyScopeOptionWhenMarkJobWorkExpNotMatch =
|
||||||
|
payload.strategyScopeOptionWhenMarkJobWorkExpNotMatch
|
||||||
|
}
|
||||||
|
|
||||||
promiseArr.push(writeConfigFile('boss.json', bossConfig))
|
promiseArr.push(writeConfigFile('boss.json', bossConfig))
|
||||||
|
|
||||||
if (hasOwn(payload, 'expectCompanies')) {
|
if (hasOwn(payload, 'expectCompanies')) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export function createMainWindow(): BrowserWindow {
|
|||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 1280,
|
width: 1280,
|
||||||
height: 720,
|
height: 720,
|
||||||
minWidth: 1024,
|
minWidth: 1280,
|
||||||
show: false,
|
show: false,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
...(process.platform === 'linux'
|
...(process.platform === 'linux'
|
||||||
|
|||||||
+24
-2
@@ -11,8 +11,23 @@
|
|||||||
<div v-else>
|
<div v-else>
|
||||||
<div>当前未选择任何期望城市,将不会按照城市进行筛选</div>
|
<div>当前未选择任何期望城市,将不会按照城市进行筛选</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div
|
||||||
<el-button size="small" type="primary" @click="isDialogVisible = true">选择城市</el-button>
|
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
|
<el-button
|
||||||
v-if="modelValue?.length"
|
v-if="modelValue?.length"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -105,6 +120,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PropType, ref } from 'vue'
|
import { PropType, ref } from 'vue'
|
||||||
import cityGroupData from '../../../../../../common/constant/cityGroup.json'
|
import cityGroupData from '../../../../../../common/constant/cityGroup.json'
|
||||||
|
import { gtagRenderer } from '@renderer/utils/gtag'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@@ -136,23 +152,29 @@ for (const group of cityGroup) {
|
|||||||
function handleDialogOpen() {
|
function handleDialogOpen() {
|
||||||
activeTabName.value = '热门城市'
|
activeTabName.value = '热门城市'
|
||||||
selectedCities.value = [...(props.modelValue ?? [])]
|
selectedCities.value = [...(props.modelValue ?? [])]
|
||||||
|
gtagRenderer('choose_city_dialog_open')
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancelClicked() {
|
function handleCancelClicked() {
|
||||||
|
gtagRenderer('choose_city_cancel_button_clicked')
|
||||||
isDialogVisible.value = false
|
isDialogVisible.value = false
|
||||||
}
|
}
|
||||||
function handleConfirmClicked() {
|
function handleConfirmClicked() {
|
||||||
|
gtagRenderer('choose_city_confirm_button_clicked', { value: selectedCities.value.join(',') })
|
||||||
isDialogVisible.value = false
|
isDialogVisible.value = false
|
||||||
emits('update:modelValue', [...(selectedCities.value ?? [])])
|
emits('update:modelValue', [...(selectedCities.value ?? [])])
|
||||||
}
|
}
|
||||||
function handleDialogClosed() {
|
function handleDialogClosed() {
|
||||||
selectedCities.value = []
|
selectedCities.value = []
|
||||||
|
gtagRenderer('choose_city_dialog_closed')
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClearSelectedCitiesInModelValue() {
|
function handleClearSelectedCitiesInModelValue() {
|
||||||
emits('update:modelValue', [])
|
emits('update:modelValue', [])
|
||||||
|
gtagRenderer('clear_selected_cities_in_mv_clicked')
|
||||||
}
|
}
|
||||||
function handleClearSelectedCitiesInDialog() {
|
function handleClearSelectedCitiesInDialog() {
|
||||||
selectedCities.value = []
|
selectedCities.value = []
|
||||||
|
gtagRenderer('clear_selected_cities_in_dialog_clicked')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
期望公司白名单(以逗号分隔,不区分大小写;输入框留空表示不筛选)<el-tooltip
|
公司白名单(以逗号分隔,不区分大小写;输入框留空表示不筛选)<el-tooltip
|
||||||
effect="light"
|
effect="light"
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
@show="gtagRenderer('tooltip_show_about_expect_company_figure')"
|
@show="gtagRenderer('tooltip_show_about_expect_company_figure')"
|
||||||
@@ -47,14 +47,13 @@
|
|||||||
<img block h-270px src="../resources/intro-of-job-entry.png" />
|
<img block h-270px src="../resources/intro-of-job-entry.png" />
|
||||||
</template>
|
</template>
|
||||||
<el-button type="text" font-size-12px
|
<el-button type="text" font-size-12px
|
||||||
><span><QuestionFilled w-1em h-1em mr2px /></span
|
><span><QuestionFilled w-1em h-1em mr2px /></span>公司信息UI位置图示</el-button
|
||||||
>期望公司信息位置图示</el-button
|
|
||||||
>
|
>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<el-dropdown @command="handleExpectCompanyTemplateClicked">
|
<el-dropdown @command="handleExpectCompanyTemplateClicked">
|
||||||
<el-button size="small"
|
<el-button size="small"
|
||||||
>期望公司模板 <el-icon class="el-icon--right"><arrow-down /></el-icon
|
>公司列表模板 <el-icon class="el-icon--right"><arrow-down /></el-icon
|
||||||
></el-button>
|
></el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
@@ -76,22 +75,9 @@
|
|||||||
@blur="normalizeExpectCompanies"
|
@blur="normalizeExpectCompanies"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item prop="expectSalary" mb10px>
|
|
||||||
<div
|
|
||||||
font-size-12px
|
|
||||||
:style="{
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
alignItems: 'center',
|
|
||||||
width: '100%'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div>期望薪资范围(以 k 为单位)</div>
|
|
||||||
<el-input />
|
|
||||||
</div>
|
|
||||||
</el-form-item> -->
|
|
||||||
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||||
<div mt16px>
|
<div mt16px>
|
||||||
<div font-size-14px>期望工作地</div>
|
<div font-size-14px mb8px>工作地</div>
|
||||||
<div
|
<div
|
||||||
:style="{
|
:style="{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -114,16 +100,10 @@
|
|||||||
<div
|
<div
|
||||||
v-if="formContent.expectCityList?.length"
|
v-if="formContent.expectCityList?.length"
|
||||||
:style="{
|
:style="{
|
||||||
backgroundColor: '#f0f0f0',
|
width: '400px',
|
||||||
width: '1px'
|
borderLeft: '1px solid #f0f0f0',
|
||||||
}"
|
paddingLeft: '10px',
|
||||||
></div>
|
flex: `0 0 auto`
|
||||||
<div
|
|
||||||
v-if="formContent.expectCityList?.length"
|
|
||||||
prop="expectCityList"
|
|
||||||
:style="{
|
|
||||||
flex: 1,
|
|
||||||
minWidth: '400px'
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
@@ -132,7 +112,7 @@
|
|||||||
width: '100%'
|
width: '100%'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div font-size-12px>当前职位工作地与期望工作地不匹配时:</div>
|
<div font-size-12px>当前职位工作地与选择的工作地不匹配时:</div>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formContent.expectCityNotMatchStrategy"
|
v-model="formContent.expectCityNotMatchStrategy"
|
||||||
@change="
|
@change="
|
||||||
@@ -178,34 +158,340 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<el-tooltip
|
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||||
effect="light"
|
<div mt16px>
|
||||||
placement="bottom-start"
|
<div font-size-14px mb8px>
|
||||||
@show="gtagRenderer('tooltip_show_about_wrongly_mark_not_suit')"
|
薪资(仅支持按月计算薪资的职位;非按月计算薪资职位(例如兼职职位、实习职位)将直接跳过)
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
gap: '10px'
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<template #content>
|
<div>
|
||||||
<ul m0 line-height-1.5em w-400px pl2em>
|
<el-form-item prop="expectSalaryLow" mb10px>
|
||||||
<li>
|
<div w-full>
|
||||||
如有错误标记,请在左侧“<a
|
<div font-size-12px>薪资筛选方式</div>
|
||||||
href="javascript:void(0)"
|
<el-select
|
||||||
style="color: var(--el-color-primary)"
|
v-model="formContent.expectSalaryCalculateWay"
|
||||||
@click.prevent="
|
@change="handleExpectSalaryCalculateWayChanged"
|
||||||
() => {
|
>
|
||||||
gtagRenderer('click_view_mansr_from_boss_b_tooltip')
|
<el-option
|
||||||
$router.push('/main-layout/MarkAsNotSuitRecord')
|
v-for="op in expectSalaryCalculateWayOption"
|
||||||
}
|
:key="op.value"
|
||||||
"
|
:label="op.name"
|
||||||
>标记不合适</a
|
:value="op.value"
|
||||||
>”记录中找到相关记录,来查看职位详情,或手动对这些职位发起会话
|
>{{ op.name }}</el-option
|
||||||
</li>
|
>
|
||||||
</ul>
|
</el-select>
|
||||||
</template>
|
</div>
|
||||||
<el-button type="text" font-size-12px
|
</el-form-item>
|
||||||
><span><QuestionFilled w-1em h-1em mr2px /></span
|
<el-form-item prop="expectSalaryLow" mb10px>
|
||||||
>职位被错误标记不合适时如何处理?</el-button
|
<div>
|
||||||
|
<div font-size-12px>期望薪资范围</div>
|
||||||
|
<div>
|
||||||
|
<el-input-number
|
||||||
|
v-model="formContent.expectSalaryLow"
|
||||||
|
controls-position="right"
|
||||||
|
:min="0"
|
||||||
|
:step="0.25"
|
||||||
|
placeholder="不设置"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
gtagRenderer('expect_salary_low_changed')
|
||||||
|
ensureSalaryRangeCorrect()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #prefix>下限</template>
|
||||||
|
<template #suffix>
|
||||||
|
<template v-if="formContent.expectSalaryLow">
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
formContent.expectSalaryCalculateWay ===
|
||||||
|
SalaryCalculateWay.MONTH_SALARY
|
||||||
|
"
|
||||||
|
>k</template
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
formContent.expectSalaryCalculateWay ===
|
||||||
|
SalaryCalculateWay.ANNUAL_PACKAGE
|
||||||
|
"
|
||||||
|
>W</template
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-input-number>
|
||||||
|
-
|
||||||
|
<el-input-number
|
||||||
|
v-model="formContent.expectSalaryHigh"
|
||||||
|
controls-position="right"
|
||||||
|
:min="0"
|
||||||
|
:step="0.25"
|
||||||
|
placeholder="不设置"
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
gtagRenderer('expect_salary_high_changed')
|
||||||
|
ensureSalaryRangeCorrect()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #prefix>上限</template>
|
||||||
|
<template #suffix>
|
||||||
|
<template v-if="formContent.expectSalaryHigh">
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
formContent.expectSalaryCalculateWay ===
|
||||||
|
SalaryCalculateWay.MONTH_SALARY
|
||||||
|
"
|
||||||
|
>k</template
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
formContent.expectSalaryCalculateWay ===
|
||||||
|
SalaryCalculateWay.ANNUAL_PACKAGE
|
||||||
|
"
|
||||||
|
>W</template
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-input-number>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-if="
|
||||||
|
formContent.expectSalaryCalculateWay === SalaryCalculateWay.ANNUAL_PACKAGE &&
|
||||||
|
(formContent.expectSalaryLow || formContent.expectSalaryHigh)
|
||||||
|
"
|
||||||
|
mb10px
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div font-size-12px>薪资范围满足以下条件的职位将会被匹配</div>
|
||||||
|
<div>
|
||||||
|
<div flex flex-nowrap flex-items-start>
|
||||||
|
<template
|
||||||
|
v-for="(mGroup, index) in [
|
||||||
|
[12, 13, 14, 15, 16, 17, 18],
|
||||||
|
[19, 20, 21, 22, 23, 24]
|
||||||
|
]"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
:style="{
|
||||||
|
lineHeight: '1.25em'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
v-for="(text, i) in ['月薪下限', '月薪上限', '']"
|
||||||
|
:key="i"
|
||||||
|
:style="{
|
||||||
|
borderBottom: '2px solid #f0f0f0'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ text }}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="m in mGroup" :key="m">
|
||||||
|
<td>
|
||||||
|
{{
|
||||||
|
formContent.expectSalaryLow
|
||||||
|
? ((formContent.expectSalaryLow / m) * 10).toFixed(2)
|
||||||
|
: '无下限'
|
||||||
|
}}<small
|
||||||
|
v-if="formContent.expectSalaryLow"
|
||||||
|
class="color-#999 ml-2px"
|
||||||
|
>k</small
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{
|
||||||
|
formContent.expectSalaryHigh
|
||||||
|
? ((formContent.expectSalaryHigh / m) * 10).toFixed(2)
|
||||||
|
: '无上限'
|
||||||
|
}}<small
|
||||||
|
v-if="formContent.expectSalaryHigh"
|
||||||
|
class="color-#999 ml-2px"
|
||||||
|
>k</small
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td>{{ m }}薪</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div v-if="index !== 1" class="bg-#f0f0f0 w-2px flex-self-stretch"></div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isShowSalaryMarkAsNotSuitStrategy"
|
||||||
|
:style="{
|
||||||
|
width: '400px',
|
||||||
|
borderLeft: '1px solid #f0f0f0',
|
||||||
|
paddingLeft: '10px',
|
||||||
|
flex: `0 0 auto`
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
</el-tooltip>
|
<el-form-item
|
||||||
|
mb10px
|
||||||
|
:style="{
|
||||||
|
width: '100%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div font-size-12px>当前职位薪资{{ salaryMarkAsNotSuitLabelText }}时:</div>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.expectSalaryNotMatchStrategy"
|
||||||
|
@change="
|
||||||
|
(value) => gtagRenderer('expect_salary_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
|
||||||
|
>
|
||||||
|
</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.expectSalaryNotMatchStrategy)
|
||||||
|
"
|
||||||
|
mb0
|
||||||
|
:style="{
|
||||||
|
width: '100%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div font-size-12px>标记不合适针对的职位范围:</div>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.strategyScopeOptionWhenMarkSalaryNotMatch"
|
||||||
|
@change="
|
||||||
|
(value) => gtagRenderer('strategy_scope_option_wmjsnm_changed', { value })
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="op in strategyScopeOptionWhenMarkJobNotMatch"
|
||||||
|
:key="op.value"
|
||||||
|
:label="op.name"
|
||||||
|
:value="op.value"
|
||||||
|
>{{ op.name }}</el-option
|
||||||
|
>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||||
|
<div mt16px>
|
||||||
|
<div font-size-14px mb8px>工作经验(暂不支持按日计算薪资的实习类职位)</div>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
gap: '10px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-form-item prop="expectWorkExpList" mb0>
|
||||||
|
<div font-size-12px>认为匹配的工作经验</div>
|
||||||
|
<div
|
||||||
|
font-size-12px
|
||||||
|
:style="{
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.expectWorkExpList"
|
||||||
|
multiple
|
||||||
|
placeholder="不限制,都匹配"
|
||||||
|
@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"
|
||||||
|
:disabled="op.code === 108 || op.name === '在校生'"
|
||||||
|
>
|
||||||
|
{{ op.name }}</el-option
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<div
|
||||||
|
v-if="formContent.expectWorkExpList?.length"
|
||||||
|
:style="{
|
||||||
|
width: '400px',
|
||||||
|
borderLeft: '1px solid #f0f0f0',
|
||||||
|
paddingLeft: '10px',
|
||||||
|
flex: `0 0 auto`
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-form-item
|
||||||
|
mb10px
|
||||||
|
:style="{
|
||||||
|
width: '100%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div font-size-12px>当前工作经验不匹配时:</div>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.expectWorkExpNotMatchStrategy"
|
||||||
|
@change="
|
||||||
|
(value) => gtagRenderer('expect_we_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
|
||||||
|
>
|
||||||
|
</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%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div font-size-12px>标记不合适针对的职位范围:</div>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.strategyScopeOptionWhenMarkJobWorkExpNotMatch"
|
||||||
|
@change="
|
||||||
|
(value) => gtagRenderer('strategy_scope_option_wmjwenm_changed', { value })
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="op in strategyScopeOptionWhenMarkJobNotMatch"
|
||||||
|
:key="op.value"
|
||||||
|
:label="op.name"
|
||||||
|
:value="op.value"
|
||||||
|
>{{ op.name }}</el-option
|
||||||
|
>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="config-section">
|
<el-card class="config-section">
|
||||||
@@ -319,7 +605,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</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">
|
<el-form-item mb0 prop="expectJobTypeRegExpStr">
|
||||||
<div font-size-12px>职位类型正则(推荐填写,不区分大小写)</div>
|
<div font-size-12px>职位类型正则(推荐填写,不区分大小写)</div>
|
||||||
<el-input
|
<el-input
|
||||||
@@ -331,7 +617,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</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">
|
<el-form-item mb0 prop="expectJobDescRegExpStr">
|
||||||
<div font-size-12px>职位描述正则(不区分大小写)</div>
|
<div font-size-12px>职位描述正则(不区分大小写)</div>
|
||||||
<el-input
|
<el-input
|
||||||
@@ -344,32 +630,42 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt10px lh-2em font-size-12px">当前职位名称/类型/描述不符合投递条件时:</div>
|
<template
|
||||||
<div
|
v-if="
|
||||||
:style="{
|
formContent.expectJobNameRegExpStr?.trim() ||
|
||||||
display: 'grid',
|
formContent.expectJobTypeRegExpStr?.trim() ||
|
||||||
gridTemplateColumns: '1.25fr 0.75fr',
|
formContent.expectJobDescRegExpStr?.trim()
|
||||||
gap: '10px 0',
|
"
|
||||||
width: '100%',
|
|
||||||
alignItems: 'end'
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<el-form-item mb0>
|
<div class="mt10px lh-2em font-size-12px">
|
||||||
<el-select
|
当前职位名称/类型/描述不符合投递条件时:
|
||||||
v-model="formContent.jobNotMatchStrategy"
|
</div>
|
||||||
@change="(value) => gtagRenderer('job_not_match_strategy_changed', { value })"
|
<div
|
||||||
>
|
:style="{
|
||||||
<el-option
|
display: 'grid',
|
||||||
v-for="op in strategyOptionWhenCurrentJobNotMatch"
|
gridTemplateColumns: '1.25fr 0.75fr',
|
||||||
:key="op.value"
|
gap: '10px 0',
|
||||||
:label="op.name"
|
width: '100%',
|
||||||
:value="op.value"
|
alignItems: 'end'
|
||||||
>{{ op.name }}</el-option
|
}"
|
||||||
|
>
|
||||||
|
<el-form-item mb0>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.jobNotMatchStrategy"
|
||||||
|
@change="(value) => gtagRenderer('job_not_match_strategy_changed', { value })"
|
||||||
>
|
>
|
||||||
</el-select>
|
<el-option
|
||||||
</el-form-item>
|
v-for="op in strategyOptionWhenCurrentJobNotMatch"
|
||||||
<div />
|
:key="op.value"
|
||||||
</div>
|
:label="op.name"
|
||||||
|
:value="op.value"
|
||||||
|
>{{ op.name }}</el-option
|
||||||
|
>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
<div class="h-1px bg-#f0f0f0" mt16px mb16px />
|
||||||
<div mt16px>
|
<div mt16px>
|
||||||
@@ -475,7 +771,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
import { computed, onBeforeUnmount, ref, watch, nextTick } from 'vue'
|
||||||
import { ElForm, ElMessage } from 'element-plus'
|
import { ElForm, ElMessage } from 'element-plus'
|
||||||
import { QuestionFilled } from '@element-plus/icons-vue'
|
import { QuestionFilled } from '@element-plus/icons-vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@@ -487,11 +783,13 @@ import defaultTargetCompanyListConf from '@geekgeekrun/geek-auto-start-chat-with
|
|||||||
import { ArrowDown } from '@element-plus/icons-vue'
|
import { ArrowDown } from '@element-plus/icons-vue'
|
||||||
import {
|
import {
|
||||||
MarkAsNotSuitOp,
|
MarkAsNotSuitOp,
|
||||||
StrategyScopeOptionWhenMarkJobNotMatch
|
StrategyScopeOptionWhenMarkJobNotMatch,
|
||||||
|
SalaryCalculateWay
|
||||||
} from '@geekgeekrun/sqlite-plugin/src/enums'
|
} from '@geekgeekrun/sqlite-plugin/src/enums'
|
||||||
import { debounce } from 'lodash-es'
|
import { debounce } from 'lodash-es'
|
||||||
import mittBus from '../../../utils/mitt'
|
import mittBus from '../../../utils/mitt'
|
||||||
import CityChooser from './components/CityChooser.vue'
|
import CityChooser from './components/CityChooser.vue'
|
||||||
|
import conditions from '@geekgeekrun/geek-auto-start-chat-with-boss/internal-config/job-filter-conditions-20241002.json'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@@ -505,9 +803,22 @@ const formContent = ref({
|
|||||||
jobNotMatchStrategy: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
jobNotMatchStrategy: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
||||||
jobNotActiveStrategy: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
jobNotActiveStrategy: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
|
||||||
markAsNotActiveSelectedTimeRange: 7,
|
markAsNotActiveSelectedTimeRange: 7,
|
||||||
|
// city
|
||||||
expectCityList: [],
|
expectCityList: [],
|
||||||
expectCityNotMatchStrategy: MarkAsNotSuitOp.NO_OP,
|
expectCityNotMatchStrategy: MarkAsNotSuitOp.NO_OP,
|
||||||
strategyScopeOptionWhenMarkJobCityNotMatch:
|
strategyScopeOptionWhenMarkJobCityNotMatch:
|
||||||
|
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB,
|
||||||
|
// salary
|
||||||
|
expectSalaryCalculateWay: SalaryCalculateWay.MONTH_SALARY,
|
||||||
|
expectSalaryNotMatchStrategy: MarkAsNotSuitOp.NO_OP,
|
||||||
|
strategyScopeOptionWhenMarkSalaryNotMatch:
|
||||||
|
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB,
|
||||||
|
expectSalaryLow: null,
|
||||||
|
expectSalaryHigh: null,
|
||||||
|
// work exp
|
||||||
|
expectWorkExpList: [],
|
||||||
|
expectWorkExpNotMatchStrategy: MarkAsNotSuitOp.NO_OP,
|
||||||
|
strategyScopeOptionWhenMarkJobWorkExpNotMatch:
|
||||||
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -571,6 +882,7 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => {
|
|||||||
? res.config['boss.json'].jobNotActiveStrategy
|
? res.config['boss.json'].jobNotActiveStrategy
|
||||||
: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
||||||
|
|
||||||
|
// city
|
||||||
formContent.value.expectCityList = res.config['boss.json']?.expectCityList ?? []
|
formContent.value.expectCityList = res.config['boss.json']?.expectCityList ?? []
|
||||||
formContent.value.expectCityNotMatchStrategy = strategyOptionWhenCurrentJobNotMatch
|
formContent.value.expectCityNotMatchStrategy = strategyOptionWhenCurrentJobNotMatch
|
||||||
.map((it) => it.value)
|
.map((it) => it.value)
|
||||||
@@ -580,6 +892,33 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => {
|
|||||||
formContent.value.strategyScopeOptionWhenMarkJobCityNotMatch =
|
formContent.value.strategyScopeOptionWhenMarkJobCityNotMatch =
|
||||||
res.config['boss.json']?.strategyScopeOptionWhenMarkJobCityNotMatch ??
|
res.config['boss.json']?.strategyScopeOptionWhenMarkJobCityNotMatch ??
|
||||||
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||||
|
|
||||||
|
// salary
|
||||||
|
formContent.value.expectSalaryCalculateWay =
|
||||||
|
res.config['boss.json'].expectSalaryCalculateWay ?? SalaryCalculateWay.MONTH_SALARY
|
||||||
|
formContent.value.expectSalaryNotMatchStrategy =
|
||||||
|
res.config['boss.json'].expectSalaryNotMatchStrategy ?? MarkAsNotSuitOp.NO_OP
|
||||||
|
formContent.value.strategyScopeOptionWhenMarkSalaryNotMatch =
|
||||||
|
res.config['boss.json'].strategyScopeOptionWhenMarkSalaryNotMatch ??
|
||||||
|
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||||
|
formContent.value.expectSalaryLow = parseFloat(res.config['boss.json'].expectSalaryLow) || null
|
||||||
|
formContent.value.expectSalaryHigh = parseFloat(res.config['boss.json'].expectSalaryHigh) || null
|
||||||
|
ensureSalaryRangeCorrect()
|
||||||
|
|
||||||
|
// work exp
|
||||||
|
formContent.value.expectWorkExpList =
|
||||||
|
Array.isArray(res.config['boss.json'].expectWorkExpList) &&
|
||||||
|
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 =
|
||||||
|
res.config['boss.json'].strategyScopeOptionWhenMarkJobWorkExpNotMatch ??
|
||||||
|
StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRules = {
|
const formRules = {
|
||||||
@@ -809,11 +1148,104 @@ const strategyScopeOptionWhenMarkJobNotMatch = [
|
|||||||
value: StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
value: StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '仅和“期望公司白名单”匹配的职位',
|
name: '仅和“公司白名单”匹配的职位',
|
||||||
value: StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
value: StrategyScopeOptionWhenMarkJobNotMatch.ONLY_COMPANY_MATCHED_JOB
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
async function handleExpectSalaryCalculateWayChanged(value) {
|
||||||
|
gtagRenderer('expect_salary_calculate_way_changed', { value })
|
||||||
|
|
||||||
|
await nextTick()
|
||||||
|
// convert annual package to month salary as 12-month
|
||||||
|
if (value === SalaryCalculateWay.MONTH_SALARY) {
|
||||||
|
if (formContent.value.expectSalaryHigh) {
|
||||||
|
formContent.value.expectSalaryHigh = Number(
|
||||||
|
((formContent.value.expectSalaryHigh * 10) / 12).toFixed(2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (formContent.value.expectSalaryLow) {
|
||||||
|
formContent.value.expectSalaryLow = Number(
|
||||||
|
((formContent.value.expectSalaryLow * 10) / 12).toFixed(2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// convert month salary to annual package as 12-month
|
||||||
|
else if (value === SalaryCalculateWay.ANNUAL_PACKAGE) {
|
||||||
|
if (formContent.value.expectSalaryHigh) {
|
||||||
|
formContent.value.expectSalaryHigh = Number(
|
||||||
|
((formContent.value.expectSalaryHigh / 10) * 12).toFixed(2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (formContent.value.expectSalaryLow) {
|
||||||
|
formContent.value.expectSalaryLow = Number(
|
||||||
|
((formContent.value.expectSalaryLow / 10) * 12).toFixed(2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectSalaryCalculateWayOption = [
|
||||||
|
{
|
||||||
|
name: '月薪(单位为 千元 - 即“k”)',
|
||||||
|
value: SalaryCalculateWay.MONTH_SALARY
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '“年包”(单位为 万元 - 即“W”)',
|
||||||
|
value: SalaryCalculateWay.ANNUAL_PACKAGE
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const salaryMarkAsNotSuitLabelText = computed(() => {
|
||||||
|
const textSeg = []
|
||||||
|
if (formContent.value.expectSalaryLow) {
|
||||||
|
textSeg.push('低于期望薪资下限')
|
||||||
|
}
|
||||||
|
if (formContent.value.expectSalaryHigh) {
|
||||||
|
textSeg.push('高于期望薪资上限')
|
||||||
|
}
|
||||||
|
return textSeg.join(' / ')
|
||||||
|
})
|
||||||
|
|
||||||
|
const isShowSalaryMarkAsNotSuitStrategy = computed(() => {
|
||||||
|
let flag = formContent.value.expectSalaryHigh || formContent.value.expectSalaryLow
|
||||||
|
|
||||||
|
if (
|
||||||
|
formContent.value.expectSalaryHigh &&
|
||||||
|
formContent.value.expectSalaryLow &&
|
||||||
|
formContent.value.expectSalaryHigh < formContent.value.expectSalaryLow
|
||||||
|
) {
|
||||||
|
flag = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag
|
||||||
|
})
|
||||||
|
|
||||||
|
function ensureSalaryRangeCorrect() {
|
||||||
|
if (
|
||||||
|
!formContent.value.expectSalaryHigh ||
|
||||||
|
isNaN(parseFloat(formContent.value.expectSalaryHigh))
|
||||||
|
) {
|
||||||
|
formContent.value.expectSalaryHigh = null
|
||||||
|
} else {
|
||||||
|
formContent.value.expectSalaryHigh = parseFloat(formContent.value.expectSalaryHigh.toFixed(2))
|
||||||
|
}
|
||||||
|
if (!formContent.value.expectSalaryLow || isNaN(parseFloat(formContent.value.expectSalaryLow))) {
|
||||||
|
formContent.value.expectSalaryLow = null
|
||||||
|
} else {
|
||||||
|
formContent.value.expectSalaryLow = parseFloat(formContent.value.expectSalaryLow.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
formContent.value.expectSalaryLow &&
|
||||||
|
formContent.value.expectSalaryHigh &&
|
||||||
|
formContent.value.expectSalaryLow > formContent.value.expectSalaryHigh
|
||||||
|
) {
|
||||||
|
formContent.value.expectSalaryHigh = formContent.value.expectSalaryLow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const noActiveDefinitionMarks = computed(() => {
|
const noActiveDefinitionMarks = computed(() => {
|
||||||
let arr = [...activeDescList]
|
let arr = [...activeDescList]
|
||||||
arr.shift()
|
arr.shift()
|
||||||
|
|||||||
@@ -42,6 +42,14 @@
|
|||||||
<strong>{{ markReasonTopicMap[row.markReason] }}</strong>
|
<strong>{{ markReasonTopicMap[row.markReason] }}</strong>
|
||||||
<pre class="m-0 of-auto">{{ formatMarkReason(row) }}</pre>
|
<pre class="m-0 of-auto">{{ formatMarkReason(row) }}</pre>
|
||||||
</template>
|
</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>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
<ElTableColumn prop="experienceName" label="工作经验" />
|
<ElTableColumn prop="experienceName" label="工作经验" />
|
||||||
@@ -209,7 +217,9 @@ const markReasonTopicMap = {
|
|||||||
[MarkAsNotSuitReason.BOSS_INACTIVE]: 'Boss不活跃',
|
[MarkAsNotSuitReason.BOSS_INACTIVE]: 'Boss不活跃',
|
||||||
[MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON]: '手动标记不合适',
|
[MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON]: '手动标记不合适',
|
||||||
[MarkAsNotSuitReason.JOB_NOT_SUIT]: '职位不合适',
|
[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) {
|
function formatMarkReason(row: VMarkAsNotSuitLog) {
|
||||||
@@ -241,6 +251,7 @@ function formatMarkReason(row: VMarkAsNotSuitLog) {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join('\n')
|
.join('\n')
|
||||||
}
|
}
|
||||||
|
case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT:
|
||||||
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
|
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
|
||||||
const extInfo = (() => {
|
const extInfo = (() => {
|
||||||
try {
|
try {
|
||||||
@@ -253,6 +264,21 @@ function formatMarkReason(row: VMarkAsNotSuitLog) {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join('\n')
|
.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: {
|
default: {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+10
-5
@@ -209,8 +209,8 @@ importers:
|
|||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.0.0(vite@5.1.1)
|
version: 2.0.0(vite@5.1.1)
|
||||||
element-plus:
|
element-plus:
|
||||||
specifier: ^2.5.5
|
specifier: ^2.8.4
|
||||||
version: 2.5.5(vue@3.4.15)
|
version: 2.8.4(vue@3.4.15)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8.56.0
|
specifier: ^8.56.0
|
||||||
version: 8.56.0
|
version: 8.56.0
|
||||||
@@ -3085,6 +3085,11 @@ packages:
|
|||||||
|
|
||||||
/dayjs@1.11.10:
|
/dayjs@1.11.10:
|
||||||
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/dayjs@1.11.13:
|
||||||
|
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/de-indent@1.0.2:
|
/de-indent@1.0.2:
|
||||||
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
||||||
@@ -3360,8 +3365,8 @@ packages:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
/element-plus@2.5.5(vue@3.4.15):
|
/element-plus@2.8.4(vue@3.4.15):
|
||||||
resolution: {integrity: sha512-yGU/MruLOWI0ImQPFCyFM4cXtHtILJNAi0hhLImcxjRukjgQLYNkvcvbwqNgBUt808KSeKF9MyxENFyBQLTg+Q==}
|
resolution: {integrity: sha512-ZlVAdUOoJliv4kW3ntWnnSHMT+u/Os7mXJjk2xzOlqNeHaI2/ozlF+R58ZCEak8ZnDi6+5A2viWEYRsq64IuiA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.2.0
|
vue: ^3.2.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3373,7 +3378,7 @@ packages:
|
|||||||
'@types/lodash-es': 4.17.12
|
'@types/lodash-es': 4.17.12
|
||||||
'@vueuse/core': 9.13.0(vue@3.4.15)
|
'@vueuse/core': 9.13.0(vue@3.4.15)
|
||||||
async-validator: 4.2.5
|
async-validator: 4.2.5
|
||||||
dayjs: 1.11.10
|
dayjs: 1.11.13
|
||||||
escape-html: 1.0.3
|
escape-html: 1.0.3
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
lodash-es: 4.17.21
|
lodash-es: 4.17.21
|
||||||
|
|||||||
Reference in New Issue
Block a user