From ba7c61f22b7ba63f3dbacfed531e7fa11f1f08cc Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Thu, 19 Feb 2026 19:16:33 +0800 Subject: [PATCH] add ui of commonJobConditionConfig --- .../flow/OPEN_SETTING_WINDOW/ipc/index.ts | 8 + .../window/commonJobConditionConfigWindow.ts | 46 ++ .../page/CommonJobConditionConfig/index.vue | 708 ++++++++++++++++++ .../GeekAutoStartChatWithBoss/common.ts | 282 +++++++ .../GeekAutoStartChatWithBoss/index.vue | 326 ++------ .../LeftNavBar/GlabalConfigPart.vue | 12 + packages/ui/src/renderer/src/router/index.ts | 7 + 7 files changed, 1123 insertions(+), 266 deletions(-) create mode 100644 packages/ui/src/main/window/commonJobConditionConfigWindow.ts create mode 100644 packages/ui/src/renderer/src/page/CommonJobConditionConfig/index.vue create mode 100644 packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/common.ts diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts index bcafd3b..5427a7a 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts @@ -58,6 +58,7 @@ import { waitForUserApproveAgreement } from '../../../features/first-launch-notice-window' import { getLastUsedAndAvailableBrowser } from '../../DOWNLOAD_DEPENDENCIES/utils/browser-history' +import { createCommonJobConditionConfigWindow } from '../../../window/commonJobConditionConfigWindow' export default function initIpc() { ipcMain.handle('fetch-config-file-content', async () => { @@ -607,6 +608,13 @@ export default function initIpc() { } } }) + ipcMain.handle('common-job-condition-config', async () => { + createCommonJobConditionConfigWindow({ + parent: mainWindow!, + modal: true, + show: true + }) + }) ipcMain.handle('exit-app-immediately', () => { app.exit(0) diff --git a/packages/ui/src/main/window/commonJobConditionConfigWindow.ts b/packages/ui/src/main/window/commonJobConditionConfigWindow.ts new file mode 100644 index 0000000..f825726 --- /dev/null +++ b/packages/ui/src/main/window/commonJobConditionConfigWindow.ts @@ -0,0 +1,46 @@ +import { BrowserWindow } from 'electron' +import path from 'path' + +export let commonJobConditionConfigWindow: BrowserWindow | null = null +export function createCommonJobConditionConfigWindow( + opt?: Electron.BrowserWindowConstructorOptions +): BrowserWindow { + // Create the browser window. + if (commonJobConditionConfigWindow) { + commonJobConditionConfigWindow!.show() + } + commonJobConditionConfigWindow = new BrowserWindow({ + width: 1024, + height: 768, + resizable: false, + show: false, + autoHideMenuBar: true, + webPreferences: { + preload: path.join(__dirname, '../preload/index.js'), + sandbox: false + }, + ...opt + }) + + commonJobConditionConfigWindow.on('ready-to-show', () => { + commonJobConditionConfigWindow!.show() + }) + + // HMR for renderer base on electron-vite cli. + // Load the remote URL for development or the local html file for production. + if (process.env.NODE_ENV === 'development' && process.env['ELECTRON_RENDERER_URL']) { + commonJobConditionConfigWindow.loadURL( + process.env['ELECTRON_RENDERER_URL'] + '#/commonJobConditionConfig' + ) + } else { + commonJobConditionConfigWindow.loadURL( + 'file://' + path.join(__dirname, '../renderer/index.html') + '#/commonJobConditionConfig' + ) + } + + commonJobConditionConfigWindow!.once('closed', () => { + commonJobConditionConfigWindow = null + }) + + return commonJobConditionConfigWindow! +} diff --git a/packages/ui/src/renderer/src/page/CommonJobConditionConfig/index.vue b/packages/ui/src/renderer/src/page/CommonJobConditionConfig/index.vue new file mode 100644 index 0000000..669dc4e --- /dev/null +++ b/packages/ui/src/renderer/src/page/CommonJobConditionConfig/index.vue @@ -0,0 +1,708 @@ + + + + + diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/common.ts b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/common.ts new file mode 100644 index 0000000..b0fc20d --- /dev/null +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/common.ts @@ -0,0 +1,282 @@ +import { SalaryCalculateWay, JobDetailRegExpMatchLogic } from '@geekgeekrun/sqlite-plugin/src/enums' +import sampleCompanyList from '@geekgeekrun/geek-auto-start-chat-with-boss/default-config-file/sample-company-list.json' +import { nextTick } from 'vue' + +export function isJobDetailRegExpEmpty({ formContent }) { + return [ + formContent.expectJobDescRegExpStr, + formContent.expectJobNameRegExpStr, + formContent.expectJobTypeRegExpStr + ] + .map((it) => Boolean(it?.trim())) + .every((it) => it === false) +} + +export function getJobDetailRegExpMatchLogicConfig({ formContent }) { + const result = { + logicText: '-', + inputPlaceholderText: '-' + } + if (formContent.jobDetailRegExpMatchLogic === JobDetailRegExpMatchLogic.EVERY) { + Object.assign(result, { + logicText: '且', + inputPlaceholderText: 'true' + }) + } + if (formContent.jobDetailRegExpMatchLogic === JobDetailRegExpMatchLogic.SOME) { + Object.assign(result, { + logicText: '或', + inputPlaceholderText: 'false' + }) + } + + if (isJobDetailRegExpEmpty({ formContent })) { + result.inputPlaceholderText = 'true' + } + return result +} + +export const expectSalaryCalculateWayOption = [ + { + name: '月薪(单位为 千元 - 即“k”)', + value: SalaryCalculateWay.MONTH_SALARY + }, + { + name: '“年包”(单位为 万元 - 即“W”)', + value: SalaryCalculateWay.ANNUAL_PACKAGE + } +] + +export function ensureSalaryRangeCorrect({ formContent }) { + if (!formContent.expectSalaryHigh || isNaN(parseFloat(formContent.expectSalaryHigh))) { + formContent.expectSalaryHigh = null + } else { + formContent.expectSalaryHigh = parseFloat(formContent.expectSalaryHigh.toFixed(2)) + } + if (!formContent.expectSalaryLow || isNaN(parseFloat(formContent.expectSalaryLow))) { + formContent.expectSalaryLow = null + } else { + formContent.expectSalaryLow = parseFloat(formContent.expectSalaryLow.toFixed(2)) + } + + if ( + formContent.expectSalaryLow && + formContent.expectSalaryHigh && + formContent.expectSalaryLow > formContent.expectSalaryHigh + ) { + formContent.expectSalaryHigh = formContent.expectSalaryLow + } +} + +export function getRuleOfExpectJobNameRegExpStr({ gtagRenderer, jobDetailRegExpSectionEl }) { + return (_, value, cb) => { + if (!value) { + cb() + gtagRenderer('empty_reg_exp_for_expect_job_name') + return + } + try { + new RegExp(value, 'ig') + gtagRenderer('valid_reg_exp_for_expect_job_name', { v: value }) + cb() + } catch (err) { + cb(new Error(`正则无效:${err?.message}`)) + jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded() + gtagRenderer('invalid_reg_exp_for_expect_job_name', { v: value }) + } + } +} + +export function getRuleOfExpectJobTypeRegExpStr({ gtagRenderer, jobDetailRegExpSectionEl }) { + return (_, value, cb) => { + if (!value) { + cb() + gtagRenderer('empty_reg_exp_for_expect_job_type') + return + } + try { + new RegExp(value, 'ig') + gtagRenderer('valid_reg_exp_for_expect_job_type', { v: value }) + cb() + } catch (err) { + cb(new Error(`正则无效:${err?.message}`)) + jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded() + gtagRenderer('invalid_reg_exp_for_expect_job_type', { v: value }) + } + } +} + +export function getRuleOfExpectJobDescRegExpStr({ gtagRenderer, jobDetailRegExpSectionEl }) { + return (_, value, cb) => { + if (!value) { + cb() + gtagRenderer('empty_reg_exp_for_expect_job_desc') + return + } + try { + new RegExp(value, 'ig') + gtagRenderer('valid_reg_exp_for_expect_job_desc', { v: value }) + cb() + } catch (err) { + cb(new Error(`正则无效:${err?.message}`)) + jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded() + gtagRenderer('invalid_reg_exp_for_expect_job_desc', { v: value }) + } + } +} + +export function getRuleOfBlockCompanyNameRegExpStr({ + gtagRenderer, + blockCompanyNameRegExpSectionEl +}) { + return (_, value, cb) => { + if (!value) { + cb() + gtagRenderer('empty_reg_exp_for_bcn') + return + } + try { + new RegExp(value, 'ig') + gtagRenderer('valid_reg_exp_for_bcn', { v: value }) + cb() + } catch (err) { + cb(new Error(`正则无效:${err?.message}`)) + blockCompanyNameRegExpSectionEl.value?.scrollIntoViewIfNeeded() + gtagRenderer('invalid_reg_exp_for_bcn', { v: value }) + } + } +} + +export const expectCompanyTemplateList = [ + { + name: '不限公司(随便投)', + value: '' + }, + { + name: '示例公司', + value: sampleCompanyList.join(',') + }, + { + name: '大厂及关联企业', + value: `抖音,字节,字跳,有竹居,脸萌,头条,懂车帝,滴滴,嘀嘀,巨量引擎,小桔,网易,有道,腾讯,酷狗,酷我,阅文,搜狗,小鹅通,富途,京东,沃东天骏,达达,达冠,京邦达,百度,昆仑芯,小度,度小满,爱奇艺,携程,趣拿,去哪儿,集度,智图,长地万方,瑞图万方,道道通,小熊博望,理想,蔚来,顺丰,丰巢,中通,圆通,申通,跨越,讯飞,同程,艺龙,马蜂窝,贝壳,自如,链家,我爱我家,相寓,多点,金山,小米,猎豹,新浪,微博,阿里,淘宝,淘麦郎,天猫,盒马,口碑,优视,夸克,UC,蚂蚁,高德,LAZADA,来赞达,飞猪,菜鸟,哈啰,钉钉,乌鸫,饿了么,美团,三快,猫眼,快手,映客,小红书,行吟,奇虎,360,三六零,鸿盈,奇富,奇元,亚信,启明星辰,奇安信,深信服,长亭,绿盟,天融信,商汤,SenseTime,大华,海康威视,hikvision,汽车之家,车好多,瓜子,易车,昆仑万维,昆仑天工,闲徕,趣加,FunPlus,完美,马上消费,轻松,水滴,白龙马,58,更赢,车欢欢,五八,红布林,致美,快狗,天鹅到家,转转,美餐,知乎,智者四海,易点云,搜狐,用友,畅捷通,猿辅导,小猿,猿力,好未来,学而思,希望学,新东方,东方甄选,东方优选,作业帮,高途,跟谁学,学科网,天学网,一起教育,一起作业,美术宝,火花思维,粉笔,51talk,爱学习,高思,老虎国际,一心向上,向上一意,联想,拉勾,乐视,欢聚,竞技世界,拼多多,寻梦,从鲸,TEMU,得物,有赞,Moka,希瑞亚斯,北森,OPPO,欧珀,vivo,维沃,小天才,步步高,读书郎,货拉拉,陌陌,探探,Shopee,虾皮,首汽租车,GoFun,神州租车,天眼查,旷视,小冰,美图,智谱华章,MiniMax,石头科技,迅雷,TP,锐捷,Tenda,腾达,斐讯,希音,SHEIN,稀宇,深言,百川智能,与爱为舞,牵手,Grab,爱回收,洋钱罐,瓴岳,得到,思维造物,地平线,咪咕,翼支付,电信,天翼,联通,蓝湖,墨刀,海尔,美的,米哈游,传音,同花顺,国美,TCL` + }, + { + name: '阿里系', + value: `阿里,淘宝,淘麦郎,天猫,盒马,口碑,优视,夸克,UC,蚂蚁,飞猪,乌鸫,饿了么,LAZADA,来赞达,菜鸟,哈啰,钉钉,高德,白龙马,新浪,微博` + }, + { + name: '字节(头条/抖音)系', + value: `抖音,字节,字跳,有竹居,脸萌,头条,懂车帝,巨量引擎` + }, + { + name: '百度系', + value: `百度,昆仑芯,小度,度小满,爱奇艺,携程,趣拿,去哪儿,集度,作业帮,智图,长地万方,瑞图万方,道道通,小熊博望` + }, + { + name: '腾讯系', + value: `腾讯,酷狗,酷我,阅文,搜狗,小鹅通,富途,京东,沃东天骏,达达,达冠,京邦达,美团,三快,猫眼,快手,拼多多,寻梦,从鲸,TEMU,Shopee,虾皮,滴滴,嘀嘀,小桔,转转` + }, + { + name: '外包、劳务派遣企业', + value: `青钱,软通动力,南天,睿服,中电金信,佰钧成,云链,博彦,汉克时代,柯莱特,拓保,亿达信息,纬创,微创,微澜,诚迈科技,法本,兆尹,诚迈,联合永道,新致软件,宇信科技,华为,德科,FESCO,科锐,科之锐` + } +] + +export const blockCompanyNameRegExpTemplateList = [ + { + name: '不限公司(不按照公司名称来标注不合适)', + value: '' + }, + { + name: '外包、劳务派遣企业', + value: `青钱|软通动力|南天|睿服|中电金信|佰钧成|云链|博彦|汉克时代|柯莱特|拓保|亿达信息|纬创|微创|微澜|诚迈科技|法本|兆尹|诚迈|联合永道|新致软件|宇信科技|华为|德科|FESCO|科锐|科之锐` + }, + { + name: '京东及相关公司', + value: '京东|沃东天骏|达达|达冠|京邦达' + } +] + +export function getHandlerForExpectCompanyTemplateClicked({ gtagRenderer, formContent }) { + return function handleExpectCompanyTemplateClicked(item) { + gtagRenderer('expect_company_tpl_clicked', { + name: item.name + }) + formContent.value.expectCompanies = item.value + } +} + +export function getHandlerForExpectJobFilterTemplateClicked({ gtagRenderer, formContent }) { + return function handleExpectJobFilterTemplateClicked(item) { + gtagRenderer('expect_job_filter_tpl_clicked', { + name: item.name + }) + Object.assign(formContent.value, { + ...item.config + }) + } +} + +export function getHandlerForBlockCompanyNameRegExpTemplateClicked({ gtagRenderer, formContent }) { + return function handleBlockCompanyNameRegExpTemplateClicked(item) { + gtagRenderer('bcn_reg_exp_tpl_clicked', { + name: item.name + }) + formContent.value.blockCompanyNameRegExpStr = item.value + } +} + +export const jobDetailRegExpMatchLogicOptions = [ + { + name: '“且”模式 - 所有正则匹配时才认为职位匹配', + value: JobDetailRegExpMatchLogic.EVERY + }, + { + name: '“或”模式 - 任一正则匹配时即认为职位匹配', + value: JobDetailRegExpMatchLogic.SOME + } +] + +export function getHandlerForExpectSalaryCalculateWayChanged({ gtagRenderer, formContent }) { + return 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 + } + } +} + +export const normalizeCommaSplittedStr = (str) => { + return str + .split(/,|,/) + .map((it) => it.trim()) + .filter(Boolean) + .join(',') +} diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue index 74ee323..daca352 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss/index.vue @@ -292,7 +292,11 @@ max-h-8lh type="textarea" placeholder="置空表示“不限公司,任意公司都可以投递”" - @blur="normalizeExpectCompanies" + @blur=" + formContent.expectCompanies = normalizeCommaSplittedStr( + formContent.expectCompanies + ) + " />
@@ -570,7 +574,7 @@ @change=" () => { gtagRenderer('expect_salary_low_changed') - ensureSalaryRangeCorrect() + ensureSalaryRangeCorrect({ formContent }) } " > @@ -604,7 +608,7 @@ @change=" () => { gtagRenderer('expect_salary_high_changed') - ensureSalaryRangeCorrect() + ensureSalaryRangeCorrect({ formContent }) } " > @@ -1033,7 +1037,9 @@ - {{ getJobDetailRegExpMatchLogicConfig().logicText }} + {{ getJobDetailRegExpMatchLogicConfig({ formContent }).logicText }}
@@ -1061,7 +1067,9 @@ - {{ getJobDetailRegExpMatchLogicConfig().logicText }} + {{ getJobDetailRegExpMatchLogicConfig({ formContent }).logicText }}
职位描述正则(不区分大小写)
import { computed, onBeforeUnmount, ref, watch, nextTick, onUnmounted } from 'vue' import { ElForm, ElMessage } from 'element-plus' -import { QuestionFilled } from '@element-plus/icons-vue' +import { QuestionFilled, ArrowDown } from '@element-plus/icons-vue' import { useRouter } from 'vue-router' import AnyCombineBossRecommendFilter from '@renderer/features/AnyCombineBossRecommendFilter/index.vue' import StaticCombineBossRecommendFilter from '@renderer/features/StaticCombineBossRecommendFilter/index.vue' @@ -1258,8 +1268,6 @@ import { formatStaticCombineFilters } from '@geekgeekrun/geek-auto-start-chat-with-boss/combineCalculator.mjs' import { gtagRenderer as baseGtagRenderer } from '@renderer/utils/gtag' -import sampleCompanyList from '@geekgeekrun/geek-auto-start-chat-with-boss/default-config-file/sample-company-list.json' -import { ArrowDown } from '@element-plus/icons-vue' import { CombineRecommendJobFilterType, MarkAsNotSuitOp, @@ -1275,6 +1283,24 @@ import JobSourceDragOrderer from '../../../features/JobSourceDragOrderer/index.v import expectJobFilterTemplateList from './expectJobFilterTemplateList' import RunningOverlay from '@renderer/features/RunningOverlay/index.vue' import { RUNNING_STATUS_ENUM } from '../../../../../common/enums/auto-start-chat' +import { + getJobDetailRegExpMatchLogicConfig, + isJobDetailRegExpEmpty, + expectSalaryCalculateWayOption, + ensureSalaryRangeCorrect, + getRuleOfExpectJobNameRegExpStr, + getRuleOfExpectJobDescRegExpStr, + getRuleOfBlockCompanyNameRegExpStr, + expectCompanyTemplateList, + blockCompanyNameRegExpTemplateList, + getHandlerForExpectCompanyTemplateClicked, + getHandlerForExpectJobFilterTemplateClicked, + getHandlerForBlockCompanyNameRegExpTemplateClicked, + getRuleOfExpectJobTypeRegExpStr, + jobDetailRegExpMatchLogicOptions, + getHandlerForExpectSalaryCalculateWayChanged, + normalizeCommaSplittedStr +} from './common' const gtagRenderer = (name, params?: object) => { return baseGtagRenderer(name, { @@ -1451,7 +1477,7 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => { 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() + ensureSalaryRangeCorrect({ formContent }) // work exp formContent.value.expectWorkExpList = @@ -1497,60 +1523,15 @@ const blockCompanyNameRegExpSectionEl = ref() const formRules = { expectJobNameRegExpStr: { trigger: 'blur', - validator(_, value, cb) { - if (!value) { - cb() - gtagRenderer('empty_reg_exp_for_expect_job_name') - return - } - try { - new RegExp(value, 'ig') - gtagRenderer('valid_reg_exp_for_expect_job_name', { v: value }) - cb() - } catch (err) { - cb(new Error(`正则无效:${err?.message}`)) - jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded() - gtagRenderer('invalid_reg_exp_for_expect_job_name', { v: value }) - } - } + validator: getRuleOfExpectJobNameRegExpStr({ gtagRenderer, jobDetailRegExpSectionEl }) }, expectJobTypeRegExpStr: { trigger: 'blur', - validator(_, value, cb) { - if (!value) { - cb() - gtagRenderer('empty_reg_exp_for_expect_job_type') - return - } - try { - new RegExp(value, 'ig') - gtagRenderer('valid_reg_exp_for_expect_job_type', { v: value }) - cb() - } catch (err) { - cb(new Error(`正则无效:${err?.message}`)) - jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded() - gtagRenderer('invalid_reg_exp_for_expect_job_type', { v: value }) - } - } + validator: getRuleOfExpectJobTypeRegExpStr({ gtagRenderer, jobDetailRegExpSectionEl }) }, expectJobDescRegExpStr: { trigger: 'blur', - validator(_, value, cb) { - if (!value) { - cb() - gtagRenderer('empty_reg_exp_for_expect_job_desc') - return - } - try { - new RegExp(value, 'ig') - gtagRenderer('valid_reg_exp_for_expect_job_desc', { v: value }) - cb() - } catch (err) { - cb(new Error(`正则无效:${err?.message}`)) - jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded() - gtagRenderer('invalid_reg_exp_for_expect_job_desc', { v: value }) - } - } + validator: getRuleOfExpectJobDescRegExpStr({ gtagRenderer, jobDetailRegExpSectionEl }) }, __jobSourceList: { trigger: null, @@ -1611,22 +1592,7 @@ const formRules = { }, blockCompanyNameRegExpStr: { trigger: 'blur', - validator(_, value, cb) { - if (!value) { - cb() - gtagRenderer('empty_reg_exp_for_bcn') - return - } - try { - new RegExp(value, 'ig') - gtagRenderer('valid_reg_exp_for_bcn', { v: value }) - cb() - } catch (err) { - cb(new Error(`正则无效:${err?.message}`)) - blockCompanyNameRegExpSectionEl.value?.scrollIntoViewIfNeeded() - gtagRenderer('invalid_reg_exp_for_bcn', { v: value }) - } - } + validator: getRuleOfBlockCompanyNameRegExpStr({ gtagRenderer, blockCompanyNameRegExpSectionEl }) } } @@ -1707,7 +1673,7 @@ const handleSave = async () => { opTimes: formContent.value.sageTimeOpTimes }) }) - normalizeExpectCompanies() + formContent.value.expectCompanies = normalizeCommaSplittedStr(formContent.value.expectCompanies) try { await formRef.value!.validate() } catch (err) { @@ -1729,64 +1695,15 @@ const handleSave = async () => { gtagRenderer('config_saved') } -const normalizeExpectCompanies = () => { - formContent.value.expectCompanies = formContent.value.expectCompanies - .split(/,|,/) - .map((it) => it.trim()) - .filter(Boolean) - .join(',') -} +const handleExpectCompanyTemplateClicked = getHandlerForExpectCompanyTemplateClicked({ + gtagRenderer, + formContent +}) -const expectCompanyTemplateList = [ - { - name: '不限公司(随便投)', - value: '' - }, - { - name: '示例公司', - value: sampleCompanyList.join(',') - }, - { - name: '大厂及关联企业', - value: `抖音,字节,字跳,有竹居,脸萌,头条,懂车帝,滴滴,嘀嘀,巨量引擎,小桔,网易,有道,腾讯,酷狗,酷我,阅文,搜狗,小鹅通,富途,京东,沃东天骏,达达,达冠,京邦达,百度,昆仑芯,小度,度小满,爱奇艺,携程,趣拿,去哪儿,集度,智图,长地万方,瑞图万方,道道通,小熊博望,理想,蔚来,顺丰,丰巢,中通,圆通,申通,跨越,讯飞,同程,艺龙,马蜂窝,贝壳,自如,链家,我爱我家,相寓,多点,金山,小米,猎豹,新浪,微博,阿里,淘宝,淘麦郎,天猫,盒马,口碑,优视,夸克,UC,蚂蚁,高德,LAZADA,来赞达,飞猪,菜鸟,哈啰,钉钉,乌鸫,饿了么,美团,三快,猫眼,快手,映客,小红书,行吟,奇虎,360,三六零,鸿盈,奇富,奇元,亚信,启明星辰,奇安信,深信服,长亭,绿盟,天融信,商汤,SenseTime,大华,海康威视,hikvision,汽车之家,车好多,瓜子,易车,昆仑万维,昆仑天工,闲徕,趣加,FunPlus,完美,马上消费,轻松,水滴,白龙马,58,更赢,车欢欢,五八,红布林,致美,快狗,天鹅到家,转转,美餐,知乎,智者四海,易点云,搜狐,用友,畅捷通,猿辅导,小猿,猿力,好未来,学而思,希望学,新东方,东方甄选,东方优选,作业帮,高途,跟谁学,学科网,天学网,一起教育,一起作业,美术宝,火花思维,粉笔,51talk,爱学习,高思,老虎国际,一心向上,向上一意,联想,拉勾,乐视,欢聚,竞技世界,拼多多,寻梦,从鲸,TEMU,得物,有赞,Moka,希瑞亚斯,北森,OPPO,欧珀,vivo,维沃,小天才,步步高,读书郎,货拉拉,陌陌,探探,Shopee,虾皮,首汽租车,GoFun,神州租车,天眼查,旷视,小冰,美图,智谱华章,MiniMax,石头科技,迅雷,TP,锐捷,Tenda,腾达,斐讯,希音,SHEIN,稀宇,深言,百川智能,与爱为舞,牵手,Grab,爱回收,洋钱罐,瓴岳,得到,思维造物,地平线,咪咕,翼支付,电信,天翼,联通,蓝湖,墨刀,海尔,美的,米哈游,传音,同花顺,国美,TCL` - }, - { - name: '阿里系', - value: `阿里,淘宝,淘麦郎,天猫,盒马,口碑,优视,夸克,UC,蚂蚁,飞猪,乌鸫,饿了么,LAZADA,来赞达,菜鸟,哈啰,钉钉,高德,白龙马,新浪,微博` - }, - { - name: '字节(头条/抖音)系', - value: `抖音,字节,字跳,有竹居,脸萌,头条,懂车帝,巨量引擎` - }, - { - name: '百度系', - value: `百度,昆仑芯,小度,度小满,爱奇艺,携程,趣拿,去哪儿,集度,作业帮,智图,长地万方,瑞图万方,道道通,小熊博望` - }, - { - name: '腾讯系', - value: `腾讯,酷狗,酷我,阅文,搜狗,小鹅通,富途,京东,沃东天骏,达达,达冠,京邦达,美团,三快,猫眼,快手,拼多多,寻梦,从鲸,TEMU,Shopee,虾皮,滴滴,嘀嘀,小桔,转转` - }, - { - name: '外包、劳务派遣企业', - value: `青钱,软通动力,南天,睿服,中电金信,佰钧成,云链,博彦,汉克时代,柯莱特,拓保,亿达信息,纬创,微创,微澜,诚迈科技,法本,兆尹,诚迈,联合永道,新致软件,宇信科技,华为,德科,FESCO,科锐,科之锐` - } -] -function handleExpectCompanyTemplateClicked(item) { - gtagRenderer('expect_company_tpl_clicked', { - name: item.name - }) - formContent.value.expectCompanies = item.value -} - -function handleExpectJobFilterTemplateClicked(item) { - gtagRenderer('expect_job_filter_tpl_clicked', { - name: item.name - }) - - Object.assign(formContent.value, { - ...item.config - }) -} +const handleExpectJobFilterTemplateClicked = getHandlerForExpectJobFilterTemplateClicked({ + gtagRenderer, + formContent +}) const strategyOptionWhenCurrentJobNotMatch = [ { @@ -1814,61 +1731,11 @@ const strategyScopeOptionWhenMarkJobNotMatch = [ } ] -const jobDetailRegExpMatchLogicOptions = [ - { - name: '“且”模式 - 所有正则匹配时才认为职位匹配', - value: JobDetailRegExpMatchLogic.EVERY - }, - { - name: '“或”模式 - 任一正则匹配时即认为职位匹配', - value: JobDetailRegExpMatchLogic.SOME - } -] +const handleExpectSalaryCalculateWayChanged = getHandlerForExpectSalaryCalculateWayChanged({ + gtagRenderer, + formContent +}) -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) { @@ -1894,30 +1761,6 @@ const isShowSalaryMarkAsNotSuitStrategy = computed(() => { 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(() => { let arr = [...activeDescList] arr.shift() @@ -1948,40 +1791,6 @@ function handleHowToFillDetailFilterClick() { ) } -function isJobDetailRegExpEmpty() { - return [ - formContent.value.expectJobDescRegExpStr, - formContent.value.expectJobNameRegExpStr, - formContent.value.expectJobTypeRegExpStr - ] - .map((it) => Boolean(it?.trim())) - .every((it) => it === false) -} - -function getJobDetailRegExpMatchLogicConfig() { - const result = { - logicText: '-', - inputPlaceholderText: '-' - } - if (formContent.value.jobDetailRegExpMatchLogic === JobDetailRegExpMatchLogic.EVERY) { - Object.assign(result, { - logicText: '且', - inputPlaceholderText: 'true' - }) - } - if (formContent.value.jobDetailRegExpMatchLogic === JobDetailRegExpMatchLogic.SOME) { - Object.assign(result, { - logicText: '或', - inputPlaceholderText: 'false' - }) - } - - if (isJobDetailRegExpEmpty()) { - result.inputPlaceholderText = 'true' - } - return result -} - function formatJobSourceConfigToFormValue(config = []) { const typeToNameKey = { recommend: '推荐列表中的职位', @@ -2063,26 +1872,11 @@ const handleStopButtonClick = async () => { } } -const blockCompanyNameRegExpTemplateList = [ - { - name: '不限公司(不按照公司名称来标注不合适)', - value: '' - }, - { - name: '外包、劳务派遣企业', - value: `青钱|软通动力|南天|睿服|中电金信|佰钧成|云链|博彦|汉克时代|柯莱特|拓保|亿达信息|纬创|微创|微澜|诚迈科技|法本|兆尹|诚迈|联合永道|新致软件|宇信科技|华为|德科|FESCO|科锐|科之锐` - }, - { - name: '京东及相关公司', - value: '京东|沃东天骏|达达|达冠|京邦达' - } -] -const handleBlockCompanyNameRegExpTemplateClicked = (item) => { - gtagRenderer('bcn_reg_exp_tpl_clicked', { - name: item.name +const handleBlockCompanyNameRegExpTemplateClicked = + getHandlerForBlockCompanyNameRegExpTemplateClicked({ + gtagRenderer, + formContent }) - formContent.value.blockCompanyNameRegExpStr = item.value -} diff --git a/packages/ui/src/renderer/src/router/index.ts b/packages/ui/src/renderer/src/router/index.ts index 5561ec3..4579527 100644 --- a/packages/ui/src/renderer/src/router/index.ts +++ b/packages/ui/src/renderer/src/router/index.ts @@ -59,6 +59,13 @@ const routes: Array = [ title: '已读不回自动复聊 大语言模型测试' } }, + { + path: '/commonJobConditionConfig', + component: () => import('@renderer/page/CommonJobConditionConfig/index.vue'), + meta: { + title: '公共职位筛选条件' + } + }, { path: '/main-layout', component: () => import('@renderer/page/MainLayout/index.vue'),