mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-07 00:17:17 +08:00
add basic ui for expectCityList config
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
"jobNotMatchStrategy": 1,
|
"jobNotMatchStrategy": 1,
|
||||||
"jobNotActiveStrategy": 1,
|
"jobNotActiveStrategy": 1,
|
||||||
"markAsNotActiveSelectedTimeRange": 7,
|
"markAsNotActiveSelectedTimeRange": 7,
|
||||||
|
"expectCityList": [],
|
||||||
|
"expectCityNotMatchStrategy": 1,
|
||||||
"autoReminder": {
|
"autoReminder": {
|
||||||
"throttleIntervalMinutes": 10,
|
"throttleIntervalMinutes": 10,
|
||||||
"rechatLimitDay": 21,
|
"rechatLimitDay": 21,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -107,6 +107,12 @@ export default function initIpc() {
|
|||||||
if (hasOwn(payload, 'autoReminder')) {
|
if (hasOwn(payload, 'autoReminder')) {
|
||||||
bossConfig.autoReminder = payload.autoReminder
|
bossConfig.autoReminder = payload.autoReminder
|
||||||
}
|
}
|
||||||
|
if (hasOwn(payload, 'expectCityList')) {
|
||||||
|
bossConfig.expectCityList = payload.expectCityList
|
||||||
|
}
|
||||||
|
if (hasOwn(payload, 'expectCityNotMatchStrategy')) {
|
||||||
|
bossConfig.expectCityNotMatchStrategy = payload.expectCityNotMatchStrategy
|
||||||
|
}
|
||||||
promiseArr.push(writeConfigFile('boss.json', bossConfig))
|
promiseArr.push(writeConfigFile('boss.json', bossConfig))
|
||||||
|
|
||||||
if (hasOwn(payload, 'expectCompanies')) {
|
if (hasOwn(payload, 'expectCompanies')) {
|
||||||
|
|||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="modelValue?.length">
|
||||||
|
<div>当前已选择城市:</div>
|
||||||
|
<div flex flex-wrap gap-10px>
|
||||||
|
<el-tag v-for="it in modelValue" :key="it">
|
||||||
|
{{ it }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div>当前未选择任何期望城市,将不会按照城市进行筛选</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button size="small" type="primary" @click="isDialogVisible = true">选择城市</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="modelValue?.length"
|
||||||
|
size="small"
|
||||||
|
type="danger"
|
||||||
|
text
|
||||||
|
@click="handleClearSelectedCitiesInModelValue"
|
||||||
|
>清空已选择的所有城市</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<el-dialog
|
||||||
|
v-model="isDialogVisible"
|
||||||
|
width="1000px"
|
||||||
|
title="请选择城市"
|
||||||
|
:show-close="false"
|
||||||
|
@open="handleDialogOpen"
|
||||||
|
@closed="handleDialogClosed"
|
||||||
|
>
|
||||||
|
<el-tabs v-model="activeTabName">
|
||||||
|
<el-tab-pane
|
||||||
|
:style="{ height: '300px', overflow: 'auto' }"
|
||||||
|
label="热门城市"
|
||||||
|
name="热门城市"
|
||||||
|
>
|
||||||
|
<el-checkbox-group v-model="selectedCities">
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr 1fr 1fr 1fr'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
v-for="op in hotCityList.filter((it) => it.code !== 100010000)"
|
||||||
|
:key="op.code"
|
||||||
|
:label="op.name"
|
||||||
|
>
|
||||||
|
{{ op.name }}
|
||||||
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane
|
||||||
|
v-for="it in cityGroupsByAlphabetMap.keys()"
|
||||||
|
:key="it"
|
||||||
|
:style="{ height: '300px', overflow: 'auto' }"
|
||||||
|
:label="it"
|
||||||
|
:value="it"
|
||||||
|
>
|
||||||
|
<div v-for="group in cityGroupsByAlphabetMap.get(it)" :key="group.firstChar">
|
||||||
|
{{ group.firstChar }}
|
||||||
|
<el-checkbox-group v-model="selectedCities">
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr 1fr 1fr 1fr'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-checkbox v-for="op in group.cityList" :key="op.code" :label="op.name">
|
||||||
|
{{ op.name }}
|
||||||
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<template #footer>
|
||||||
|
<div
|
||||||
|
:style="{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
v-if="selectedCities.length"
|
||||||
|
type="danger"
|
||||||
|
text
|
||||||
|
@click="handleClearSelectedCitiesInDialog"
|
||||||
|
>清空已选择的所有城市</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button type="text" @click="handleCancelClicked">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleConfirmClicked">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { PropType, ref } from 'vue'
|
||||||
|
import cityGroupData from '../../../../../../common/constant/cityGroup.json'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Array as PropType<string[]>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emits = defineEmits(['update:modelValue'])
|
||||||
|
const { hotCityList, cityGroup } = cityGroupData.zpData
|
||||||
|
|
||||||
|
const activeTabName = ref('热门城市')
|
||||||
|
const isDialogVisible = ref(false)
|
||||||
|
const selectedCities = ref([])
|
||||||
|
|
||||||
|
const cityGroupsByAlphabetMap = ref(
|
||||||
|
new Map(['ABCDE', 'FGHJ', 'KLMN', 'PQRST', 'WXYZ'].map((it) => [it, []]))
|
||||||
|
)
|
||||||
|
for (const group of cityGroup) {
|
||||||
|
const { firstChar } = group
|
||||||
|
const targetKey =
|
||||||
|
[...cityGroupsByAlphabetMap.value.keys()].find((it) => it.includes(firstChar)) ?? null
|
||||||
|
if (!targetKey) {
|
||||||
|
if (!cityGroupsByAlphabetMap.value.get(targetKey)) {
|
||||||
|
cityGroupsByAlphabetMap.value.set(targetKey, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cityGroupsByAlphabetMap.value.get(targetKey)?.push(group)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDialogOpen() {
|
||||||
|
activeTabName.value = '热门城市'
|
||||||
|
selectedCities.value = [...(props.modelValue ?? [])]
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCancelClicked() {
|
||||||
|
isDialogVisible.value = false
|
||||||
|
}
|
||||||
|
function handleConfirmClicked() {
|
||||||
|
isDialogVisible.value = false
|
||||||
|
emits('update:modelValue', [...(selectedCities.value ?? [])])
|
||||||
|
}
|
||||||
|
function handleDialogClosed() {
|
||||||
|
selectedCities.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClearSelectedCitiesInModelValue() {
|
||||||
|
emits('update:modelValue', [])
|
||||||
|
}
|
||||||
|
function handleClearSelectedCitiesInDialog() {
|
||||||
|
selectedCities.value = []
|
||||||
|
}
|
||||||
|
</script>
|
||||||
+77
-11
@@ -14,10 +14,7 @@
|
|||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<div>
|
<div>
|
||||||
<el-form-item mb0>
|
<el-form-item mb0>
|
||||||
<div>
|
<div>是否查看职位详情的条件</div>
|
||||||
是否查看职位详情的条件
|
|
||||||
<span font-size-12px>(以下条件为空表示不筛选)</span>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="expectCompanies" mb10px>
|
<el-form-item prop="expectCompanies" mb10px>
|
||||||
<div
|
<div
|
||||||
@@ -31,13 +28,13 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<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')"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<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>期望公司信息位置图示</el-button
|
><span><QuestionFilled w-1em h-1em mr2px /></span>期望公司信息位置图示</el-button
|
||||||
@@ -68,6 +65,67 @@
|
|||||||
@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
|
||||||
|
:style="{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr 1fr'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<el-form-item prop="expectCityList" mb10px>
|
||||||
|
<div
|
||||||
|
font-size-12px
|
||||||
|
:style="{
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>期望工作地</div>
|
||||||
|
<city-chooser v-model="formContent.expectCityList" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="formContent.expectCityList?.length" prop="expectCityList" mb10px>
|
||||||
|
<div
|
||||||
|
font-size-12px
|
||||||
|
:style="{
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>当找到的工作和期望工作地不匹配时,将要执行的操作</div>
|
||||||
|
<el-form-item mb0>
|
||||||
|
<el-select
|
||||||
|
v-model="formContent.expectCityNotMatchStrategy"
|
||||||
|
@change="
|
||||||
|
(value) => gtagRenderer('expect_city_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>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div mb42px>
|
<div mb42px>
|
||||||
<el-form-item mb0>
|
<el-form-item mb0>
|
||||||
@@ -88,7 +146,7 @@
|
|||||||
@show="gtagRenderer('tooltip_show_about_expect_job_info_figure')"
|
@show="gtagRenderer('tooltip_show_about_expect_job_info_figure')"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<img block h-270px src="./resources/intro-of-job-info.png" />
|
<img block h-270px src="../resources/intro-of-job-info.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>如下各信息位置图示</el-button
|
><span><QuestionFilled w-1em h-1em mr2px /></span>如下各信息位置图示</el-button
|
||||||
@@ -125,6 +183,7 @@
|
|||||||
<div font-size-12px>职位名称正则(不区分大小写)</div>
|
<div font-size-12px>职位名称正则(不区分大小写)</div>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formContent.expectJobNameRegExpStr"
|
v-model="formContent.expectJobNameRegExpStr"
|
||||||
|
placeholder="true"
|
||||||
@blur="
|
@blur="
|
||||||
formContent.expectJobNameRegExpStr =
|
formContent.expectJobNameRegExpStr =
|
||||||
formContent.expectJobNameRegExpStr?.trim() ?? ''
|
formContent.expectJobNameRegExpStr?.trim() ?? ''
|
||||||
@@ -136,6 +195,7 @@
|
|||||||
<div font-size-12px>职位类型正则(推荐填写,不区分大小写)</div>
|
<div font-size-12px>职位类型正则(推荐填写,不区分大小写)</div>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formContent.expectJobTypeRegExpStr"
|
v-model="formContent.expectJobTypeRegExpStr"
|
||||||
|
placeholder="true"
|
||||||
@blur="
|
@blur="
|
||||||
formContent.expectJobTypeRegExpStr =
|
formContent.expectJobTypeRegExpStr =
|
||||||
formContent.expectJobTypeRegExpStr?.trim() ?? ''
|
formContent.expectJobTypeRegExpStr?.trim() ?? ''
|
||||||
@@ -147,6 +207,7 @@
|
|||||||
<div font-size-12px>职位描述正则(不区分大小写)</div>
|
<div font-size-12px>职位描述正则(不区分大小写)</div>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formContent.expectJobDescRegExpStr"
|
v-model="formContent.expectJobDescRegExpStr"
|
||||||
|
placeholder="true"
|
||||||
@blur="
|
@blur="
|
||||||
formContent.expectJobDescRegExpStr =
|
formContent.expectJobDescRegExpStr =
|
||||||
formContent.expectJobDescRegExpStr?.trim() ?? ''
|
formContent.expectJobDescRegExpStr?.trim() ?? ''
|
||||||
@@ -323,7 +384,8 @@ import defaultTargetCompanyListConf from '@geekgeekrun/geek-auto-start-chat-with
|
|||||||
import { ArrowDown } from '@element-plus/icons-vue'
|
import { ArrowDown } from '@element-plus/icons-vue'
|
||||||
import { MarkAsNotSuitOp } from '@geekgeekrun/sqlite-plugin/src/enums'
|
import { MarkAsNotSuitOp } 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'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@@ -336,7 +398,9 @@ const formContent = ref({
|
|||||||
expectJobDescRegExpStr: '',
|
expectJobDescRegExpStr: '',
|
||||||
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,
|
||||||
|
expectCityList: [],
|
||||||
|
expectCityNotMatchStrategy: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentAnyCombineRecommendJobFilterCombinationCount = computed(() => {
|
const currentAnyCombineRecommendJobFilterCombinationCount = computed(() => {
|
||||||
@@ -398,6 +462,8 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => {
|
|||||||
.includes(res.config['boss.json'].jobNotActiveStrategy)
|
.includes(res.config['boss.json'].jobNotActiveStrategy)
|
||||||
? res.config['boss.json'].jobNotActiveStrategy
|
? res.config['boss.json'].jobNotActiveStrategy
|
||||||
: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
||||||
|
|
||||||
|
formContent.value.expectCityList = res.config['boss.json']?.expectCityList ?? []
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRules = {
|
const formRules = {
|
||||||
@@ -612,11 +678,11 @@ const strategyOptionWhenCurrentJobNotMatch = [
|
|||||||
value: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
value: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '本地记录,且1周内再次遇到这个职位时将直接跳过',
|
name: '7天内再次遇到这个职位时直接跳过',
|
||||||
value: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL
|
value: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '本地不记录,但本次运行再次遇到这个职位时将直接跳过',
|
name: '本次运行再次遇到这个职位时直接跳过',
|
||||||
value: MarkAsNotSuitOp.NO_OP
|
value: MarkAsNotSuitOp.NO_OP
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -45,7 +45,7 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'GeekAutoStartChatWithBoss',
|
path: 'GeekAutoStartChatWithBoss',
|
||||||
component: () => import('@renderer/page/MainLayout/GeekAutoStartChatWithBoss.vue'),
|
component: () => import('@renderer/page/MainLayout/GeekAutoStartChatWithBoss/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'BOSS炸弹'
|
title: 'BOSS炸弹'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user