文章目录
-
- 在当今数字化时代,网站已不仅仅是信息展示平台,更是用户互动与价值传递的重要载体。对于教育机构、职业咨询平台、人力资源网站或企业招聘门户而言,集成专业的心理测评与职业倾向分析工具能够显著提升用户体验和网站价值。 通过WordPress这一全球最流行的内容管理系统,我们可以通过代码二次开发实现这些功能,而无需依赖昂贵的第三方服务。本教程将详细指导您如何从零开始,为您的WordPress网站集成专业的在线心理测评与职业倾向分析工具,同时确保数据安全、用户体验和系统稳定性。
-
- 在开始开发之前,我们需要明确技术需求: WordPress版本:5.0或更高(推荐最新版本) PHP版本:7.4或更高(推荐8.0+) MySQL版本:5.6或更高 服务器内存:至少512MB(推荐1GB以上) 必要的WordPress权限:主题编辑、插件安装、文件上传
- 为了安全地进行开发,建议首先在本地或测试服务器搭建环境: 本地开发环境选择: XAMPP(Windows/Mac/Linux) Local by Flywheel(特别适合WordPress开发) Docker WordPress开发环境 测试服务器配置: # 示例:通过SSH配置测试服务器环境 sudo apt update sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql sudo systemctl restart apache2 WordPress安装与基础配置: 下载最新WordPress版本 创建数据库和用户 完成五步安装流程 设置固定链接结构(推荐"文章名"格式)
- 在进行任何代码修改前,必须建立完整备份: 数据库备份: -- 通过phpMyAdmin或命令行备份 mysqldump -u username -p database_name > backup_date.sql 文件备份: # 备份整个WordPress目录 tar -czf wordpress_backup_date.tar.gz /path/to/wordpress 使用备份插件: UpdraftPlus BackWPup Duplicator(特别适合迁移)
-
- 我们需要设计两种主要测评类型: 心理测评:包含人格测试、情绪评估、压力测试等 职业倾向分析:基于霍兰德职业兴趣理论、MBTI等经典模型
- 在WordPress数据库中添加自定义表来存储测评数据: -- 测评问卷表 CREATE TABLE wp_assessment_questionnaires ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT, type ENUM('psychological', 'career') NOT NULL, questions_count INT DEFAULT 0, time_estimate INT COMMENT '预计完成时间(分钟)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, status ENUM('active', 'inactive', 'draft') DEFAULT 'draft' ); -- 测评问题表 CREATE TABLE wp_assessment_questions ( id INT AUTO_INCREMENT PRIMARY KEY, questionnaire_id INT NOT NULL, question_text TEXT NOT NULL, question_type ENUM('single_choice', 'multiple_choice', 'likert_scale', 'open_ended') NOT NULL, options JSON COMMENT 'JSON格式存储选项', sort_order INT DEFAULT 0, FOREIGN KEY (questionnaire_id) REFERENCES wp_assessment_questionnaires(id) ON DELETE CASCADE ); -- 测评结果表 CREATE TABLE wp_assessment_results ( id INT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT(20) UNSIGNED, questionnaire_id INT NOT NULL, answers JSON NOT NULL COMMENT '用户答案JSON', score_data JSON COMMENT '得分与解析JSON', completed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ip_address VARCHAR(45), session_id VARCHAR(255), FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE SET NULL, FOREIGN KEY (questionnaire_id) REFERENCES wp_assessment_questionnaires(id) ON DELETE CASCADE ); -- 职业倾向分析结果表 CREATE TABLE wp_career_analysis ( id INT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT(20) UNSIGNED, holland_code CHAR(3) COMMENT '霍兰德代码如RIA, SEC等', mbti_type VARCHAR(4) COMMENT 'MBTI类型如INTJ, ENFP等', strengths TEXT COMMENT '优势分析', career_suggestions JSON COMMENT '职业建议', analysis_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE SET NULL );
- 在插件或主题中注册自定义表: // 在插件激活时创建表 function assessment_tools_install_tables() { global $wpdb; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); // 获取字符集和排序规则 $charset_collate = $wpdb->get_charset_collate(); // 创建问卷表 $table_name = $wpdb->prefix . 'assessment_questionnaires'; $sql = "CREATE TABLE $table_name ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT, type ENUM('psychological', 'career') NOT NULL, questions_count INT DEFAULT 0, time_estimate INT COMMENT '预计完成时间(分钟)', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, status ENUM('active', 'inactive', 'draft') DEFAULT 'draft' ) $charset_collate;"; dbDelta($sql); // 类似创建其他表... // 添加默认测评数据 assessment_tools_add_default_data(); } register_activation_hook(__FILE__, 'assessment_tools_install_tables');
-
- 使用HTML5、CSS3和JavaScript创建现代化测评界面: <!-- 测评容器模板 --> <div class="assessment-container" id="assessment-container"> <!-- 进度指示器 --> <div class="assessment-progress"> <div class="progress-bar"> <div class="progress-fill" id="progress-fill"></div> </div> <div class="progress-text"> 问题 <span id="current-question">1</span> / <span id="total-questions">10</span> </div> </div> <!-- 问题展示区 --> <div class="question-container"> <h2 class="question-title" id="question-title"></h2> <div class="question-options" id="question-options"></div> </div> <!-- 导航按钮 --> <div class="assessment-navigation"> <button class="btn btn-secondary" id="prev-btn">上一题</button> <button class="btn btn-primary" id="next-btn">下一题</button> <button class="btn btn-success" id="submit-btn" style="display:none;">提交测评</button> </div> </div> <!-- 结果展示模态框 --> <div class="modal fade" id="result-modal" tabindex="-1"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">测评结果</h5> </div> <div class="modal-body" id="result-content"> <!-- 结果内容将通过AJAX加载 --> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="download-report">下载报告</button> </div> </div> </div> </div>
- 使用JavaScript实现测评流程控制: // 测评状态管理 class AssessmentManager { constructor(questionnaireId) { this.questionnaireId = questionnaireId; this.currentQuestionIndex = 0; this.questions = []; this.answers = {}; this.isLoading = false; this.init(); } async init() { await this.loadQuestions(); this.renderQuestion(); this.setupEventListeners(); } async loadQuestions() { try { const response = await fetch( `/wp-json/assessment/v1/questions/${this.questionnaireId}` ); this.questions = await response.json(); this.updateProgress(); } catch (error) { console.error('加载问题失败:', error); } } renderQuestion() { if (this.questions.length === 0) return; const question = this.questions[this.currentQuestionIndex]; document.getElementById('question-title').textContent = question.text; const optionsContainer = document.getElementById('question-options'); optionsContainer.innerHTML = ''; // 根据问题类型渲染不同选项 switch(question.type) { case 'single_choice': this.renderSingleChoiceOptions(question, optionsContainer); break; case 'likert_scale': this.renderLikertScaleOptions(question, optionsContainer); break; // 其他类型处理... } this.updateNavigationButtons(); } renderSingleChoiceOptions(question, container) { question.options.forEach((option, index) => { const optionId = `option-${index}`; const isChecked = this.answers[question.id] === option.value; const optionElement = document.createElement('div'); optionElement.className = 'form-check'; optionElement.innerHTML = ` <input class="form-check-input" type="radio" name="question-${question.id}" id="${optionId}" value="${option.value}" ${isChecked ? 'checked' : ''}> <label class="form-check-label" for="${optionId}"> ${option.text} </label> `; container.appendChild(optionElement); }); } updateNavigationButtons() { const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); const submitBtn = document.getElementById('submit-btn'); prevBtn.disabled = this.currentQuestionIndex === 0; if (this.currentQuestionIndex === this.questions.length - 1) { nextBtn.style.display = 'none'; submitBtn.style.display = 'inline-block'; } else { nextBtn.style.display = 'inline-block'; submitBtn.style.display = 'none'; } } setupEventListeners() { document.getElementById('prev-btn').addEventListener('click', () => { if (this.currentQuestionIndex > 0) { this.saveCurrentAnswer(); this.currentQuestionIndex--; this.renderQuestion(); this.updateProgress(); } }); document.getElementById('next-btn').addEventListener('click', () => { if (this.validateCurrentAnswer()) { this.saveCurrentAnswer(); this.currentQuestionIndex++; this.renderQuestion(); this.updateProgress(); } }); document.getElementById('submit-btn').addEventListener('click', () => { this.submitAssessment(); }); } saveCurrentAnswer() { const question = this.questions[this.currentQuestionIndex]; const selectedOption = document.querySelector( `input[name="question-${question.id}"]:checked` ); if (selectedOption) { this.answers[question.id] = selectedOption.value; } } async submitAssessment() { this.saveCurrentAnswer(); const submissionData = { questionnaire_id: this.questionnaireId, answers: this.answers, user_id: window.currentUserId || 0 }; try { const response = await fetch('/wp-json/assessment/v1/submit', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': window.wpApiSettings.nonce }, body: JSON.stringify(submissionData) }); const result = await response.json(); this.showResults(result); } catch (error) { console.error('提交失败:', error); alert('提交失败,请稍后重试'); } } showResults(resultData) { // 显示结果模态框 const modal = new bootstrap.Modal(document.getElementById('result-modal')); document.getElementById('result-content').innerHTML = this.formatResults(resultData); modal.show(); } formatResults(resultData) { // 根据测评类型格式化结果 let html = `<h3>${resultData.title}</h3>`; html += `<div class="score-section">得分: ${resultData.score}/100</div>`; html += `<div class="interpretation">${resultData.interpretation}</div>`; if (resultData.recommendations) { html += `<h4>建议与推荐</h4><ul>`; resultData.recommendations.forEach(rec => { html += `<li>${rec}</li>`; }); html += `</ul>`; } return html; } updateProgress() { const progress = ((this.currentQuestionIndex + 1) / this.questions.length) * 100; document.getElementById('progress-fill').style.width = `${progress}%`; document.getElementById('current-question').textContent = this.currentQuestionIndex + 1; document.getElementById('total-questions').textContent = this.questions.length; } } // 初始化测评管理器 document.addEventListener('DOMContentLoaded', function() { const questionnaireId = document.getElementById('assessment-container').dataset.questionnaireId; window.assessmentManager = new AssessmentManager(questionnaireId); });
-
- // 心理测评评分系统 class PsychologicalAssessmentScorer { /** * 计算测评得分 */ public static function calculateScore($questionnaire_id, $answers) { global $wpdb; // 获取测评的评分规则 $scoring_rules = self::getScoringRules($questionnaire_id); $total_score = 0; $dimension_scores = []; $max_possible_score = 0; foreach ($answers as $question_id => $answer_value) { // 获取问题信息 $question = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}assessment_questions WHERE id = %d", $question_id )); if (!$question) continue; // 解析问题选项 $options = json_decode($question->options, true); // 根据问题类型计算得分 $question_score = self::calculateQuestionScore( $question->question_type, $answer_value, $options, $scoring_rules ); $total_score += $question_score; // 记录维度得分(如果问题属于特定维度) if (!empty($question->dimension)) { $dimension = $question->dimension; if (!isset($dimension_scores[$dimension])) { $dimension_scores[$dimension] = [ 'score' => 0, 'count' => 0 ]; } $dimension_scores[$dimension]['score'] += $question_score; $dimension_scores[$dimension]['count']++; } // 计算最大可能得分 $max_possible_score += self::getMaxQuestionScore($question, $options); } // 计算百分比得分 $percentage_score = $max_possible_score > 0 ? round(($total_score / $max_possible_score) * 100, 1) : 0; // 计算维度平均分 foreach ($dimension_scores as $dimension => &$data) { $data['average'] = $data['count'] > 0 ? round($data['score'] / $data['count'], 2) : 0; } return [ 'total_score' => $total_score, 'percentage_score' => $percentage_score, 'dimension_scores' => $dimension_scores, 'max_possible_score' => $max_possible_score ]; } /** * 根据问题类型计算单个问题得分 */ private static function calculateQuestionScore($question_type, $answer_value, $options, $scoring_rules) { switch ($question_type) { case 'single_choice': return self::scoreSingleChoice($answer_value, $options); case 'likert_scale': return self::scoreLikertScale($answer_value, $options); case 'multiple_choice': return self::scoreMultipleChoice($answer_value, $options); default: return 0; } } /** * 单选题评分 */ private static function scoreSingleChoice($answer_value, $options) { foreach ($options as $option) { if ($option['value'] == $answer_value) { return isset($option['score']) ? (int)$option['score'] : 0; } } return 0; } /** * 李克特量表评分 */ private static function scoreLikertScale($answer_value, $options) { // 李克特量表通常为1-5分或1-7分 $score_map = [ 'strongly_disagree' => 1, 'disagree' => 2, 'neutral' => 3, 'agree' => 4, 'strongly_agree' => 5 ]; return isset($score_map[$answer_value]) ? $score_map[$answer_value] : 3; } /** * 获取评分规则 */ private static function getScoringRules($questionnaire_id) { // 从数据库或配置文件中获取评分规则 $rules = [ 'depression_scale' => [ 'ranges' => [ ['min' => 0, 'max' => 4, 'level' => 'normal', 'interpretation' => '无抑郁症状'], ['min' => 5, 'max' => 9, 'level' => 'mild', 'interpretation' => '轻度抑郁'], ['min' => 10, 'max' => 14, 'level' => 'moderate', 'interpretation' => '中度抑郁'], ['min' => 15, 'max' => 19, 'level' => 'severe', 'interpretation' => '中重度抑郁'], ['min' => 20, 'max' => 27, 'level' => 'extreme', 'interpretation' => '重度抑郁'] ] ], // 其他测评的评分规则... ]; return $rules; } }
- // 霍兰德职业兴趣测评系统 class HollandCareerAnalyzer { // 霍兰德六种人格类型 const HOLLAND_TYPES = ['R', 'I', 'A', 'S', 'E', 'C']; // 类型描述 const TYPE_DESCRIPTIONS = [ 'R' => ['name' => '现实型', 'traits' => ['动手能力强', '喜欢具体任务', '实际', '稳定']], 'I' => ['name' => '研究型', 'traits' => ['分析能力强', '喜欢思考', '独立', '好奇']], 'A' => ['name' => '艺术型', 'traits' => ['创造力强', '喜欢表达', '独立', '理想化']], 'S' => ['name' => '社会型', 'traits' => ['善于沟通', '喜欢帮助他人', '友善', '合作']], 'E' => ['name' => '企业型', 'traits' => ['领导能力强', '喜欢影响他人', '自信', '冒险']], 'C' => ['name' => '常规型', 'traits' => ['注重细节', '喜欢有序', '谨慎', '高效']] ]; // 职业代码对应表 const CAREER_CODES = [ 'RIA' => ['机械工程师', '电子工程师', '技术员'], 'RIS' => ['外科医生', '牙医', '兽医'], 'RIE' => ['建筑师', '土木工程师', '制图员'], 'RSE' => ['消防员', '警察', '保安'], 'RSC' => ['理发师', '厨师', '工匠'], 'RAI' => ['摄影师', '音乐家', '画家'], 'RCE' => ['司机', '操作员', '装配工'], 'IAS' => ['心理学家', '社会学家', '人类学家'], 'IAR' => ['数学家', '物理学家', '天文学家'], 'ISC' => ['医生', '药剂师', '营养师'], 'ISR' => ['生物学家', '化学家', '地质学家'], 'IRA' => ['计算机科学家', '统计学家', '系统分析师'], 'IRE' => ['工程师', '技术专家', '研究员'], 'AIC' => ['作家', '编辑', '记者'], 'AIR' => ['作曲家', '指挥家', '音乐教师'], 'AIS' => ['演员', '导演', '舞蹈家'], 'ASE' => ['设计师', '艺术指导', '创意总监'], 'ASC' => ['广告经理', '公关专员', '活动策划'], 'AEI' => ['艺术家', '摄影师', '插画师'], 'AER' => ['建筑师', '室内设计师', '景观设计师'], 'SEC' => ['教师', '辅导员', '社工'], 'SEI' => ['护士', '理疗师', '营养师'], 'SER' => ['教练', '健身指导', '体育教师'], 'SEA' => ['心理咨询师', '职业顾问', '人力资源'], 'SAC' => ['销售员', '客户服务', '接待员'], 'SAI' => ['教师', '培训师', '教育顾问'], 'ECI' => ['经理', '主管', '执行官'], 'ECS' => ['销售经理', '市场经理', '业务经理'], 'ERI' => ['企业家', '投资人', '商业顾问'], 'ERA' => ['项目经理', '产品经理', '运营经理'], 'ESC' => ['行政主管', '办公室主任', '秘书'], 'ESR' => ['零售经理', '酒店经理', '餐厅经理'], 'CRI' => ['会计师', '审计师', '财务分析师'], 'CRA' => ['图书管理员', '档案管理员', '数据录入员'], 'CRE' => ['银行职员', '税务专员', '保险代理'], 'CSE' => ['行政助理', '文员', '接待员'], 'CSR' => ['客服代表', '技术支持', '电话销售'], 'CSI' => ['计算机操作员', '数据管理员', '统计员'] ]; /** * 分析霍兰德代码 */ public static function analyzeHollandCode($scores) { // 按得分排序 arsort($scores); // 获取前三高的类型代码 $top_three = array_slice(array_keys($scores), 0, 3); // 生成霍兰德三字代码 $holland_code = implode('', $top_three); // 获取类型描述 $type_descriptions = []; foreach ($top_three as $type) { if (isset(self::TYPE_DESCRIPTIONS[$type])) { $type_descriptions[$type] = self::TYPE_DESCRIPTIONS[$type]; } } // 获取推荐职业 $recommended_careers = self::getRecommendedCareers($holland_code); // 生成分析报告 $analysis = self::generateAnalysisReport($holland_code, $scores, $type_descriptions, $recommended_careers); return $analysis; } /** * 获取推荐职业 */ private static function getRecommendedCareers($holland_code) { $careers = []; // 精确匹配 if (isset(self::CAREER_CODES[$holland_code])) { $careers = self::CAREER_CODES[$holland_code]; } else { // 模糊匹配:尝试前两个字母匹配 $partial_code = substr($holland_code, 0, 2); foreach (self::CAREER_CODES as $code => $career_list) { if (strpos($code, $partial_code) === 0) { $careers = array_merge($careers, $career_list); } } // 如果还是没有匹配,返回通用职业建议 if (empty($careers)) { $careers = self::getGeneralCareers($holland_code); } } // 去重并限制数量 $careers = array_unique($careers); return array_slice($careers, 0, 10); } /** * 生成分析报告 */ private static function generateAnalysisReport($holland_code, $scores, $type_descriptions, $recommended_careers) { $report = [ 'holland_code' => $holland_code, 'primary_type' => [ 'code' => $holland_code[0], 'name' => $type_descriptions[$holland_code[0]]['name'] ?? '', 'description' => '这是您最突出的职业兴趣类型。', 'traits' => $type_descriptions[$holland_code[0]]['traits'] ?? [] ], 'secondary_type' => [ 'code' => $holland_code[1], 'name' => $type_descriptions[$holland_code[1]]['name'] ?? '', 'description' => '这是您的次要职业兴趣类型。', 'traits' => $type_descriptions[$holland_code[1]]['traits'] ?? [] ], 'tertiary_type' => [ 'code' => $holland_code[2], 'name' => $type_descriptions[$holland_code[2]]['name'] ?? '', 'description' => '这是您的第三职业兴趣类型。', 'traits' => $type_descriptions[$holland_code[2]]['traits'] ?? [] ], 'score_distribution' => $scores, 'career_recommendations' => $recommended_careers, 'interpretation' => self::generateInterpretation($holland_code, $scores), 'development_suggestions' => self::getDevelopmentSuggestions($holland_code) ]; return $report; } /** * 生成个性化解读 */ private static function generateInterpretation($holland_code, $scores) { $interpretations = [ 'R' => '您喜欢动手操作,倾向于从事技术性、机械性的工作。', 'I' => '您善于思考分析,适合研究型、探索性的工作环境。', 'A' => '您富有创造力,适合在艺术、设计等需要创新的领域发展。', 'S' => '您乐于助人,擅长人际交往,适合教育、服务等行业。', 'E' => '您具有领导才能,适合管理、销售等需要影响力的工作。', 'C' => '您注重细节和秩序,适合行政、财务等需要精确性的工作。' ]; $primary = $holland_code[0]; $secondary = $holland_code[1]; $text = "根据测评结果,您的霍兰德职业代码是<strong>{$holland_code}</strong>。"; $text .= "这表明您的主要职业兴趣是{$interpretations[$primary]}"; $text .= "同时,您还具有{$interpretations[$secondary]}的特点。"; // 添加组合类型的特殊解读 $combination_interpretations = [ 'RIS' => '您兼具研究精神和动手能力,适合医疗、科研等技术性工作。', 'ASE' => '您的创造力和社交能力结合,适合创意产业和市场营销。', 'SEC' => '您的服务精神和细致特点,适合教育、行政等支持性工作。', 'EIC' => '您的领导力、分析能力和条理性结合,适合管理和咨询工作。' ]; if (isset($combination_interpretations[$holland_code])) { $text .= " " . $combination_interpretations[$holland_code]; } return $text; } }
在当今数字化时代,网站已不仅仅是信息展示平台,更是用户互动与价值传递的重要载体。对于教育机构、职业咨询平台、人力资源网站或企业招聘门户而言,集成专业的心理测评与职业倾向分析工具能够显著提升用户体验和网站价值。
通过WordPress这一全球最流行的内容管理系统,我们可以通过代码二次开发实现这些功能,而无需依赖昂贵的第三方服务。本教程将详细指导您如何从零开始,为您的WordPress网站集成专业的在线心理测评与职业倾向分析工具,同时确保数据安全、用户体验和系统稳定性。
在开始开发之前,我们需要明确技术需求:
- WordPress版本:5.0或更高(推荐最新版本)
- PHP版本:7.4或更高(推荐8.0+)
- MySQL版本:5.6或更高
- 服务器内存:至少512MB(推荐1GB以上)
- 必要的WordPress权限:主题编辑、插件安装、文件上传
为了安全地进行开发,建议首先在本地或测试服务器搭建环境:
-
本地开发环境选择:
- XAMPP(Windows/Mac/Linux)
- Local by Flywheel(特别适合WordPress开发)
- Docker WordPress开发环境
-
测试服务器配置:
# 示例:通过SSH配置测试服务器环境 sudo apt update sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql sudo systemctl restart apache2 -
WordPress安装与基础配置:
- 下载最新WordPress版本
- 创建数据库和用户
- 完成五步安装流程
- 设置固定链接结构(推荐"文章名"格式)
在进行任何代码修改前,必须建立完整备份:
-
数据库备份:
-- 通过phpMyAdmin或命令行备份 mysqldump -u username -p database_name > backup_date.sql -
文件备份:
# 备份整个WordPress目录 tar -czf wordpress_backup_date.tar.gz /path/to/wordpress -
使用备份插件:
- UpdraftPlus
- BackWPup
- Duplicator(特别适合迁移)
我们需要设计两种主要测评类型:
- 心理测评:包含人格测试、情绪评估、压力测试等
- 职业倾向分析:基于霍兰德职业兴趣理论、MBTI等经典模型
在WordPress数据库中添加自定义表来存储测评数据:
-- 测评问卷表
CREATE TABLE wp_assessment_questionnaires (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
type ENUM('psychological', 'career') NOT NULL,
questions_count INT DEFAULT 0,
time_estimate INT COMMENT '预计完成时间(分钟)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
status ENUM('active', 'inactive', 'draft') DEFAULT 'draft'
);
-- 测评问题表
CREATE TABLE wp_assessment_questions (
id INT AUTO_INCREMENT PRIMARY KEY,
questionnaire_id INT NOT NULL,
question_text TEXT NOT NULL,
question_type ENUM('single_choice', 'multiple_choice', 'likert_scale', 'open_ended') NOT NULL,
options JSON COMMENT 'JSON格式存储选项',
sort_order INT DEFAULT 0,
FOREIGN KEY (questionnaire_id) REFERENCES wp_assessment_questionnaires(id) ON DELETE CASCADE
);
-- 测评结果表
CREATE TABLE wp_assessment_results (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT(20) UNSIGNED,
questionnaire_id INT NOT NULL,
answers JSON NOT NULL COMMENT '用户答案JSON',
score_data JSON COMMENT '得分与解析JSON',
completed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ip_address VARCHAR(45),
session_id VARCHAR(255),
FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE SET NULL,
FOREIGN KEY (questionnaire_id) REFERENCES wp_assessment_questionnaires(id) ON DELETE CASCADE
);
-- 职业倾向分析结果表
CREATE TABLE wp_career_analysis (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT(20) UNSIGNED,
holland_code CHAR(3) COMMENT '霍兰德代码如RIA, SEC等',
mbti_type VARCHAR(4) COMMENT 'MBTI类型如INTJ, ENFP等',
strengths TEXT COMMENT '优势分析',
career_suggestions JSON COMMENT '职业建议',
analysis_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES wp_users(ID) ON DELETE SET NULL
);
在插件或主题中注册自定义表:
// 在插件激活时创建表
function assessment_tools_install_tables() {
global $wpdb;
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
// 获取字符集和排序规则
$charset_collate = $wpdb->get_charset_collate();
// 创建问卷表
$table_name = $wpdb->prefix . 'assessment_questionnaires';
$sql = "CREATE TABLE $table_name (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
type ENUM('psychological', 'career') NOT NULL,
questions_count INT DEFAULT 0,
time_estimate INT COMMENT '预计完成时间(分钟)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
status ENUM('active', 'inactive', 'draft') DEFAULT 'draft'
) $charset_collate;";
dbDelta($sql);
// 类似创建其他表...
// 添加默认测评数据
assessment_tools_add_default_data();
}
register_activation_hook(__FILE__, 'assessment_tools_install_tables');
使用HTML5、CSS3和JavaScript创建现代化测评界面:
<!-- 测评容器模板 -->
<div class="assessment-container" id="assessment-container">
<!-- 进度指示器 -->
<div class="assessment-progress">
<div class="progress-bar">
<div class="progress-fill" id="progress-fill"></div>
</div>
<div class="progress-text">
问题 <span id="current-question">1</span> / <span id="total-questions">10</span>
</div>
</div>
<!-- 问题展示区 -->
<div class="question-container">
<h2 class="question-title" id="question-title"></h2>
<div class="question-options" id="question-options"></div>
</div>
<!-- 导航按钮 -->
<div class="assessment-navigation">
<button class="btn btn-secondary" id="prev-btn">上一题</button>
<button class="btn btn-primary" id="next-btn">下一题</button>
<button class="btn btn-success" id="submit-btn" style="display:none;">提交测评</button>
</div>
</div>
<!-- 结果展示模态框 -->
<div class="modal fade" id="result-modal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">测评结果</h5>
</div>
<div class="modal-body" id="result-content">
<!-- 结果内容将通过AJAX加载 -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="download-report">下载报告</button>
</div>
</div>
</div>
</div>
使用JavaScript实现测评流程控制:
// 测评状态管理
class AssessmentManager {
constructor(questionnaireId) {
this.questionnaireId = questionnaireId;
this.currentQuestionIndex = 0;
this.questions = [];
this.answers = {};
this.isLoading = false;
this.init();
}
async init() {
await this.loadQuestions();
this.renderQuestion();
this.setupEventListeners();
}
async loadQuestions() {
try {
const response = await fetch(
`/wp-json/assessment/v1/questions/${this.questionnaireId}`
);
this.questions = await response.json();
this.updateProgress();
} catch (error) {
console.error('加载问题失败:', error);
}
}
renderQuestion() {
if (this.questions.length === 0) return;
const question = this.questions[this.currentQuestionIndex];
document.getElementById('question-title').textContent = question.text;
const optionsContainer = document.getElementById('question-options');
optionsContainer.innerHTML = '';
// 根据问题类型渲染不同选项
switch(question.type) {
case 'single_choice':
this.renderSingleChoiceOptions(question, optionsContainer);
break;
case 'likert_scale':
this.renderLikertScaleOptions(question, optionsContainer);
break;
// 其他类型处理...
}
this.updateNavigationButtons();
}
renderSingleChoiceOptions(question, container) {
question.options.forEach((option, index) => {
const optionId = `option-${index}`;
const isChecked = this.answers[question.id] === option.value;
const optionElement = document.createElement('div');
optionElement.className = 'form-check';
optionElement.innerHTML = `
<input class="form-check-input" type="radio"
name="question-${question.id}"
id="${optionId}"
value="${option.value}"
${isChecked ? 'checked' : ''}>
<label class="form-check-label" for="${optionId}">
${option.text}
</label>
`;
container.appendChild(optionElement);
});
}
updateNavigationButtons() {
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const submitBtn = document.getElementById('submit-btn');
prevBtn.disabled = this.currentQuestionIndex === 0;
if (this.currentQuestionIndex === this.questions.length - 1) {
nextBtn.style.display = 'none';
submitBtn.style.display = 'inline-block';
} else {
nextBtn.style.display = 'inline-block';
submitBtn.style.display = 'none';
}
}
setupEventListeners() {
document.getElementById('prev-btn').addEventListener('click', () => {
if (this.currentQuestionIndex > 0) {
this.saveCurrentAnswer();
this.currentQuestionIndex--;
this.renderQuestion();
this.updateProgress();
}
});
document.getElementById('next-btn').addEventListener('click', () => {
if (this.validateCurrentAnswer()) {
this.saveCurrentAnswer();
this.currentQuestionIndex++;
this.renderQuestion();
this.updateProgress();
}
});
document.getElementById('submit-btn').addEventListener('click', () => {
this.submitAssessment();
});
}
saveCurrentAnswer() {
const question = this.questions[this.currentQuestionIndex];
const selectedOption = document.querySelector(
`input[name="question-${question.id}"]:checked`
);
if (selectedOption) {
this.answers[question.id] = selectedOption.value;
}
}
async submitAssessment() {
this.saveCurrentAnswer();
const submissionData = {
questionnaire_id: this.questionnaireId,
answers: this.answers,
user_id: window.currentUserId || 0
};
try {
const response = await fetch('/wp-json/assessment/v1/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': window.wpApiSettings.nonce
},
body: JSON.stringify(submissionData)
});
const result = await response.json();
this.showResults(result);
} catch (error) {
console.error('提交失败:', error);
alert('提交失败,请稍后重试');
}
}
showResults(resultData) {
// 显示结果模态框
const modal = new bootstrap.Modal(document.getElementById('result-modal'));
document.getElementById('result-content').innerHTML = this.formatResults(resultData);
modal.show();
}
formatResults(resultData) {
// 根据测评类型格式化结果
let html = `<h3>${resultData.title}</h3>`;
html += `<div class="score-section">得分: ${resultData.score}/100</div>`;
html += `<div class="interpretation">${resultData.interpretation}</div>`;
if (resultData.recommendations) {
html += `<h4>建议与推荐</h4><ul>`;
resultData.recommendations.forEach(rec => {
html += `<li>${rec}</li>`;
});
html += `</ul>`;
}
return html;
}
updateProgress() {
const progress = ((this.currentQuestionIndex + 1) / this.questions.length) * 100;
document.getElementById('progress-fill').style.width = `${progress}%`;
document.getElementById('current-question').textContent = this.currentQuestionIndex + 1;
document.getElementById('total-questions').textContent = this.questions.length;
}
}
// 初始化测评管理器
document.addEventListener('DOMContentLoaded', function() {
const questionnaireId = document.getElementById('assessment-container').dataset.questionnaireId;
window.assessmentManager = new AssessmentManager(questionnaireId);
});
在WordPress中注册自定义REST API端点:
// 注册测评相关REST API
add_action('rest_api_init', function() {
// 获取测评列表
register_rest_route('assessment/v1', '/questionnaires', [
'methods' => 'GET',
'callback' => 'get_questionnaires',
'permission_callback' => function() {
return current_user_can('read');
}
]);
// 获取特定测评的问题
register_rest_route('assessment/v1', '/questions/(?P<id>d+)', [
'methods' => 'GET',
'callback' => 'get_questions_by_questionnaire',
'permission_callback' => function() {
return true; // 公开访问
}
]);
// 提交测评答案
register_rest_route('assessment/v1', '/submit', [
'methods' => 'POST',
'callback' => 'submit_assessment',
'permission_callback' => function() {
return true; // 允许非登录用户提交
}
]);
// 获取测评结果
register_rest_route('assessment/v1', '/results/(?P<id>d+)', [
'methods' => 'GET',
'callback' => 'get_assessment_result',
'permission_callback' => function($request) {
// 验证用户只能访问自己的结果
$result_id = $request->get_param('id');
return can_user_access_result($result_id);
}
]);
});
// 获取测评列表
function get_questionnaires($request) {
global $wpdb;
$table_name = $wpdb->prefix . 'assessment_questionnaires';
$status = $request->get_param('status') ?: 'active';
$type = $request->get_param('type');
$query = "SELECT * FROM $table_name WHERE status = %s";
$params = [$status];
if ($type) {
$query .= " AND type = %s";
$params[] = $type;
}
$query .= " ORDER BY created_at DESC";
$results = $wpdb->get_results($wpdb->prepare($query, $params));
return rest_ensure_response($results);
}
// 获取测评问题
function get_questions_by_questionnaire($request) {
$questionnaire_id = $request->get_param('id');
global $wpdb;
$questions_table = $wpdb->prefix . 'assessment_questions';
$questions = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $questions_table
WHERE questionnaire_id = %d
ORDER BY sort_order ASC",
$questionnaire_id
));
// 处理选项JSON
foreach ($questions as &$question) {
if ($question->options) {
$question->options = json_decode($question->options);
}
}
return rest_ensure_response($questions);
}
// 提交测评处理
function submit_assessment($request) {
$data = $request->get_json_params();
// 验证数据
if (empty($data['questionnaire_id']) || empty($data['answers'])) {
return new WP_Error('invalid_data', '无效的提交数据', ['status' => 400]);
}
global $wpdb;
// 获取用户ID(如果已登录)
$user_id = is_user_logged_in() ? get_current_user_id() : 0;
// 获取问卷信息
$questionnaire = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}assessment_questionnaires WHERE id = %d",
$data['questionnaire_id']
));
if (!$questionnaire) {
return new WP_Error('not_found', '测评不存在', ['status' => 404]);
// 心理测评评分系统
class PsychologicalAssessmentScorer {
/**
* 计算测评得分
*/
public static function calculateScore($questionnaire_id, $answers) {
global $wpdb;
// 获取测评的评分规则
$scoring_rules = self::getScoringRules($questionnaire_id);
$total_score = 0;
$dimension_scores = [];
$max_possible_score = 0;
foreach ($answers as $question_id => $answer_value) {
// 获取问题信息
$question = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}assessment_questions WHERE id = %d",
$question_id
));
if (!$question) continue;
// 解析问题选项
$options = json_decode($question->options, true);
// 根据问题类型计算得分
$question_score = self::calculateQuestionScore(
$question->question_type,
$answer_value,
$options,
$scoring_rules
);
$total_score += $question_score;
// 记录维度得分(如果问题属于特定维度)
if (!empty($question->dimension)) {
$dimension = $question->dimension;
if (!isset($dimension_scores[$dimension])) {
$dimension_scores[$dimension] = [
'score' => 0,
'count' => 0
];
}
$dimension_scores[$dimension]['score'] += $question_score;
$dimension_scores[$dimension]['count']++;
}
// 计算最大可能得分
$max_possible_score += self::getMaxQuestionScore($question, $options);
}
// 计算百分比得分
$percentage_score = $max_possible_score > 0 ?
round(($total_score / $max_possible_score) * 100, 1) : 0;
// 计算维度平均分
foreach ($dimension_scores as $dimension => &$data) {
$data['average'] = $data['count'] > 0 ?
round($data['score'] / $data['count'], 2) : 0;
}
return [
'total_score' => $total_score,
'percentage_score' => $percentage_score,
'dimension_scores' => $dimension_scores,
'max_possible_score' => $max_possible_score
];
}
/**
* 根据问题类型计算单个问题得分
*/
private static function calculateQuestionScore($question_type, $answer_value, $options, $scoring_rules) {
switch ($question_type) {
case 'single_choice':
return self::scoreSingleChoice($answer_value, $options);
case 'likert_scale':
return self::scoreLikertScale($answer_value, $options);
case 'multiple_choice':
return self::scoreMultipleChoice($answer_value, $options);
default:
return 0;
}
}
/**
* 单选题评分
*/
private static function scoreSingleChoice($answer_value, $options) {
foreach ($options as $option) {
if ($option['value'] == $answer_value) {
return isset($option['score']) ? (int)$option['score'] : 0;
}
}
return 0;
}
/**
* 李克特量表评分
*/
private static function scoreLikertScale($answer_value, $options) {
// 李克特量表通常为1-5分或1-7分
$score_map = [
'strongly_disagree' => 1,
'disagree' => 2,
'neutral' => 3,
'agree' => 4,
'strongly_agree' => 5
];
return isset($score_map[$answer_value]) ? $score_map[$answer_value] : 3;
}
/**
* 获取评分规则
*/
private static function getScoringRules($questionnaire_id) {
// 从数据库或配置文件中获取评分规则
$rules = [
'depression_scale' => [
'ranges' => [
['min' => 0, 'max' => 4, 'level' => 'normal', 'interpretation' => '无抑郁症状'],
['min' => 5, 'max' => 9, 'level' => 'mild', 'interpretation' => '轻度抑郁'],
['min' => 10, 'max' => 14, 'level' => 'moderate', 'interpretation' => '中度抑郁'],
['min' => 15, 'max' => 19, 'level' => 'severe', 'interpretation' => '中重度抑郁'],
['min' => 20, 'max' => 27, 'level' => 'extreme', 'interpretation' => '重度抑郁']
]
],
// 其他测评的评分规则...
];
return $rules;
}
}
// 心理测评评分系统
class PsychologicalAssessmentScorer {
/**
* 计算测评得分
*/
public static function calculateScore($questionnaire_id, $answers) {
global $wpdb;
// 获取测评的评分规则
$scoring_rules = self::getScoringRules($questionnaire_id);
$total_score = 0;
$dimension_scores = [];
$max_possible_score = 0;
foreach ($answers as $question_id => $answer_value) {
// 获取问题信息
$question = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}assessment_questions WHERE id = %d",
$question_id
));
if (!$question) continue;
// 解析问题选项
$options = json_decode($question->options, true);
// 根据问题类型计算得分
$question_score = self::calculateQuestionScore(
$question->question_type,
$answer_value,
$options,
$scoring_rules
);
$total_score += $question_score;
// 记录维度得分(如果问题属于特定维度)
if (!empty($question->dimension)) {
$dimension = $question->dimension;
if (!isset($dimension_scores[$dimension])) {
$dimension_scores[$dimension] = [
'score' => 0,
'count' => 0
];
}
$dimension_scores[$dimension]['score'] += $question_score;
$dimension_scores[$dimension]['count']++;
}
// 计算最大可能得分
$max_possible_score += self::getMaxQuestionScore($question, $options);
}
// 计算百分比得分
$percentage_score = $max_possible_score > 0 ?
round(($total_score / $max_possible_score) * 100, 1) : 0;
// 计算维度平均分
foreach ($dimension_scores as $dimension => &$data) {
$data['average'] = $data['count'] > 0 ?
round($data['score'] / $data['count'], 2) : 0;
}
return [
'total_score' => $total_score,
'percentage_score' => $percentage_score,
'dimension_scores' => $dimension_scores,
'max_possible_score' => $max_possible_score
];
}
/**
* 根据问题类型计算单个问题得分
*/
private static function calculateQuestionScore($question_type, $answer_value, $options, $scoring_rules) {
switch ($question_type) {
case 'single_choice':
return self::scoreSingleChoice($answer_value, $options);
case 'likert_scale':
return self::scoreLikertScale($answer_value, $options);
case 'multiple_choice':
return self::scoreMultipleChoice($answer_value, $options);
default:
return 0;
}
}
/**
* 单选题评分
*/
private static function scoreSingleChoice($answer_value, $options) {
foreach ($options as $option) {
if ($option['value'] == $answer_value) {
return isset($option['score']) ? (int)$option['score'] : 0;
}
}
return 0;
}
/**
* 李克特量表评分
*/
private static function scoreLikertScale($answer_value, $options) {
// 李克特量表通常为1-5分或1-7分
$score_map = [
'strongly_disagree' => 1,
'disagree' => 2,
'neutral' => 3,
'agree' => 4,
'strongly_agree' => 5
];
return isset($score_map[$answer_value]) ? $score_map[$answer_value] : 3;
}
/**
* 获取评分规则
*/
private static function getScoringRules($questionnaire_id) {
// 从数据库或配置文件中获取评分规则
$rules = [
'depression_scale' => [
'ranges' => [
['min' => 0, 'max' => 4, 'level' => 'normal', 'interpretation' => '无抑郁症状'],
['min' => 5, 'max' => 9, 'level' => 'mild', 'interpretation' => '轻度抑郁'],
['min' => 10, 'max' => 14, 'level' => 'moderate', 'interpretation' => '中度抑郁'],
['min' => 15, 'max' => 19, 'level' => 'severe', 'interpretation' => '中重度抑郁'],
['min' => 20, 'max' => 27, 'level' => 'extreme', 'interpretation' => '重度抑郁']
]
],
// 其他测评的评分规则...
];
return $rules;
}
}
// 霍兰德职业兴趣测评系统
class HollandCareerAnalyzer {
// 霍兰德六种人格类型
const HOLLAND_TYPES = ['R', 'I', 'A', 'S', 'E', 'C'];
// 类型描述
const TYPE_DESCRIPTIONS = [
'R' => ['name' => '现实型', 'traits' => ['动手能力强', '喜欢具体任务', '实际', '稳定']],
'I' => ['name' => '研究型', 'traits' => ['分析能力强', '喜欢思考', '独立', '好奇']],
'A' => ['name' => '艺术型', 'traits' => ['创造力强', '喜欢表达', '独立', '理想化']],
'S' => ['name' => '社会型', 'traits' => ['善于沟通', '喜欢帮助他人', '友善', '合作']],
'E' => ['name' => '企业型', 'traits' => ['领导能力强', '喜欢影响他人', '自信', '冒险']],
'C' => ['name' => '常规型', 'traits' => ['注重细节', '喜欢有序', '谨慎', '高效']]
];
// 职业代码对应表
const CAREER_CODES = [
'RIA' => ['机械工程师', '电子工程师', '技术员'],
'RIS' => ['外科医生', '牙医', '兽医'],
'RIE' => ['建筑师', '土木工程师', '制图员'],
'RSE' => ['消防员', '警察', '保安'],
'RSC' => ['理发师', '厨师', '工匠'],
'RAI' => ['摄影师', '音乐家', '画家'],
'RCE' => ['司机', '操作员', '装配工'],
'IAS' => ['心理学家', '社会学家', '人类学家'],
'IAR' => ['数学家', '物理学家', '天文学家'],
'ISC' => ['医生', '药剂师', '营养师'],
'ISR' => ['生物学家', '化学家', '地质学家'],
'IRA' => ['计算机科学家', '统计学家', '系统分析师'],
'IRE' => ['工程师', '技术专家', '研究员'],
'AIC' => ['作家', '编辑', '记者'],
'AIR' => ['作曲家', '指挥家', '音乐教师'],
'AIS' => ['演员', '导演', '舞蹈家'],
'ASE' => ['设计师', '艺术指导', '创意总监'],
'ASC' => ['广告经理', '公关专员', '活动策划'],
'AEI' => ['艺术家', '摄影师', '插画师'],
'AER' => ['建筑师', '室内设计师', '景观设计师'],
'SEC' => ['教师', '辅导员', '社工'],
'SEI' => ['护士', '理疗师', '营养师'],
'SER' => ['教练', '健身指导', '体育教师'],
'SEA' => ['心理咨询师', '职业顾问', '人力资源'],
'SAC' => ['销售员', '客户服务', '接待员'],
'SAI' => ['教师', '培训师', '教育顾问'],
'ECI' => ['经理', '主管', '执行官'],
'ECS' => ['销售经理', '市场经理', '业务经理'],
'ERI' => ['企业家', '投资人', '商业顾问'],
'ERA' => ['项目经理', '产品经理', '运营经理'],
'ESC' => ['行政主管', '办公室主任', '秘书'],
'ESR' => ['零售经理', '酒店经理', '餐厅经理'],
'CRI' => ['会计师', '审计师', '财务分析师'],
'CRA' => ['图书管理员', '档案管理员', '数据录入员'],
'CRE' => ['银行职员', '税务专员', '保险代理'],
'CSE' => ['行政助理', '文员', '接待员'],
'CSR' => ['客服代表', '技术支持', '电话销售'],
'CSI' => ['计算机操作员', '数据管理员', '统计员']
];
/**
* 分析霍兰德代码
*/
public static function analyzeHollandCode($scores) {
// 按得分排序
arsort($scores);
// 获取前三高的类型代码
$top_three = array_slice(array_keys($scores), 0, 3);
// 生成霍兰德三字代码
$holland_code = implode('', $top_three);
// 获取类型描述
$type_descriptions = [];
foreach ($top_three as $type) {
if (isset(self::TYPE_DESCRIPTIONS[$type])) {
$type_descriptions[$type] = self::TYPE_DESCRIPTIONS[$type];
}
}
// 获取推荐职业
$recommended_careers = self::getRecommendedCareers($holland_code);
// 生成分析报告
$analysis = self::generateAnalysisReport($holland_code, $scores, $type_descriptions, $recommended_careers);
return $analysis;
}
/**
* 获取推荐职业
*/
private static function getRecommendedCareers($holland_code) {
$careers = [];
// 精确匹配
if (isset(self::CAREER_CODES[$holland_code])) {
$careers = self::CAREER_CODES[$holland_code];
} else {
// 模糊匹配:尝试前两个字母匹配
$partial_code = substr($holland_code, 0, 2);
foreach (self::CAREER_CODES as $code => $career_list) {
if (strpos($code, $partial_code) === 0) {
$careers = array_merge($careers, $career_list);
}
}
// 如果还是没有匹配,返回通用职业建议
if (empty($careers)) {
$careers = self::getGeneralCareers($holland_code);
}
}
// 去重并限制数量
$careers = array_unique($careers);
return array_slice($careers, 0, 10);
}
/**
* 生成分析报告
*/
private static function generateAnalysisReport($holland_code, $scores, $type_descriptions, $recommended_careers) {
$report = [
'holland_code' => $holland_code,
'primary_type' => [
'code' => $holland_code[0],
'name' => $type_descriptions[$holland_code[0]]['name'] ?? '',
'description' => '这是您最突出的职业兴趣类型。',
'traits' => $type_descriptions[$holland_code[0]]['traits'] ?? []
],
'secondary_type' => [
'code' => $holland_code[1],
'name' => $type_descriptions[$holland_code[1]]['name'] ?? '',
'description' => '这是您的次要职业兴趣类型。',
'traits' => $type_descriptions[$holland_code[1]]['traits'] ?? []
],
'tertiary_type' => [
'code' => $holland_code[2],
'name' => $type_descriptions[$holland_code[2]]['name'] ?? '',
'description' => '这是您的第三职业兴趣类型。',
'traits' => $type_descriptions[$holland_code[2]]['traits'] ?? []
],
'score_distribution' => $scores,
'career_recommendations' => $recommended_careers,
'interpretation' => self::generateInterpretation($holland_code, $scores),
'development_suggestions' => self::getDevelopmentSuggestions($holland_code)
];
return $report;
}
/**
* 生成个性化解读
*/
private static function generateInterpretation($holland_code, $scores) {
$interpretations = [
'R' => '您喜欢动手操作,倾向于从事技术性、机械性的工作。',
'I' => '您善于思考分析,适合研究型、探索性的工作环境。',
'A' => '您富有创造力,适合在艺术、设计等需要创新的领域发展。',
'S' => '您乐于助人,擅长人际交往,适合教育、服务等行业。',
'E' => '您具有领导才能,适合管理、销售等需要影响力的工作。',
'C' => '您注重细节和秩序,适合行政、财务等需要精确性的工作。'
];
$primary = $holland_code[0];
$secondary = $holland_code[1];
$text = "根据测评结果,您的霍兰德职业代码是<strong>{$holland_code}</strong>。";
$text .= "这表明您的主要职业兴趣是{$interpretations[$primary]}";
$text .= "同时,您还具有{$interpretations[$secondary]}的特点。";
// 添加组合类型的特殊解读
$combination_interpretations = [
'RIS' => '您兼具研究精神和动手能力,适合医疗、科研等技术性工作。',
'ASE' => '您的创造力和社交能力结合,适合创意产业和市场营销。',
'SEC' => '您的服务精神和细致特点,适合教育、行政等支持性工作。',
'EIC' => '您的领导力、分析能力和条理性结合,适合管理和咨询工作。'
];
if (isset($combination_interpretations[$holland_code])) {
$text .= " " . $combination_interpretations[$holland_code];
}
return $text;
}
}
// 霍兰德职业兴趣测评系统
class HollandCareerAnalyzer {
// 霍兰德六种人格类型
const HOLLAND_TYPES = ['R', 'I', 'A', 'S', 'E', 'C'];
// 类型描述
const TYPE_DESCRIPTIONS = [
'R' => ['name' => '现实型', 'traits' => ['动手能力强', '喜欢具体任务', '实际', '稳定']],
'I' => ['name' => '研究型', 'traits' => ['分析能力强', '喜欢思考', '独立', '好奇']],
'A' => ['name' => '艺术型', 'traits' => ['创造力强', '喜欢表达', '独立', '理想化']],
'S' => ['name' => '社会型', 'traits' => ['善于沟通', '喜欢帮助他人', '友善', '合作']],
'E' => ['name' => '企业型', 'traits' => ['领导能力强', '喜欢影响他人', '自信', '冒险']],
'C' => ['name' => '常规型', 'traits' => ['注重细节', '喜欢有序', '谨慎', '高效']]
];
// 职业代码对应表
const CAREER_CODES = [
'RIA' => ['机械工程师', '电子工程师', '技术员'],
'RIS' => ['外科医生', '牙医', '兽医'],
'RIE' => ['建筑师', '土木工程师', '制图员'],
'RSE' => ['消防员', '警察', '保安'],
'RSC' => ['理发师', '厨师', '工匠'],
'RAI' => ['摄影师', '音乐家', '画家'],
'RCE' => ['司机', '操作员', '装配工'],
'IAS' => ['心理学家', '社会学家', '人类学家'],
'IAR' => ['数学家', '物理学家', '天文学家'],
'ISC' => ['医生', '药剂师', '营养师'],
'ISR' => ['生物学家', '化学家', '地质学家'],
'IRA' => ['计算机科学家', '统计学家', '系统分析师'],
'IRE' => ['工程师', '技术专家', '研究员'],
'AIC' => ['作家', '编辑', '记者'],
'AIR' => ['作曲家', '指挥家', '音乐教师'],
'AIS' => ['演员', '导演', '舞蹈家'],
'ASE' => ['设计师', '艺术指导', '创意总监'],
'ASC' => ['广告经理', '公关专员', '活动策划'],
'AEI' => ['艺术家', '摄影师', '插画师'],
'AER' => ['建筑师', '室内设计师', '景观设计师'],
'SEC' => ['教师', '辅导员', '社工'],
'SEI' => ['护士', '理疗师', '营养师'],
'SER' => ['教练', '健身指导', '体育教师'],
'SEA' => ['心理咨询师', '职业顾问', '人力资源'],
'SAC' => ['销售员', '客户服务', '接待员'],
'SAI' => ['教师', '培训师', '教育顾问'],
'ECI' => ['经理', '主管', '执行官'],
'ECS' => ['销售经理', '市场经理', '业务经理'],
'ERI' => ['企业家', '投资人', '商业顾问'],
'ERA' => ['项目经理', '产品经理', '运营经理'],
'ESC' => ['行政主管', '办公室主任', '秘书'],
'ESR' => ['零售经理', '酒店经理', '餐厅经理'],
'CRI' => ['会计师', '审计师', '财务分析师'],
'CRA' => ['图书管理员', '档案管理员', '数据录入员'],
'CRE' => ['银行职员', '税务专员', '保险代理'],
'CSE' => ['行政助理', '文员', '接待员'],
'CSR' => ['客服代表', '技术支持', '电话销售'],
'CSI' => ['计算机操作员', '数据管理员', '统计员']
];
/**
* 分析霍兰德代码
*/
public static function analyzeHollandCode($scores) {
// 按得分排序
arsort($scores);
// 获取前三高的类型代码
$top_three = array_slice(array_keys($scores), 0, 3);
// 生成霍兰德三字代码
$holland_code = implode('', $top_three);
// 获取类型描述
$type_descriptions = [];
foreach ($top_three as $type) {
if (isset(self::TYPE_DESCRIPTIONS[$type])) {
$type_descriptions[$type] = self::TYPE_DESCRIPTIONS[$type];
}
}
// 获取推荐职业
$recommended_careers = self::getRecommendedCareers($holland_code);
// 生成分析报告
$analysis = self::generateAnalysisReport($holland_code, $scores, $type_descriptions, $recommended_careers);
return $analysis;
}
/**
* 获取推荐职业
*/
private static function getRecommendedCareers($holland_code) {
$careers = [];
// 精确匹配
if (isset(self::CAREER_CODES[$holland_code])) {
$careers = self::CAREER_CODES[$holland_code];
} else {
// 模糊匹配:尝试前两个字母匹配
$partial_code = substr($holland_code, 0, 2);
foreach (self::CAREER_CODES as $code => $career_list) {
if (strpos($code, $partial_code) === 0) {
$careers = array_merge($careers, $career_list);
}
}
// 如果还是没有匹配,返回通用职业建议
if (empty($careers)) {
$careers = self::getGeneralCareers($holland_code);
}
}
// 去重并限制数量
$careers = array_unique($careers);
return array_slice($careers, 0, 10);
}
/**
* 生成分析报告
*/
private static function generateAnalysisReport($holland_code, $scores, $type_descriptions, $recommended_careers) {
$report = [
'holland_code' => $holland_code,
'primary_type' => [
'code' => $holland_code[0],
'name' => $type_descriptions[$holland_code[0]]['name'] ?? '',
'description' => '这是您最突出的职业兴趣类型。',
'traits' => $type_descriptions[$holland_code[0]]['traits'] ?? []
],
'secondary_type' => [
'code' => $holland_code[1],
'name' => $type_descriptions[$holland_code[1]]['name'] ?? '',
'description' => '这是您的次要职业兴趣类型。',
'traits' => $type_descriptions[$holland_code[1]]['traits'] ?? []
],
'tertiary_type' => [
'code' => $holland_code[2],
'name' => $type_descriptions[$holland_code[2]]['name'] ?? '',
'description' => '这是您的第三职业兴趣类型。',
'traits' => $type_descriptions[$holland_code[2]]['traits'] ?? []
],
'score_distribution' => $scores,
'career_recommendations' => $recommended_careers,
'interpretation' => self::generateInterpretation($holland_code, $scores),
'development_suggestions' => self::getDevelopmentSuggestions($holland_code)
];
return $report;
}
/**
* 生成个性化解读
*/
private static function generateInterpretation($holland_code, $scores) {
$interpretations = [
'R' => '您喜欢动手操作,倾向于从事技术性、机械性的工作。',
'I' => '您善于思考分析,适合研究型、探索性的工作环境。',
'A' => '您富有创造力,适合在艺术、设计等需要创新的领域发展。',
'S' => '您乐于助人,擅长人际交往,适合教育、服务等行业。',
'E' => '您具有领导才能,适合管理、销售等需要影响力的工作。',
'C' => '您注重细节和秩序,适合行政、财务等需要精确性的工作。'
];
$primary = $holland_code[0];
$secondary = $holland_code[1];
$text = "根据测评结果,您的霍兰德职业代码是<strong>{$holland_code}</strong>。";
$text .= "这表明您的主要职业兴趣是{$interpretations[$primary]}";
$text .= "同时,您还具有{$interpretations[$secondary]}的特点。";
// 添加组合类型的特殊解读
$combination_interpretations = [
'RIS' => '您兼具研究精神和动手能力,适合医疗、科研等技术性工作。',
'ASE' => '您的创造力和社交能力结合,适合创意产业和市场营销。',
'SEC' => '您的服务精神和细致特点,适合教育、行政等支持性工作。',
'EIC' => '您的领导力、分析能力和条理性结合,适合管理和咨询工作。'
];
if (isset($combination_interpretations[$holland_code])) {
$text .= " " . $combination_interpretations[$holland_code];
}
return $text;
}
}
// 测评结果可视化类
class AssessmentVisualization {
/**
* 生成雷达图数据(用于多维度测评)
*/
public static function generateRadarChartData($dimension_scores) {
$labels = [];
$data = [];
$max_values = [];
foreach ($dimension_scores as $dimension => $score_data) {
$labels[] = self::getDimensionLabel($dimension);
$data[] = $score_data['average'];
$max_values[] = 5; // 假设5分制
}
return [
'type' => 'radar',
'data' => [
'labels' => $labels,
'datasets' => [[
'label' => '您的得分',
'data' => $data,
'backgroundColor' => 'rgba(54, 162, 235, 0.2)',
'borderColor' => 'rgba(54, 162, 235, 1)',
'pointBackgroundColor' => 'rgba(54, 162, 235, 1)',
'pointBorderColor' => '#fff',
'pointHoverBackgroundColor' => '#fff',
'pointHoverBorderColor' => 'rgba(54, 162, 235, 1)'
]]
],
'options' => [
'scale' => [
'ticks' => [
'beginAtZero' => true,
'max' => 5,
'stepSize' => 1
]
],
'responsive' => true,
'maintainAspectRatio' => false
]
];
}
/**
* 生成柱状图数据(用于霍兰德测评)
*/
public static function generateHollandBarChart($holland_scores) {
$colors = [
'R' => '#FF6384', // 红色
'I' => '#36A2EB', // 蓝色
'A' => '#FFCE56', // 黄色
'S' => '#4BC0C0', // 青色
'E' => '#9966FF', // 紫色
'C' => '#FF9F40' // 橙色
];
$labels = [];
$data = [];
$backgroundColors = [];
$borderColors = [];
foreach ($holland_scores as $type => $score) {
$labels[] = self::getHollandTypeName($type);
$data[] = $score;
$backgroundColors[] = $colors[$type];
$borderColors[] = str_replace('0.2', '1', $colors[$type]);
}
return [
'type' => 'bar',
'data' => [
'labels' => $labels,
'datasets' => [[
'label' => '兴趣强度',
'data' => $data,
'backgroundColor' => $backgroundColors,
'borderColor' => $borderColors,
'borderWidth' => 1
]]
],
'options' => [
// 测评结果可视化类
class AssessmentVisualization {
/**
* 生成雷达图数据(用于多维度测评)
*/
public static function generateRadarChartData($dimension_scores) {
$labels = [];
$data = [];
$max_values = [];
foreach ($dimension_scores as $dimension => $score_data) {
$labels[] = self::getDimensionLabel($dimension);
$data[] = $score_data['average'];
$max_values[] = 5; // 假设5分制
}
return [
'type' => 'radar',
'data' => [
'labels' => $labels,
'datasets' => [[
'label' => '您的得分',
'data' => $data,
'backgroundColor' => 'rgba(54, 162, 235, 0.2)',
'borderColor' => 'rgba(54, 162, 235, 1)',
'pointBackgroundColor' => 'rgba(54, 162, 235, 1)',
'pointBorderColor' => '#fff',
'pointHoverBackgroundColor' => '#fff',
'pointHoverBorderColor' => 'rgba(54, 162, 235, 1)'
]]
],
'options' => [
'scale' => [
'ticks' => [
'beginAtZero' => true,
'max' => 5,
'stepSize' => 1
]
],
'responsive' => true,
'maintainAspectRatio' => false
]
];
}
/**
* 生成柱状图数据(用于霍兰德测评)
*/
public static function generateHollandBarChart($holland_scores) {
$colors = [
'R' => '#FF6384', // 红色
'I' => '#36A2EB', // 蓝色
'A' => '#FFCE56', // 黄色
'S' => '#4BC0C0', // 青色
'E' => '#9966FF', // 紫色
'C' => '#FF9F40' // 橙色
];
$labels = [];
$data = [];
$backgroundColors = [];
$borderColors = [];
foreach ($holland_scores as $type => $score) {
$labels[] = self::getHollandTypeName($type);
$data[] = $score;
$backgroundColors[] = $colors[$type];
$borderColors[] = str_replace('0.2', '1', $colors[$type]);
}
return [
'type' => 'bar',
'data' => [
'labels' => $labels,
'datasets' => [[
'label' => '兴趣强度',
'data' => $data,
'backgroundColor' => $backgroundColors,
'borderColor' => $borderColors,
'borderWidth' => 1
]]
],
'options' => [


