Files
ks-app-employment-service/stores/useRecommedIndexedDBStore.js
2025-06-20 10:10:46 +08:00

164 lines
5.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
defineStore
} from 'pinia';
import {
ref
} from 'vue'
import useDictStore from '@/stores/useDictStore';
import jobAnalyzer from '@/utils/jobAnalyzer';
import {
msg
} from '@/common/globalFunction.js'
import baseDB from './BaseDBStore';
import config from '../config';
class JobRecommendation {
constructor() {
this.conditions = {}; // 存储最新的条件及其出现次数
this.askHistory = new Map(); // 记录每个条件的最后询问时间
this.cooldown = 5 * 60 * 1000; // 冷却时间(单位:毫秒)
}
updateConditions(newConditions) {
this.conditions = newConditions;
}
getCurrentTime() {
return Date.now();
}
deleteHostiry(name) {
for (const [key, value] of Object.entries(this.conditions)) {
if (key === name) {
delete this.conditions[key]
}
}
this.askHistory.delete(name)
}
/**
* 获取下一个符合条件的推荐问题
* @returns {string|null} 返回推荐的问题,或 null无可询问的
*/
getNextQuestion() {
const now = this.getCurrentTime();
// 按照出现次数降序排序
const sortedConditions = Object.entries(this.conditions)
.sort((a, b) => b[1] - a[1]); // 按出现次数降序排序
for (const [condition, count] of sortedConditions) {
const lastAskedTime = this.askHistory.get(condition);
if (!lastAskedTime || now - lastAskedTime >= this.cooldown) {
this.askHistory.set(condition, now);
return condition;
}
}
return null; // 没有可询问的
}
}
/**
* 计算加权用户行为偏好
* @param {Object} data - 用户行为数据,包括 categories、experience、areas、salary 等
* @param {Object} weights - 每一类行为的权重
* @returns {Object} 加权合并后的结果key 为行为项value 为权重后的分值)
*/
function applyWeightsToUserData(data, weights) {
const result = {}
for (const key in data) {
if (key === 'salary') {
result.salary = weights.salary
} else if (typeof data[key] === 'object') {
result[key] = {}
for (const itemKey in data[key]) {
const rawValue = data[key][itemKey]
result[key][itemKey] = parseFloat((rawValue * weights[key]).toFixed(2))
}
}
}
return result
}
// **🔹 创建推荐系统**
export const jobRecommender = new JobRecommendation();
export const useRecommedIndexedDBStore = defineStore("indexedDB", () => {
const tableName = ref('record')
const total = ref(200) // 记录多少条数据
// 插入数据
async function addRecord(payload) {
const totalRecords = await baseDB.db.getRecordCount(tableName.value);
if (totalRecords >= total.value) {
console.log(`⚠数据超过 ${total.value} 条,删除最早的一条...`);
await baseDB.db.deleteOldestRecord(tableName.value);
}
if (!baseDB.isDBReady) await baseDB.initDB();
return await baseDB.db.add(tableName.value, payload);
}
// 清除数据 1、清除数据库数据
async function deleteRecords(payload) {
if (!baseDB.isDBReady) await baseDB.initDB();
try {
const jobstr = payload.jobCategory
const jobsObj = {
'地区': 'jobLocationAreaCodeLabel',
'岗位': 'jobCategory',
'经验': 'experIenceLabel',
}
const [name, value] = jobstr.split(':')
const nameAttr = jobsObj[name]
jobRecommender.deleteHostiry(jobstr)
return await baseDB.db.deleteByCondition(tableName.value, (record) => record[nameAttr] ===
value);
} catch {}
}
// 获取所有数据
async function getRecord() {
if (!baseDB.isDBReady) await baseDB.initDB();
return await baseDB.db.getAll(tableName.value);
}
// 格式化浏览数据岗位数据
function JobParameter(job) {
const experIenceLabel = useDictStore().dictLabel('experience', job.experience)
const jobLocationAreaCodeLabel = useDictStore().dictLabel('area', job.jobLocationAreaCode)
return {
jobCategory: job.jobCategory,
jobTitle: job.jobTitle,
minSalary: job.minSalary,
maxSalary: job.maxSalary,
experience: job.experience,
experIenceLabel,
jobLocationAreaCode: job.jobLocationAreaCode,
jobLocationAreaCodeLabel,
createTime: Date.now()
}
}
function analyzer(jobsData) {
const result = jobAnalyzer.analyze(jobsData) // 转换格式化
const result2 = applyWeightsToUserData(result, config.weights) // 添加权重
const sort = jobAnalyzer.printUnifiedResults(result2) // 转换格式化
return {
result,
sort
}
}
return {
addRecord,
getRecord,
JobParameter,
analyzer,
deleteRecords
};
});