import { observable, action, computed } from 'mobx' import { Config } from '../types/IntelligentSearchPanel' import { init, getSimilarQuery, postSearchCandidates } from '../utils/api' import { debounce } from '../utils/common' import { SimilarQueryItem, PostSearchCandidatesResponseData, SearchFilter, SearchFilterItem, } from '../types/searchSelect' import { transformTypeName, getChannelDict, transformQueryToQ, transformQToQuery, filterTagByShowUserTag, showSuggestDropdownTenant, transformDefaultQToQuery, } from '../utils/searchSelect' import { LabeledValue } from 'antd/lib/select' import { calcUserTagDict } from '../utils/searchSelect' import searchTypeSelect from './searchTypeSelect' import searchModeRadio from './searchModeRadio' import searchPagination from './searchPagination' import hasPhoneSwitch from './hasPhoneSwitch' import savedSearchParams from './savedSearchParams' class Main { /** * @description 配置 */ @observable config!: Config @action.bound setConfig(config: Config) { Object.assign(this, { config }) init(config) } /** * @description 是否正在获取相似查询参数 */ @observable pullingSimilarQuery: boolean = false @action.bound setPullingSimilarQuery(pullingSimilarQuery: boolean) { Object.assign(this, { pullingSimilarQuery }) } /** * @description 相似查询参数 */ @observable similarQuery: SimilarQueryItem[] = [] @action.bound setSimilarQuery(similarQuery: SimilarQueryItem[]) { Object.assign(this, { similarQuery }) } @action.bound pullSimilarQuery = debounce(async (query: string[]) => { const { setPullingSimilarQuery, setSimilarQuery, config } = this const { showSuggestDropdown, tenant } = config const { searchType } = searchTypeSelect const enabledSuggestDropdown = showSuggestDropdown || showSuggestDropdownTenant.includes(tenant) const defultQuery = { q: query[0], type_name: '智能搜索', order: 1 } if (searchType === 'resume_by_name' || !enabledSuggestDropdown) { setSimilarQuery([defultQuery]) return true } setPullingSimilarQuery(true) const res = await getSimilarQuery(query[0]) setPullingSimilarQuery(false) if (!res) return false setSimilarQuery(transformTypeName([defultQuery, ...res.data.result])) return true }, 500) /** * @description 选中的查询参数 */ @observable query: LabeledValue[] = [] @action.bound setQuery(query: LabeledValue[]) { Object.assign(this, { query }) } @action.bound setQueryAndSearch(query: LabeledValue[]) { const { setSimilarQuery, searchCandidate, setSearchFilters, setFoldAbleActiveFilter, setFilters, setQuery, } = this const { initTotalAndPage } = searchPagination setQuery(query) setSimilarQuery([]) setSearchFilters(null) setFoldAbleActiveFilter(null) setFilters([]) initTotalAndPage() searchCandidate() } /** * @description 搜索到的简历 */ @observable candidates: any[] = [] @action.bound setCandidates(candidates: any[]) { Object.assign(this, { candidates }) } /** * @description 搜索返回的filters */ @observable searchFilters: SearchFilter | null = null @action.bound setSearchFilters(searchFilters: SearchFilter | null) { Object.assign(this, { searchFilters }) } /** * @description 折叠Filters */ @computed get foldAbleFilters() { const { searchFilters, config } = this const { showUserTagFilterOption } = config const tags = searchFilters?.fold_tags || [] return tags.filter(_ => filterTagByShowUserTag(_, !!showUserTagFilterOption)) } /** * @description 可以直接显示的Filters */ @computed get foldAbleNotFilters() { const { searchFilters, config } = this const { showUserTagFilterOption } = config const tags = searchFilters?.tags || [] return tags.filter(_ => filterTagByShowUserTag(_, !!showUserTagFilterOption)) } /** * @description 所有的filters */ @computed get allFilters() { const { foldAbleFilters, foldAbleNotFilters } = this return [...foldAbleFilters, ...foldAbleNotFilters] } /** * @description 当前选择的Fold Able Filter */ @observable foldAbleActiveFilter: SearchFilterItem | null = null @action.bound setFoldAbleActiveFilter(foldAbleActiveFilter: SearchFilterItem | null) { Object.assign(this, { foldAbleActiveFilter }) } /** * @description user tag Dict */ @observable userTagDict: Map = new Map([]) @action.bound setUserTagDict(userTagDict: Map) { Object.assign(this, { userTagDict }) } /** * @description channel Dict */ @observable channelDict: Map = getChannelDict() /** * @description 选中的filters */ @observable filters: SearchFilterItem[] = [] @action.bound setFilters(filters: SearchFilterItem[]) { Object.assign(this, { filters }) } @action.bound appendFilter(filter: SearchFilterItem) { const { filters, setFilters, searchCandidate } = this setFilters([...filters, filter]) searchCandidate() } @action.bound removeFilter(index: number) { const { filters, setFilters, searchCandidate } = this const willUpdated = [...filters] willUpdated.splice(index, 1) setFilters(willUpdated) searchCandidate() } /** * @description 是否展示filter */ @observable filterBox: boolean = true @action.bound setFilterBox(filterBox: boolean) { Object.assign(this, { filterBox }) } @action.bound switchFilterBox() { const { filterBox, setFilterBox } = this setFilterBox(!filterBox) } /** * @description 是否正在搜索简历 */ @observable searchingCandidate: boolean = false @action.bound setSearchingCandidate(searchingCandidate: boolean) { Object.assign(this, { searchingCandidate }) } @action.bound getSearchCandidateParams() { const { query, filters } = this const { page, size } = searchPagination.pagination const { searchType } = searchTypeSelect const { searchMode } = searchModeRadio const params = { mode: searchMode, type: searchType, data: { // Page 从0开始 page: page - 1, size, filter: filters, q: transformQueryToQ(query), }, } const firstValue = (query[0]?.value || '') as string if (!firstValue.includes('唯一搜索')) return params params.data.q = '' const openid = firstValue.split(':')[1] ;(params.data as any).idFilter = openid return params } @action.bound handleSearchCandidateResponseData({ candidates, filter, extra, total, query, }: PostSearchCandidatesResponseData) { const { setCandidates, setSearchFilters, setUserTagDict, setFoldAbleActiveFilter, setQuery, } = this const { setTotal } = searchPagination const { checked } = hasPhoneSwitch const { searchType } = searchTypeSelect setCandidates(checked ? candidates.filter(({ resume }) => resume?.basic?.phone) : candidates) setSearchFilters(filter) setUserTagDict(calcUserTagDict(extra.user_tags)) setFoldAbleActiveFilter(null) setTotal(total) setQuery(transformQToQuery(query, searchType)) } @action.bound executeCallBack() { const { candidates, query, config } = this const { pagination } = searchPagination const { total, page } = pagination config.onSearch({ results: candidates, total, page, query: ((query[0]?.value as string) || '').split(':')[1], }) } @action.bound async searchCandidate() { const { getSearchCandidateParams, setSearchingCandidate, handleSearchCandidateResponseData, executeCallBack, } = this const { addSearchParamsHistory } = savedSearchParams const { searchType } = searchTypeSelect const params = getSearchCandidateParams() setSearchingCandidate(true) const res = await postSearchCandidates(params) setSearchingCandidate(false) if (!res) return false handleSearchCandidateResponseData(res.data) executeCallBack() if (res.data.query && searchType === 'resume') addSearchParamsHistory(res.data.query, params.data.filter) return true } @action.bound init() { const { config, setQuery, setFilters, setSearchFilters, setCandidates, searchCandidate } = this const { href } = window.location const hasOpenId = href.includes('openid=') const { defaultPayload } = config setQuery([]) setFilters([]) setSearchFilters(null) setCandidates([]) if (!defaultPayload?.q && !hasOpenId) return searchCandidate() const { setPageAndSize } = searchPagination let query: LabeledValue[] = [] if (defaultPayload?.q) { const { q } = defaultPayload query = transformDefaultQToQuery(q) } else { const openid = decodeURIComponent(href.split('openid=')[1]) query = [{ label: `唯一搜索:${openid}`, value: `唯一搜索:${openid}` }] } setQuery(query) setPageAndSize(defaultPayload?.page || 0, defaultPayload?.size || 10) return true } } export default new Main()