166 lines
5.0 KiB
JavaScript
166 lines
5.0 KiB
JavaScript
![]() |
/**
|
|||
|
* 岗位数据分析模块
|
|||
|
*/
|
|||
|
const jobAnalyzer = {
|
|||
|
/**
|
|||
|
* 清洗无效薪资数据
|
|||
|
* @param {Array} jobs 原始岗位数据
|
|||
|
* @returns {Array} 有效岗位数据
|
|||
|
*/
|
|||
|
cleanData: (jobs) => {
|
|||
|
if (!Array.isArray(jobs)) return []
|
|||
|
return jobs.filter(job =>
|
|||
|
Number(job.minSalary) > 0 &&
|
|||
|
Number(job.maxSalary) > 0
|
|||
|
)
|
|||
|
},
|
|||
|
|
|||
|
/**
|
|||
|
* 执行完整分析流程
|
|||
|
* @param {Array} jobs 原始岗位数据
|
|||
|
* @param {Object} options 配置选项
|
|||
|
* @returns {Object} 分析结果
|
|||
|
*/
|
|||
|
analyze: (jobs, options = {
|
|||
|
verbose: false
|
|||
|
}) => {
|
|||
|
// 数据校验
|
|||
|
if (!Array.isArray(jobs)) {
|
|||
|
throw new Error('Invalid jobs data format')
|
|||
|
}
|
|||
|
|
|||
|
// 数据清洗
|
|||
|
const validJobs = jobAnalyzer.cleanData(jobs)
|
|||
|
if (validJobs.length === 0) {
|
|||
|
return {
|
|||
|
warning: 'No valid job data available'
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 执行分析
|
|||
|
const results = {
|
|||
|
salary: jobAnalyzer.analyzeSalaries(validJobs),
|
|||
|
categories: jobAnalyzer.countCategories(validJobs),
|
|||
|
experience: jobAnalyzer.analyzeExperience(validJobs),
|
|||
|
areas: jobAnalyzer.analyzeAreas(validJobs)
|
|||
|
}
|
|||
|
|
|||
|
// 按需控制台输出
|
|||
|
if (options.verbose) {
|
|||
|
jobAnalyzer.printResults(results)
|
|||
|
}
|
|||
|
|
|||
|
return results
|
|||
|
},
|
|||
|
|
|||
|
/** 薪资分析 */
|
|||
|
analyzeSalaries: (jobs) => {
|
|||
|
const stats = jobs.reduce((acc, job) => {
|
|||
|
acc.totalMin += job.minSalary
|
|||
|
acc.totalMax += job.maxSalary
|
|||
|
acc.highPay += (job.maxSalary >= 10000) ? 1 : 0
|
|||
|
return acc
|
|||
|
}, {
|
|||
|
totalMin: 0,
|
|||
|
totalMax: 0,
|
|||
|
highPay: 0
|
|||
|
})
|
|||
|
|
|||
|
return {
|
|||
|
avgMin: Math.round(stats.totalMin / jobs.length),
|
|||
|
avgMax: Math.round(stats.totalMax / jobs.length),
|
|||
|
highPayRatio: Math.round((stats.highPay / jobs.length) * 100)
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
/** 岗位类别统计 */
|
|||
|
countCategories: (jobs) => {
|
|||
|
return jobs.reduce((map, job) => {
|
|||
|
map[job.jobCategory] = (map[job.jobCategory] || 0) + 1
|
|||
|
return map
|
|||
|
}, {})
|
|||
|
},
|
|||
|
|
|||
|
/** 经验要求分析 */
|
|||
|
analyzeExperience: (jobs) => {
|
|||
|
return jobs.reduce((stats, job) => {
|
|||
|
const label = job.experIenceLabel || '未知'
|
|||
|
stats[label] = (stats[label] || 0) + 1
|
|||
|
return stats
|
|||
|
}, {})
|
|||
|
},
|
|||
|
|
|||
|
/** 地区分布分析 */
|
|||
|
analyzeAreas: (jobs) => {
|
|||
|
return jobs.reduce((map, job) => {
|
|||
|
const area = job.jobLocationAreaCodeLabel || '未知'
|
|||
|
map[area] = (map[area] || 0) + 1
|
|||
|
return map
|
|||
|
}, {})
|
|||
|
},
|
|||
|
|
|||
|
/** 格式化输出结果 */
|
|||
|
printResults: (results) => {
|
|||
|
console.log('【高薪岗位分析】')
|
|||
|
console.log(`- 平均月薪范围:${results.salary.avgMin}k ~ ${results.salary.avgMax}k`)
|
|||
|
console.log(`- 月薪≥10k的岗位占比:${results.salary.highPayRatio}%`)
|
|||
|
|
|||
|
console.log('\n【热门岗位类别】')
|
|||
|
console.log(Object.entries(results.categories)
|
|||
|
.sort((a, b) => b[1] - a[1])
|
|||
|
.map(([k, v]) => `- ${k} (${v}个)`)
|
|||
|
.join('\n'))
|
|||
|
|
|||
|
console.log('\n【经验要求分布】')
|
|||
|
console.log(Object.entries(results.experience)
|
|||
|
.map(([k, v]) => `- ${k}: ${v}个`)
|
|||
|
.join('\n'))
|
|||
|
|
|||
|
console.log('\n【工作地区分布】')
|
|||
|
console.log(Object.entries(results.areas)
|
|||
|
.sort((a, b) => b[1] - a[1])
|
|||
|
.map(([k, v]) => `- ${k}: ${v}个`)
|
|||
|
.join('\n'))
|
|||
|
},
|
|||
|
/** 合并所有统计属性并添加类型前缀 */
|
|||
|
_mergeAllStats: (results) => {
|
|||
|
const merged = {}
|
|||
|
|
|||
|
// 合并岗位类别(添加前缀)
|
|||
|
Object.entries(results.categories).forEach(([k, v]) => {
|
|||
|
merged[`岗位:${k}`] = v
|
|||
|
})
|
|||
|
|
|||
|
// 合并工作地区(添加前缀)
|
|||
|
Object.entries(results.areas).forEach(([k, v]) => {
|
|||
|
merged[`地区:${k}`] = v
|
|||
|
})
|
|||
|
|
|||
|
// 合并经验要求(添加前缀)
|
|||
|
Object.entries(results.experience).forEach(([k, v]) => {
|
|||
|
merged[`经验:${k}`] = v
|
|||
|
})
|
|||
|
|
|||
|
return merged
|
|||
|
},
|
|||
|
|
|||
|
/** 全属性统一排序输出 */
|
|||
|
printUnifiedResults: (results, options = {
|
|||
|
log: false
|
|||
|
}) => {
|
|||
|
const mergedData = jobAnalyzer._mergeAllStats(results)
|
|||
|
|
|||
|
const sortedEntries = Object.entries(mergedData)
|
|||
|
.sort((a, b) => b[1] - a[1])
|
|||
|
if (options.log) {
|
|||
|
// 格式化输出
|
|||
|
console.log('【全维度排序分析】')
|
|||
|
console.log(sortedEntries
|
|||
|
.map(([k, v]) => `- ${k}: ${v}个`)
|
|||
|
.join('\n'))
|
|||
|
}
|
|||
|
return sortedEntries
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
export default jobAnalyzer
|