You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PHP与Ajax的三步式故障工单标签页开发求助

三步式故障工单提交系统开发问题与解决思路指导

问题描述

我是PHP新手,要开发一个带前进/后退按钮的三步式标签页故障工单提交系统,规则如下:

  • 第一步:点击按钮即可前进到第二步
  • 第二步:必须勾选隐私协议才能前进到第三步
  • 第三步:填写姓名、邮箱等字段后提交数据

目前基于一个含JavaScript与PHP Ajax通信的两步标签页示例开发,但简化页面后前进按钮失效,怀疑是JavaScript结构问题,寻求开发指导或解决思路。

现有代码

JavaScript代码

!function(){const l=document.querySelector(".container-segnalazione");async function e(){const r=l.querySelector(".steppers-content");if(r){var e=r.querySelector("#category");if(e){const o=r.querySelector("#service");o&&(e.addEventListener("change",async e=>{r=o,t=r.firstElementChild,r.innerHTML="",r.append(t),r.disabled=!0;var t=e.target.value;if(t){var r=await async function(e){try{return await(await fetch(window.wpRestApi+"wp/v2/servizi"+(e?"?categorie_servizio="+e:""))).json()}catch(e){console.error(e)}}(t);if(Array.isArray(r)){for(servizio of r){var a=servizio?.title?.rendered,n=document.createElement("option");n.value=a,n.innerHTML=a,o.add(n)}1<o.childElementCount&&(o.disabled=!1)}}}),r.addEventListener("submit",async()=>{var e,t=r.querySelector(".errorFeedback"),t=(t&&t.remove(),await async function(){try{var e=l.querySelector('[name="name"]').value,t=l.querySelector('[name="surname"]').value,r=l.querySelector('[name="email"]').value,a=l.querySelector("#category").value,n=l.querySelector("#service").value,o=l.querySelector("#description").value,c=l.querySelector("#privacy").checked,i={title:"ticket_"+(new Date).toISOString(),nome:e,cognome:t,email:r,categoria_servizio:a,servizio:n,dettagli:o,privacyChecked:c},s=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return 0<(Object.values(i)?.filter(e=>!e))?.length||!s.test(r)?!1:(await fetch(data_segnalazione.url,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded","Cache-Control":"no-cache"},body:new URLSearchParams({action:"save_richiesta_assistenza",...i})})).ok}catch(e){console.error(e)}}());t?(document.getElementById("first-step").classList.add("d-none"),document.getElementById("second-step").classList.add("d-none"),document.getElementById("email-recap").innerText=l.querySelector('[name="email"]').value,document.getElementById("third-step").classList.remove("d-none"),(t=document.querySelector(".menu-wrapper"))&&t.scrollIntoView({behavior:"smooth"})):((t=document.createElement("p")).classList.add("form-feedback","just-validate-error-label","ms-0"),t.innerText="something went wrong, try again",(e=document.createElement("div")).classList.add("errorFeedback"),e.appendChild(t),t=e,(e=r.querySelector(".privacy-wrapper"))&&r.insertBefore(t,e))}))}}}l&&e()}();

PHP 加载脚本代码

function dci_enqueue_dci_segn_script()  {
    wp_enqueue_script( 'dci-segnalazione', get_template_directory_uri() . '/assistenza.js', array(), null, true );
    $variables = array(
        'url' => admin_url( 'admin-ajax.php' )
    );
    wp_localize_script('dci-segnalazione', "data_segnalazione", $variables);
}
add_action( 'wp_enqueue_scripts', 'dci_enqueue_dci_segn_script' );

解决思路与开发指导

1. 补全前进/后退按钮的事件绑定

现有JS代码完全没有处理第一步、第二步的前进按钮点击事件,这是按钮失效的核心原因。原示例是两步结构,改成三步后必须新增对应逻辑:

  • 给第一步前进按钮添加click事件,点击时切换标签页(隐藏first-step,显示second-step)
  • 给第二步前进按钮添加click事件,先检查隐私协议勾选状态,勾选后切换到第三步,否则提示用户
  • 给后退按钮添加对应事件,实现步骤回退

示例基础逻辑:

// 步骤切换通用函数
function switchStep(targetStep) {
  document.querySelectorAll('.step').forEach(step => step.classList.add('d-none'));
  document.getElementById(`${targetStep}-step`).classList.remove('d-none');
}

// 第一步前进
document.getElementById('step1-next').addEventListener('click', () => {
  switchStep('second');
});

// 第二步前进
document.getElementById('step2-next').addEventListener('click', () => {
  const privacyBox = document.querySelector('#privacy');
  if (!privacyBox.checked) {
    alert('请勾选隐私协议');
    return;
  }
  switchStep('third');
});

// 第二步后退
document.getElementById('step2-back').addEventListener('click', () => {
  switchStep('first');
});

// 第三步后退
document.getElementById('step3-back').addEventListener('click', () => {
  switchStep('second');
});

2. 修复JS变量覆盖问题

压缩后的代码存在严重的变量重复赋值问题:比如初始定义const r=l.querySelector(".steppers-content");,后续又把r重新赋值为服务选择器元素,导致后续逻辑中r指向错误,引发混乱。建议:

  • 格式化压缩代码(用在线JS格式化工具)
  • 给变量起清晰的命名,比如formContainer、categorySelect、serviceSelect,避免重复使用变量名

3. 拆分JS逻辑,提升可读性

把原有逻辑拆分为独立函数,比如:

  • validateForm():处理第三步的表单字段验证
  • submitTicket():处理Ajax提交逻辑
  • switchStep():统一处理标签页切换

4. 完善PHP后端逻辑

确保Ajax动作已正确注册,在主题functions.php中添加:

// 注册Ajax动作(登录/未登录用户均可访问)
add_action('wp_ajax_save_richiesta_assistenza', 'save_ticket_callback');
add_action('wp_ajax_nopriv_save_richiesta_assistenza', 'save_ticket_callback');

function save_ticket_callback() {
  // 验证提交的字段合法性
  $name = sanitize_text_field($_POST['nome']);
  $email = sanitize_email($_POST['email']);
  // 其他字段验证...

  // 保存工单到数据库或发送通知邮件
  // 示例:保存到自定义帖子类型
  $ticket_id = wp_insert_post(array(
    'post_title' => $_POST['title'],
    'post_type' => 'ticket',
    'post_status' => 'publish',
    'meta_input' => array(
      'ticket_name' => $name,
      'ticket_email' => $email,
      // 其他自定义字段
    )
  ));

  // 返回响应
  if ($ticket_id) {
    wp_send_json_success('工单提交成功');
  } else {
    wp_send_json_error('提交失败,请重试');
  }
  wp_die();
}

5. 调试技巧

  • 打开浏览器开发者工具(F12),查看Console标签的JS报错信息,快速定位问题
  • 用console.log()打印关键元素(比如按钮、表单字段),确认是否正确获取
  • 在Ajax提交逻辑中添加日志,检查后端是否接收到数据

内容的提问来源于stack exchange,提问作者Francesco Rossi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:08:11