如何为Elementor配置自定义JS脚本实现CV解析与OpenAI优化填充?
Elementor自定义CV优化脚本配置指南
一、页面元素准备(Elementor端)
在目标Elementor页面中添加并配置以下元素,确保每个元素的CSS ID与脚本中的ID完全匹配:
- 文件上传框:设置CSS ID为
pdfFileInput(用于选择CV PDF文件) - 触发按钮:设置CSS ID为
convertButton(点击后执行PDF提取与AI生成) - 结果展示元素:
- 职业快照:CSS ID
careerTitle - 专家技能:CSS ID
expertSkills - 成就列表:CSS ID
accomplishments - 使用技术:CSS ID
utilizedTechnologies - 顶级成就:CSS ID
topAchievements - 奖项与培训:CSS ID
awardsTrainings - 教育经历:CSS ID
education - 工作经历列表:CSS ID
employmentRoles(需为<ul>或<ol>标签)
- 职业快照:CSS ID
设置方法:编辑Elementor元素时,进入「高级」选项卡,在「CSS ID」栏填写对应ID。
二、脚本关键修改与安全优化
1. 创建OpenAI API后端代理(必须)
绝对禁止在前端脚本中直接写入OpenAI API密钥,会导致密钥泄露。需通过WordPress自定义REST API端点实现后端调用:
在主题的functions.php中添加以下代码:
add_action('rest_api_init', function () { register_rest_route('cv-optimizer/v1', '/generate', array( 'methods' => 'POST', 'callback' => 'cv_optimizer_openai_proxy', 'permission_callback' => function () { return is_user_logged_in(); // 仅允许登录用户调用,可按需调整 } )); }); function cv_optimizer_openai_proxy(WP_REST_Request $request) { $api_key = '你的OpenAI API密钥'; // 在此安全存储密钥 $prompt = $request->get_param('prompt'); $cv_text = $request->get_param('cv_text'); $response = wp_remote_post('https://api.openai.com/v1/completions', array( 'headers' => array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $api_key ), 'body' => json_encode(array( 'model' => 'gpt-3.5-turbo-instruct', // 替代已弃用的text-davinci-003 'prompt' => $prompt . "\n" . $cv_text, 'max_tokens' => 300, 'temperature' => 0.5 )) )); if (is_wp_error($response)) { return new WP_REST_Response(array('error' => $response->get_error_message()), 500); } return json_decode(wp_remote_retrieve_body($response), true); }
2. 修改前端脚本API调用逻辑
将原脚本中直接调用OpenAI API的部分,改为调用上述后端代理端点,并更新提示词为中文:
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> // 指定PDF Worker脚本路径 pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.worker.min.js'; // 转换按钮点击事件 document.getElementById('convertButton').addEventListener('click', () => { const fileInput = document.getElementById('pdfFileInput'); const file = fileInput.files[0]; if (file) { const reader = new FileReader(); reader.onload = function (event) { const arrayBuffer = event.target.result; // 使用pdf.js加载PDF pdfjsLib.getDocument(arrayBuffer).promise.then(pdf => { const numPages = pdf.numPages; const promises = []; // 遍历PDF所有页面提取文本 for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) { const pagePromise = pdf.getPage(pageNumber).then(page => { return page.getTextContent().then(textContent => { const pageText = textContent.items.map(item => item.str).join(' '); return { pageNumber, pageText }; }); }); promises.push(pagePromise); } // 等待所有页面文本提取完成 Promise.all(promises).then(pagesData => { const cvText = pagesData.map(item => item.pageText).join(' '); console.log('提取的CV文本:', cvText); // 定义各模块生成提示词 const prompts = [ "根据描述的经历生成一份专业得体的职业快照,不要提及姓名或地址,内容为3-5行详细描述", "从文本中列出3项核心专业技能", "从文本中列出所有成就", "从文本中列出使用过的技术栈", "从文本中挑选并重新润色最突出的3项成就", "从文本中列出所有奖项与培训经历", "从文本的教育部分中列出学校名称、学位及对应日期", "从文本中列出前3份工作的公司、职位、任职日期,并为每份工作添加2行描述" ]; const generatedResponses = []; let completedRequests = 0; // 处理API响应并填充页面元素 const handleCompletion = (promptIndex, response) => { if (response.error) { console.error('生成失败:', response.error); return; } const generatedText = response.choices[0].text.trim(); generatedResponses[promptIndex] = generatedText; completedRequests++; // 所有请求完成后填充内容 if (completedRequests === prompts.length) { document.getElementById('careerTitle').innerText = generatedResponses[0]; document.getElementById('expertSkills').innerText = generatedResponses[1]; document.getElementById('accomplishments').innerText = generatedResponses[2]; document.getElementById('utilizedTechnologies').innerText = generatedResponses[3]; document.getElementById('topAchievements').innerText = generatedResponses[4]; document.getElementById('awardsTrainings').innerText = generatedResponses[5]; document.getElementById('education').innerText = generatedResponses[6]; // 处理工作经历列表 const employmentRolesList = document.getElementById('employmentRoles'); employmentRolesList.innerHTML = ''; const employmentRoles = generatedResponses[7]; if (employmentRoles) { const roles = employmentRoles.trim().split(/\d+\./).slice(1); roles.forEach(role => { if (role.trim()) { const listItem = document.createElement('li'); listItem.textContent = role.trim(); employmentRolesList.appendChild(listItem); } }); } } }; // 遍历提示词调用后端代理API prompts.forEach((prompt, index) => { $.ajax({ url: '/wp-json/cv-optimizer/v1/generate', method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': wpApiSettings.nonce // REST API安全验证 }, data: JSON.stringify({ prompt: prompt, cv_text: cvText }), success: function (response) { handleCompletion(index, response); }, error: function (error) { console.error('请求错误:', error); completedRequests++; } }); }); }); }); }; reader.readAsArrayBuffer(file); } }); </script>
3. 添加REST API安全验证
在主题的functions.php中添加以下代码,加载WordPress REST API的验证令牌:
add_action('wp_enqueue_scripts', function () { wp_enqueue_script('wp-api'); });
三、脚本添加到Elementor页面
将修改后的完整脚本添加到目标Elementor页面的自定义HTML模块中,建议将模块放在页面页脚区域(通过Elementor「页面设置」-「自定义代码」添加到页脚),确保脚本在所有页面元素加载完成后执行。
四、WP Forms上传文件关联(可选)
如果需要直接使用WP Forms上传的PDF文件,无需用户再次上传,可按以下步骤操作:
- 在WP Forms的「确认设置」中,将用户引导到目标Elementor页面,并传递上传文件ID作为URL参数(例如
?cv_file_id=123) - 在目标页面的自定义脚本中,添加逻辑通过文件ID获取服务器上的PDF路径,再用pdf.js加载该文件(需确保文件访问权限正确)
内容的提问来源于stack exchange,提问作者hamza tariq
相关产品推荐
相关产品推荐

