enhance ux of job source

This commit is contained in:
geekgeekrun
2025-07-13 00:34:57 +08:00
parent 08028f37dd
commit 44b0e44e2e
3 changed files with 155 additions and 30 deletions
@@ -24,10 +24,9 @@
<div flex w-full flex-1>
<template
v-if="
element.item.type === 'search' &&
(!element.item?.children?.length ||
!element.item?.children?.some((it) => it.enabled) ||
!element.item?.children?.some((it) => !!it.keyword?.trim()))
element.type === 'search' &&
(!element?.children?.length ||
element?.children?.every((it) => !(it.enabled && !!it.keyword?.trim())))
"
>
<el-switch
@@ -37,12 +36,29 @@
active-text="启用"
inactive-text="禁用"
inline-prompt
@click="
() => {
if (!element?.children?.length) {
Message.info({
message: '请添加一个要搜索的关键词',
grouping: true
})
} else if (
element?.children?.every((it) => !(it.enabled && !!it.keyword?.trim()))
) {
Message.info({
message: '请启用一个要搜索的关键词',
grouping: true
})
}
}
"
/>
{{ element.label }}
</template>
<template v-else>
<el-switch
v-model="element.item.enabled"
v-model="element.enabled"
mr10px
active-text="启用"
inactive-text="禁用"
@@ -51,35 +67,47 @@
{{ element.label }}
</template>
</div>
<div v-if="element.item.type === 'search'">
<div v-if="element.type === 'search'">
<div flex flex-items-center>
<span color-orange align-self-end mr10px>
<template v-if="!element.item?.children?.length">
<template v-if="!element?.children?.length">
添加一个关键词后方可启用-&gt;
</template>
<template
v-else-if="
element.item?.children?.every((it) => !(it.enabled && !!it.keyword?.trim()))
element.enabled &&
element?.children?.every((it) => !(it.enabled && !!it.keyword?.trim()))
"
>
至少启用下方任意一个不为空的关键词后方可启用
启用下方任一非空项后方可启用
</template>
<template
v-else-if="element.item?.children?.some((it) => it.enabled && !it.keyword?.trim())"
v-else-if="
element.enabled &&
element?.children?.some((it) => it.enabled && !it.keyword?.trim())
"
>
留空的关键词会被跳过
空项会被跳过
</template>
</span>
<el-button p-0 h-fit type="text" @click="addSearchKeyword(element.item)"
<el-button
p-0
h-fit
type="text"
@click="
() => {
addSearchKeyword(element)
}
"
>添加关键词</el-button
>
</div>
</div>
</span>
</div>
<div v-if="element.item.type === 'search' && element.item?.children?.length">
<div v-if="element.type === 'search' && element?.children?.length">
<draggable
v-model="element.item.children"
v-model="element.children"
class="list-group"
:component-data="{
tag: 'ul',
@@ -101,7 +129,7 @@
<span class="inner-content">
<div flex w-full>
<el-switch
v-if="element.item.enabled"
v-if="element.enabled && searchItem.keyword?.trim()"
v-model="searchItem.enabled"
mr10px
active-text="启用"
@@ -116,6 +144,21 @@
active-text="启用"
inactive-text="禁用"
inline-prompt
@click="
() => {
if (!searchItem.keyword?.trim()) {
Message.info({
message: '关键词为空,请输入要搜索的关键词',
grouping: true
})
} else if (!element.enabled) {
Message.info({
message: '请启用“通过搜索找到的职位”来源',
grouping: true
})
}
}
"
/>
<el-input
v-model="searchItem.keyword"
@@ -129,7 +172,7 @@
h-fit
type="danger"
link
@click="removeSearchKeywordByIndex(element.item, index)"
@click="removeSearchKeywordByIndex(element, index)"
>删除</el-button
>
</span>
@@ -146,7 +189,7 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import draggable from 'vuedraggable'
import { ElMessage as Message } from 'element-plus'
defineProps({
modelValue: {
type: Array
@@ -169,6 +212,7 @@ function addSearchKeyword(item) {
if (!item.children) {
item.children = []
}
item.enabled = true
item.children.push({
type: 'search-kw',
enabled: true,
@@ -18,10 +18,35 @@
</el-form-item>
</el-card>
<el-card class="config-section">
<el-form-item prop="filter" mb0>
<el-form-item class="job-source-form-item" prop="__jobSourceList">
<div w-full>
<div font-size-16px>职位来源及查找顺序</div>
<JobSourceDragOrderer v-model="formContent.__jobSourceList" />
<div ref="jobSourceFormItemSectionEl" font-size-16px>
<div>
职位来源及其查找顺序
<el-tooltip
effect="light"
placement="bottom-start"
@show="gtagRenderer('tooltip_show_about_job_source_ui')"
>
<template #content>
<div m0 line-height-1.5em w-fit-content >
<img block h-320px src="../resources/intro-of-job-source.png" />
</div>
</template>
<el-button type="text" font-size-12px
><span><QuestionFilled w-1em h-1em mr2px /></span
>下方展示的各条目与Boss直聘界面对应关系是怎样的</el-button
>
</el-tooltip>
</div>
</div>
<div font-size-12px>
拖放条目前方的手柄以调整职位来源查找顺序点击条目前方的开关以启用/禁用对应的职位来源
</div>
<JobSourceDragOrderer
v-model="formContent.__jobSourceList"
class="job-source-drag-orderer"
/>
</div>
</el-form-item>
</el-card>
@@ -729,7 +754,9 @@
{{ getJobDetailRegExpMatchLogicConfig().logicText }}
</div>
<el-form-item mb0 prop="expectJobTypeRegExpStr">
<div font-size-12px>职位类型正则(推荐填写,不区分大小写)</div>
<div ref="jobDetailRegExpSectionEl" font-size-12px>
职位类型正则(推荐填写,不区分大小写)
</div>
<el-input
v-model="formContent.expectJobTypeRegExpStr"
type="textarea"
@@ -1052,6 +1079,8 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => {
)
})
const jobSourceFormItemSectionEl = ref()
const jobDetailRegExpSectionEl = ref()
const formRules = {
expectJobNameRegExpStr: {
validator(_, value, cb) {
@@ -1066,6 +1095,7 @@ const formRules = {
cb()
} catch (err) {
cb(new Error(`正则无效:${err?.message}`))
jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded()
gtagRenderer('invalid_reg_exp_for_expect_job_name')
}
}
@@ -1083,6 +1113,7 @@ const formRules = {
cb()
} catch (err) {
cb(new Error(`正则无效:${err?.message}`))
jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded()
gtagRenderer('invalid_reg_exp_for_expect_job_type')
}
}
@@ -1100,9 +1131,41 @@ const formRules = {
cb()
} catch (err) {
cb(new Error(`正则无效:${err?.message}`))
jobDetailRegExpSectionEl.value?.scrollIntoViewIfNeeded()
gtagRenderer('invalid_reg_exp_for_expect_job_desc')
}
}
},
__jobSourceList: {
trigger: null,
validator(_, value, cb) {
if (!Array.isArray(value)) {
cb()
return
}
if (value.every((it) => !it.enabled)) {
cb(new Error(`将上方任一来源设置为“启用”后才能继续`))
return
}
const configMap = {}
for (const config of value) {
if (configMap[config.type]) {
continue
}
configMap[config.type] = config
}
if (
!configMap.expect.enabled &&
!configMap.recommend.enabled &&
configMap.search.enabled &&
!configMap.search?.children?.some((it) => it.enabled && it.keyword?.trim())
) {
cb(new Error(`将上方任一来源设置为“启用”后才能继续`))
jobSourceFormItemSectionEl.value?.scrollIntoViewIfNeeded()
return
}
cb()
}
}
}
@@ -1500,20 +1563,18 @@ function formatJobSourceConfigToFormValue(config = []) {
return config.map((outerItem) => {
return {
item: outerItem,
label: typeToNameKey[outerItem.type],
children:
outerItem.children && outerItem.type === 'search'
? (outerItem.children || []).map((innerItem) => ({
item: innerItem
}))
: null
...outerItem,
label: typeToNameKey[outerItem.type]
}
})
}
function formatJobSourceFormValueToConfig(formValue = []) {
return formValue.map((it) => it.item)
return formValue.map((it) => {
it = { ...it }
delete it.label
return it
})
}
</script>
@@ -1579,5 +1640,25 @@ function formatJobSourceFormValueToConfig(formValue = []) {
font-size: 12px;
line-height: 1.2em;
}
.job-source-form-item {
margin-bottom: 0;
.job-source-drag-orderer {
margin-top: 10px;
background-color: #fff;
padding: 20px;
border: 1px solid var(--el-card-border-color);
border-radius: 4px;
}
&.is-error {
margin-bottom: 18px;
.el-input__wrapper {
box-shadow: 0 0 0 1px var(--el-border-color) inset;
}
.job-source-drag-orderer {
background-color: var(--el-color-danger-light-9);
border: 1px solid var(--el-color-danger);
}
}
}
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 902 KiB