岗位职责
- ${duty}
职位要求
- ${requirement}
// 处于页面配置时,绑定方法 start if ($isDecorateMode) { document.addEventListener("diy_header/1", (event) => { const { field, value } = event.detail; console.log(field, value) }); } // 处于页面配置时,绑定方法 end $(function () { let solutionTabsStickPoint = null const PAGE_TRANSLATE_STORAGE_KEY = 'shenglan.pageTranslate.locale' const PAGE_TRANSLATE_CACHE_KEY = 'shenglan.pageTranslate.cache.v2' const PAGE_TRANSLATE_PENDING_CLASS = 'is-translation-pending' const MAX_TRANSLATE_BATCH_BYTES = 4000 const MAX_TRANSLATE_BATCH_ITEMS = 30 const translateTextEncoder = new TextEncoder() let translateTimer = null $("#logout").click(function () { $request .post("/api/user/logout") .then((res) => { // 跳转页面 location.href = "/"; }); }) // 防止一开始进入页面在底部不显示 setHeaderSticky() $(window).on('scroll', setHeaderSticky) $(window).on('resize', function () { solutionTabsStickPoint = null setHeaderSticky() }) function setHeaderSticky(){ let offset = $(window).scrollTop() if (offset > 0) { $('.ys-header').addClass('is-sticky') } else { $('.ys-header').removeClass('is-sticky') } setSolutionShowcaseState(offset) } function setSolutionShowcaseState(offset) { const tabsWrap = $('.solution-showcase__tabs-wrap') if (!tabsWrap.length) { $('body').removeClass('solution-showcase-at-top solution-showcase-tabs-stuck') solutionTabsStickPoint = null return } if (solutionTabsStickPoint === null) { refreshSolutionTabsStickPoint(tabsWrap) } const isAtTop = offset <= 0 const isTabsStuck = !isAtTop && offset >= solutionTabsStickPoint $('body').toggleClass('solution-showcase-at-top', isAtTop) $('body').toggleClass('solution-showcase-tabs-stuck', isTabsStuck) tabsWrap.toggleClass('is-stuck', isTabsStuck) } function refreshSolutionTabsStickPoint(tabsWrap) { const wasStuck = tabsWrap.hasClass('is-stuck') const body = $('body') tabsWrap.removeClass('is-stuck') body.removeClass('solution-showcase-tabs-stuck') tabsWrap.addClass('is-stuck') const stickyTabsHeight = tabsWrap.outerHeight() || 64 tabsWrap.removeClass('is-stuck') const hero = tabsWrap.prev('.solution-showcase__hero') const heroBottom = hero.length ? hero.offset().top + hero.outerHeight() : tabsWrap.offset().top solutionTabsStickPoint = Math.max(0, Math.ceil(heroBottom - stickyTabsHeight)) tabsWrap.css('--solution-tabs-height', stickyTabsHeight + 'px') tabsWrap.toggleClass('is-stuck', wasStuck) body.toggleClass('solution-showcase-tabs-stuck', wasStuck) } // 隐藏 导航栏 active function hideActiveCard() { $('.ys-header__nav .nav-item .ys-header__card.active').stop().fadeOut(300) } // 显示 导航栏 active function showActiveCard() { $('.ys-header__nav .nav-item .ys-header__card.active').stop().fadeIn(300) } // mega menu hover interaction $('.mega-sidebar-item').mouseenter(function() { let index = $(this).data('index'); $('.mega-sidebar-item').removeClass('active'); $(this).addClass('active'); $(this).closest('.ys-header__mega').find('.mega-panel').removeClass('active'); $(this).closest('.ys-header__mega').find(`.mega-panel[data-index="${index}"]`).addClass('active'); }); $('.close-mega-menu').click(function() { $(this).closest('.nav-item').trigger('mouseleave'); }); // 导航栏悬停 $('.ys-header__nav .nav-item').hover(function () { if(!$(this).find('.ys-header__card').hasClass('active')) hideActiveCard() $(this).find('.ys-header__card').addClass('show') if(!$(this).hasClass('ignore')) $('.ys-header__cover').removeClass('display-none') }, function () { if(!$(this).find('.ys-header__card').hasClass('active')) showActiveCard() $(this).find('.ys-header__card').removeClass('show') $('.ys-header__cover').addClass('display-none') }) // 搜索图标点击:参考 header/2 展开搜索区域 $('.ys-header__search-icon').click(function () { openSearchCard() $('.ys-header__search input').trigger('focus') }) $('.ys-header__search input').focus(function () { openSearchCard() }) function containsTarget(selector, target) { const node = $(selector)[0] return !!(node && node.contains(target)) } $(document).on('click', function (e) { if ( containsTarget(".ys-header .ys-header__search", e.target) || containsTarget(".ys-header .ys-header__search-icon", e.target) || $(".ys-header__search input").is(":focus") || containsTarget(".ys-header .ys-header__menu", e.target) || containsTarget(".ys-header .ys-header-menu", e.target) || containsTarget(".ys-header .ys-header-search--mobile", e.target) ) return closeSearchCard(); }) // 搜索 $('.ys-header__search input').keyup(function (e) { if (e.keyCode === 13) { search() } }) $('.ys-header__search .search-btn').click(function () { search() }) // 联系销售:与 rightNav/1 的在线客服保持一致 $('.ys-header__contact-btn').click(function (e) { e.preventDefault() // 优先走全局事件,复用 rightNav/1 的统一客服打开逻辑 window.dispatchEvent(new Event('openService')) // 兜底:当 rightNav 未挂载时,直接触发已知客服按钮 if ($('#aff-im-root .embed-icon-pcIcon5').length > 0) { $('#aff-im-root .embed-icon-pcIcon5').click() return } if ($('#newBridge .nb-icon-wrap').length > 0) { $('#newBridge .nb-icon-wrap').click() } }) $('.js-page-translate-btn').click(function (e) { e.preventDefault() window.__translateFailed = false localStorage.setItem(PAGE_TRANSLATE_STORAGE_KEY, 'en') if (!isEnglishPath(location.pathname)) { location.href = buildEnglishUrl(location.pathname) return } localizeEnglishModeLinks() translatePageToEnglish($(this)) }) $('.js-page-translate-reset').click(function (e) { e.preventDefault() localStorage.removeItem(PAGE_TRANSLATE_STORAGE_KEY) delete document.documentElement.dataset.translated syncTranslateLanguageMenu() location.href = buildChineseUrl(location.pathname) }) autoTranslatePageIfNeeded() function autoTranslatePageIfNeeded() { if (isEnglishModeRequested()) { localStorage.setItem(PAGE_TRANSLATE_STORAGE_KEY, 'en') removeTranslateQueryFlag() } syncTranslateLanguageMenu() if (localStorage.getItem(PAGE_TRANSLATE_STORAGE_KEY) !== 'en') { revealTranslatedPage() return } localizeEnglishModeLinks() startTranslateDomObserver() const $button = $('.js-page-translate-btn') translatePageToEnglish($button, { silent: true }) } function isEnglishModeRequested() { return isEnglishPath(location.pathname) || new URLSearchParams(location.search).get('__translate') === 'en' } function syncTranslateLanguageMenu() { if (isPageTranslatedToEnglish()) { $('.js-page-translate-reset').removeClass('active') $('.js-page-translate-btn').addClass('active') $('.ys-header__lang-trigger span').text('EN') return } $('.js-page-translate-reset').addClass('active') $('.js-page-translate-btn').removeClass('active') $('.ys-header__lang-trigger span').text('CN') } function isPageTranslatedToEnglish() { return document.documentElement.dataset.translated === 'en' || localStorage.getItem(PAGE_TRANSLATE_STORAGE_KEY) === 'en' || isEnglishPath(location.pathname) } function revealTranslatedPage() { document.documentElement.classList.remove(PAGE_TRANSLATE_PENDING_CLASS) } function stripEnglishPrefix(pathname) { const mountPrefix = getMountPrefix(pathname) const pathAfterMount = getPathAfterMount(pathname) if (pathAfterMount === '/en') return mountPrefix || '/' if (!pathAfterMount.startsWith('/en/')) return pathname || '/' return (mountPrefix + pathAfterMount.replace(/^\/en(?=\/)/, '')) || '/' } function addEnglishPrefix(pathname) { const mountPrefix = getMountPrefix(pathname) const pathAfterMount = getPathAfterMount(pathname) if (pathAfterMount === '/en' || pathAfterMount.startsWith('/en/')) return pathname || '/' if (pathAfterMount === '/') return mountPrefix + '/en' return mountPrefix + '/en' + pathAfterMount } function isEnglishPath(pathname) { const pathAfterMount = getPathAfterMount(pathname) return pathAfterMount === '/en' || pathAfterMount.startsWith('/en/') } function getMountPrefix(pathname = location.pathname) { return pathname === '/shenglan' || pathname.startsWith('/shenglan/') ? '/shenglan' : '' } function getPathAfterMount(pathname = location.pathname) { const mountPrefix = getMountPrefix(pathname) if (!mountPrefix) return pathname || '/' if (pathname === mountPrefix) return '/' return pathname.slice(mountPrefix.length) || '/' } function cleanTranslateSearch() { const url = new URL(location.href) url.searchParams.delete('__translate') return url.search } function buildEnglishUrl(pathname) { return addEnglishPrefix(pathname) + cleanTranslateSearch() + location.hash } function buildChineseUrl(pathname) { return stripEnglishPrefix(pathname) + cleanTranslateSearch() + location.hash } function removeTranslateQueryFlag() { if (new URLSearchParams(location.search).get('__translate') !== 'en') return const url = new URL(location.href) url.searchParams.delete('__translate') history.replaceState(null, '', url.pathname + url.search + url.hash) } function localizeEnglishModeLinks(root = document) { if (localStorage.getItem(PAGE_TRANSLATE_STORAGE_KEY) !== 'en') return const scope = root && root.nodeType === 1 ? root : document $(scope).find('a[href], form[action]').addBack('a[href], form[action]').each(function () { const attr = this.tagName === 'FORM' ? 'action' : 'href' const value = $(this).attr(attr) const localized = localizeEnglishModeUrl(value) if (localized && localized !== value) { $(this).attr(attr, localized) } }) } function localizeEnglishModeUrl(value) { if (!value || shouldSkipLocalizedUrl(value)) return value let url try { url = new URL(value, location.href) } catch (e) { return value } if (url.origin !== location.origin) return value const mountPrefix = getMountPrefix(location.pathname) const normalizedPathname = normalizePathnameToCurrentMount(url.pathname, mountPrefix) if (shouldSkipLocalizedPath(normalizedPathname)) return value if (isEnglishPath(normalizedPathname)) { return normalizedPathname !== url.pathname ? normalizedPathname + url.search + url.hash : value } const localizedPathname = addEnglishPrefix(normalizedPathname) return localizedPathname + url.search + url.hash } function normalizePathnameToCurrentMount(pathname, mountPrefix) { if (!mountPrefix) return pathname || '/' if (pathname === mountPrefix || pathname.startsWith(mountPrefix + '/')) return pathname return mountPrefix + (pathname === '/' ? '' : pathname) } function shouldSkipLocalizedUrl(value) { const trimmed = String(value).trim() return ( trimmed === '' || trimmed.startsWith('#') || /^(javascript|mailto|tel):/i.test(trimmed) ) } function shouldSkipLocalizedPath(pathname) { const pathAfterMount = getPathAfterMount(pathname) if (pathAfterMount === '/en' || pathAfterMount.startsWith('/en/')) return true if (/^\/(api|admin|asset|resource|library|load)(\/|$)/.test(pathAfterMount)) return true if (pathAfterMount === '/') return false const lastSegment = pathAfterMount.split('/').pop() || '' const hasFileExtension = /\.[a-z0-9]+$/i.test(lastSegment) return hasFileExtension && !/\.html$/i.test(lastSegment) } function translatePageToEnglish($button, options = {}) { if ($button.data('loading')) { revealTranslatedPage() return } const records = collectPageTranslateRecords() const texts = Array.from(new Set(records.map((record) => record.text))).filter(Boolean) if (!texts.length) { if (!options.silent) $message.info('当前页面暂无可翻译中文') revealTranslatedPage() return } $button.data('loading', true).text('English') translateTextBatches(texts) .then((translations) => { applyPageTranslations(records, translations) document.documentElement.dataset.translated = 'en' localStorage.setItem(PAGE_TRANSLATE_STORAGE_KEY, 'en') localizeEnglishModeLinks() syncTranslateLanguageMenu() startTranslateDomObserver() $button.text('English') revealTranslatedPage() if (!options.silent) $message.success('翻译完成') }) .catch((err) => { window.__translateFailed = true $button.text('English') const msg = err?.message || err?.data?.message || '翻译失败' if (options.silent) { console.warn(msg) } else { $message.error(msg) } revealTranslatedPage() }) .finally(() => { $button.data('loading', false) }) } function collectPageTranslateRecords() { const records = [] const skipTags = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'SVG', 'CANVAS', 'IFRAME']) const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, { acceptNode(node) { const parent = node.parentElement if (!parent || skipTags.has(parent.tagName)) return NodeFilter.FILTER_REJECT if ($(parent).closest('[data-no-translate]').length) return NodeFilter.FILTER_REJECT return hasChinese(node.nodeValue) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }, }) let node while ((node = walker.nextNode())) { const original = node.nodeValue const text = normalizeTranslateText(original.trim()) if (!text) continue records.push({ type: 'text', node, text, leading: original.match(/^\s*/)?.[0] || '', trailing: original.match(/\s*$/)?.[0] || '', }) } $('[title], [alt], [placeholder], [aria-label]').each(function () { if ($(this).closest('[data-no-translate]').length) return ;['title', 'alt', 'placeholder', 'aria-label'].forEach((attr) => { const value = $(this).attr(attr) if (hasChinese(value || '')) { records.push({ type: 'attr', node: this, attr, text: normalizeTranslateText(value.trim()) }) } }) }) return records } function translateTextBatches(texts) { const cachedTranslations = readTranslateCache() const translationsFromCache = {} const pendingTexts = [] texts.forEach((text) => { if (isUsableCachedTranslation(text, cachedTranslations[text])) { translationsFromCache[text] = cachedTranslations[text] } else { pendingTexts.push(text) } }) const batches = [] let currentBatch = [] let currentBytes = 0 pendingTexts.forEach((text) => { const textBytes = translateTextBytes(text) + 1 if ( currentBatch.length > 0 && (currentBatch.length >= MAX_TRANSLATE_BATCH_ITEMS || currentBytes + textBytes > MAX_TRANSLATE_BATCH_BYTES) ) { batches.push(currentBatch) currentBatch = [] currentBytes = 0 } currentBatch.push(text) currentBytes += textBytes }) if (currentBatch.length) { batches.push(currentBatch) } let batchFailed = false return batches.reduce((promise, batch) => { return promise.then((translations) => { if (batchFailed) return translations return $request.post('/api/translate/text', { texts: batch }).then((res) => { const batchTranslations = res.data?.translations || {} Object.assign(translations, batchTranslations) writeTranslateCache(batchTranslations) return translations }).catch((err) => { batchFailed = true console.warn(err?.message || err?.data?.message || '翻译批次失败') return Promise.reject(err) }) }) }, Promise.resolve(translationsFromCache)) } function translateTextBytes(text) { return translateTextEncoder.encode(text || '').length } function readTranslateCache() { try { return JSON.parse(localStorage.getItem(PAGE_TRANSLATE_CACHE_KEY) || '{}') } catch (e) { return {} } } function writeTranslateCache(translations) { const usableTranslations = filterUsableTranslations(translations) if (!Object.keys(usableTranslations).length) return const cache = readTranslateCache() Object.assign(cache, usableTranslations) const keys = Object.keys(cache) if (keys.length > 1200) { keys.slice(0, keys.length - 1200).forEach((key) => delete cache[key]) } localStorage.setItem(PAGE_TRANSLATE_CACHE_KEY, JSON.stringify(cache)) } function filterUsableTranslations(translations) { const output = {} Object.keys(translations || {}).forEach((source) => { const translated = translations[source] if (isUsableCachedTranslation(source, translated)) { output[source] = translated } }) return output } function isUsableCachedTranslation(source, translated) { return typeof translated === 'string' && translated !== '' && translated !== source && !hasChinese(translated) } function applyPageTranslations(records, translations) { records.forEach((record) => { const translated = translations[record.text] if (!translated || translated === record.text) return if (record.type === 'text') { record.node.nodeValue = `${record.leading || ''}${translated}${record.trailing || ''}` return } $(record.node).attr(record.attr, translated) }) } function hasChinese(text) { return /[\u4e00-\u9fff]/.test(text || '') } function normalizeTranslateText(text) { return (text || '').replace(/\s+/g, ' ').trim() } function startTranslateDomObserver() { if (window.__pageTranslateObserver) return window.__pageTranslateObserver = new MutationObserver(() => { localizeEnglishModeLinks() scheduleTranslateRemainingChinese() }) window.__pageTranslateObserver.observe(document.body, { childList: true, subtree: true, characterData: true, }) } function scheduleTranslateRemainingChinese() { if (localStorage.getItem(PAGE_TRANSLATE_STORAGE_KEY) !== 'en') return if (window.__translateFailed) return clearTimeout(translateTimer) translateTimer = setTimeout(() => { translatePageToEnglish($('.js-page-translate-btn'), { silent: true }) }, 300) } // 展开搜索卡片 function openSearchCard() { $('.ys-header__nav').addClass('display-none') $('.ys-header__logo').addClass('display-none') $('.ys-header__right').addClass('open') } // 收起搜索卡片 function closeSearchCard() { $('.ys-header__nav').removeClass('display-none') $('.ys-header__logo').removeClass('display-none') $('.ys-header__right').removeClass('open') $('.ys-header').removeClass('is-show-mobile-search') } // 搜索事件 function search() { let val = $('.ys-header__search input').val() if (!val) return $message.warning('请输入搜索关键词') const searchPath = localStorage.getItem(PAGE_TRANSLATE_STORAGE_KEY) === 'en' ? addEnglishPrefix(normalizePathnameToCurrentMount('/search_result.html', getMountPrefix(location.pathname))) : normalizePathnameToCurrentMount('/search_result.html', getMountPrefix(location.pathname)) window.location.href = searchPath + '?keyword=' + encodeURIComponent(val) closeSearchCard() } // 产品二级菜单切换 $('.ys-header__nav .product-item').hover(function () { $('.ys-header__nav .product-child').addClass('display-none') $('.ys-header__nav .product-item').removeClass('active') $(this).addClass('active') $(this).next().removeClass('display-none') }) // 点击遮罩 $('.ys-header__cover').click(function(){ closeMenuFold() }) // 移动端搜索 $('.ys-header .ys-header-search--mobile .icon-search').click(function(){ $('.ys-header').addClass('is-show-mobile-search') openSearchCard() }) // 抽屉 function openMenuFold() { $('.ys-header .ys-header-menu').addClass('show') $('.ys-header__cover').removeClass('display-none') $('body').addClass('popup-parent--hidden') } function closeMenuFold() { $('.ys-header__cover').addClass('display-none') $('.ys-header .ys-header-menu').removeClass('show') $('body').removeClass('popup-parent--hidden') closeAllMenuSecond() } $('.ys-header .ys-header__menu .icon-menu').click(openMenuFold) $('.ys-header .ys-header-menu .icon-close').click(closeMenuFold) }) // 二级菜单 $('.ys-header-menu').on('click', '.header-menu__more', function() { const item = $(this) const flag = item.next().hasClass('active') $('.header-menu__list').removeClass('active').stop().slideUp() if(flag) return item.next().addClass('active').stop().slideDown() }) $('.ys-header-menu').on('click', '.header-menu__button', function() { const item = $(this) closeAllMenuSecond() item.next().addClass('active') }) $('.ys-header-menu').on('click', '.header-second-back', function() { closeAllMenuSecond() }) function closeAllMenuSecond() { $('.header-menu__second').removeClass('active') } /* 岗位 start */ // 详情 $(".join-post__list").on("click", ".post-header", function () { const current = $(this); const parent = current.parents(".post-item"); if (parent.hasClass("active")) { current.next().stop().slideUp(); parent.removeClass("active"); return; } $(".join-post__list .post-item").removeClass("active"); $(".join-post__list .post-content").hide(); current.next().stop().slideDown(); parent.addClass("active"); }); // 分页器 let params = { total: +$(".c-pagination-nav").data("total") || 0, page: +$(".c-pagination-nav").data("page") || 1, pageSize: +$(".c-page-selector").data("default") || 8, }; $(".c-pagination").zPager({ totalData: params.total, pageStep: 5, current: params.page, pageData: params.pageSize, }); window.addEventListener("current_page", currentPage); // 监听页码变化 function currentPage(e) { if (e == params.page) return; // window.location.href = `/join/job.html?page=${page}&pageSize=${pageSize}`; params.page = +e; request(); } function request() { $loading.start(); getFromData(); // 获取from数据 $request .get("/api/service/job/list", { params }) .then((res) => { $(".join-post__list").html(''); $(".c-pagination").html(""); const result = res.data; if (!result || !Array.isArray(result.list) || !result.list.length) { $(".join-post__list").html('
暂无数据${item.city ? `工作地点: ${item.city}` :''} ${item.job_type ? `招聘类型: ${item.job_type == 1 ? '校园招聘':'社会招聘'}` :''} ${item.created_at ? `发布时间: ${item.created_at}` :''}