📖WordPress产品防伪码查询,带扫码功能

WordPress产品防伪码查询,带扫码功能插图

在wordpress后台创建一个可以批量上传防伪码的功能,并且在前面使用form输入框查询防伪码是否有效

可批量上传防伪码,需要CSV + UTF-8,一次上传10W条数据,演示文件dd.csv

其中包含一个扫码的JS文件需要放到指定文件jsQR.min.js

//安装WpCode并输入以下代码,PHP
// 创建防伪码数据库表
function create_auth_code_table() {
    global $wpdb;

    $table_name = $wpdb->prefix . 'auth_codes';

    // 检查表是否已存在
    if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
        // 表的字符集和校对规则
        $charset_collate = $wpdb->get_charset_collate();

        // 创建表的 SQL 语句
        $sql = "CREATE TABLE $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            auth_code varchar(255) NOT NULL,
            PRIMARY KEY  (id)
        ) $charset_collate;";

        // 引入 WordPress 的升级文件
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);  // 执行 SQL 语句
    }
}

// 激活插件时创建数据库表
add_action('after_switch_theme', 'create_auth_code_table');

// 后端处理:验证防伪码是否有效
function verify_auth_code_ajax() {
    if (isset($_POST['auth_code'])) {
        $auth_code = sanitize_text_field($_POST['auth_code']);
        global $wpdb;

        // 查询防伪码是否存在
        $result = $wpdb->get_var(
            $wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}auth_codes WHERE auth_code = %s", $auth_code)
        );
        
        if ($result > 0) {
            // 防伪码有效
            echo 'valid';  // 返回 "valid" 表示防伪码有效
        } else {
            // 防伪码无效
            echo 'invalid';  // 返回 "invalid" 表示防伪码无效
        }
    }
    die(); // 结束 AJAX 请求
}
add_action('wp_ajax_verify_auth_code', 'verify_auth_code_ajax'); // 管理员 AJAX 请求
add_action('wp_ajax_nopriv_verify_auth_code', 'verify_auth_code_ajax'); // 非管理员 AJAX 请求

// 前端验证防伪码功能
function verify_auth_code() {
    ?>
<style>
    /* 表单区域 */
    #searchForm{display:flex;gap:0px;flex-wrap: wrap;}
    #searchForm #scanBtn{padding: 8px 30px;font-size: 16px;border: none;cursor: pointer;border-radius: 0px 100px 100px 0px;display: flex;width: 20%;}
    #scanBtn svg {width: 35px;height: 35px;}
    #scanBtn{background:#000;color:#fff}

    /* 扫描层覆盖全屏,初始隐藏 */
    #scanner{display:none;position:fixed;inset:0;background:#000}
    #scanner video,#scanner canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
    .scan-box{
      position:absolute;top:50%;left:50%;
      width:60vmin;height:60vmin;
      transform:translate(-50%,-50%);
      border:3px solid #ffeb3b;border-radius:8px;pointer-events:none;
    }
  </style>
  <script src="/wp-content/themes/woodmart2025-4-17/jsQR.min.js"></script>
    <form method="post" class="Verify_Form" onsubmit="return doSearch();" id="searchForm">
        <input type="text" name="auth_code" id="auth_code" placeholder="Enter your security code" required/>
        <!-- 将提交按钮改为 button 元素,并加入 Font Awesome 图标 -->
		<button type="button" id="scanBtn">
			<svg t="1750067170492" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2374" width="200" height="200"><path d="M928 544 96 544c-17.664 0-32-14.336-32-32s14.336-32 32-32l832 0c17.696 0 32 14.336 32 32S945.696 544 928 544zM832 928l-192 0c-17.696 0-32-14.304-32-32s14.304-32 32-32l192 0c17.664 0 32-14.336 32-32l0-160c0-17.696 14.304-32 32-32s32 14.304 32 32l0 160C928 884.928 884.928 928 832 928zM352 928 192 928c-52.928 0-96-43.072-96-96l0-160c0-17.696 14.336-32 32-32s32 14.304 32 32l0 160c0 17.664 14.368 32 32 32l160 0c17.664 0 32 14.304 32 32S369.664 928 352 928zM128 384c-17.664 0-32-14.336-32-32L96 192c0-52.928 43.072-96 96-96l160 0c17.664 0 32 14.336 32 32s-14.336 32-32 32L192 160C174.368 160 160 174.368 160 192l0 160C160 369.664 145.664 384 128 384zM896 384c-17.696 0-32-14.336-32-32L864 192c0-17.632-14.336-32-32-32l-192 0c-17.696 0-32-14.336-32-32s14.304-32 32-32l192 0c52.928 0 96 43.072 96 96l0 160C928 369.664 913.696 384 896 384z" fill="#ffffff" p-id="2375"></path></svg>
		</button>
        <button type="submit" id="verify_button">Click on the query</button>
    </form>
  <!-- ② 扫码层(点击扫码后显示) -->
  <div id="scanner">
    <video id="video" playsinline muted></video>
    <canvas id="canvas"></canvas>
    <div class="scan-box"></div>
  </div>
<script>
    // ======== 搜索逻辑 ========
    function doSearch(){
      const q = document.getElementById('auth_code').value.trim();
      if(!q) return false;            // 空值不搜索
		submit();
      return false;                   // 阻止表单默认提交
    }
function submit() {
// 获取输入的防伪码
	jQuery(document).ready(function($) {
                var auth_code = $('#auth_code').val();
                // 发送 AJAX 请求
                $.ajax({
                    url: '<?php echo admin_url('admin-ajax.php'); ?>', // WordPress AJAX URL
                    method: 'POST',
                    data: {
                        action: 'verify_auth_code',   // 后端处理的钩子
                        auth_code: auth_code,         // 要验证的防伪码
                    },
                    success: function(response) {
                        // 根据返回结果显示弹框
                        if (response === 'valid') {
                            // 防伪码有效,显示"真的"弹框
                            if (typeof elementorProFrontend !== 'undefined') {
								console.log(1);
                                elementorProFrontend.modules.popup.showPopup( { id: 933 } );
                            } else {
                                alert("Elementor 前端 API 未加载!");
                            }
                        } else if (response === 'invalid') {
                            // 防伪码无效,显示"假的"弹框
                            if (typeof elementorProFrontend !== 'undefined') {
								console.log(2);
                                elementorProFrontend.modules.popup.showPopup( { id: 936 } );
                            } else {
                                alert("Elementor 前端 API 未加载!");
                            }
                        }
                    },
                    error: function() {
                        alert('发生错误,请稍后再试。');
                    }
                });
	});
}
    // ======== 扫码逻辑 ========
    const scanBtn   = document.getElementById('scanBtn');
    const scanner   = document.getElementById('scanner');
    const video     = document.getElementById('video');
    const canvas    = document.getElementById('canvas');
    const ctx       = canvas.getContext('2d');
    let scanning    = false;
    let stream      = null;           // 用于稍后关闭摄像头

    scanBtn.addEventListener('click', startScan);

    async function startScan(){
      scanner.style.display = 'block';            // 显示扫描层
      try{
        stream = await navigator.mediaDevices.getUserMedia({video:{facingMode:'environment'}});
        video.srcObject = stream;
        await video.play();
        canvas.width  = video.videoWidth;
        canvas.height = video.videoHeight;
        scanning = true;
        requestAnimationFrame(scanFrame);
      }catch(e){
        alert('无法打开摄像头:'+e);
        scanner.style.display = 'none';
      }
    }

    async function scanFrame(){
      if(!scanning) return;
      ctx.drawImage(video,0,0,canvas.width,canvas.height);

      // 按可视扫描框裁剪像素
      const box = document.querySelector('.scan-box');
      const {left,top,width,height} = box.getBoundingClientRect();
      const scaleX = canvas.width  / window.innerWidth;
      const scaleY = canvas.height / window.innerHeight;
      const imgData = ctx.getImageData(left*scaleX, top*scaleY, width*scaleX, height*scaleY);

      const code = jsQR(imgData.data, imgData.width, imgData.height);
      if(code){
        handleResult(code.data);
      }else{
        requestAnimationFrame(scanFrame);
      }
    }

    function handleResult(text){
      scanning = false;
      video.pause();
      if(stream){
        stream.getTracks().forEach(t => t.stop()); // 关闭摄像头
        stream = null;
      }
      scanner.style.display = 'none';
      // ③ 把结果回填搜索框并自动搜索
	  
		document.getElementById('auth_code').value = text.split('s=')[1];
      doSearch();
    }
  </script>
    <?php
}
add_shortcode('verify_auth_code', 'verify_auth_code');



// 添加后台菜单项
function add_verity_product_menu() {
    // 确保在后台页面时才添加菜单项
    if (current_user_can('manage_options')) {
        add_menu_page(
            'Verity Product',       // 页面标题
            'Verity Product',       // 菜单名称
            'manage_options',       // 用户权限
            'verity-product',       // 菜单的 slug
            'verity_product_page',  // 显示页面的回调函数
            'dashicons-upload',     // 菜单图标
            20                      // 菜单位置
        );
    }
}

// 确保钩子正确执行
add_action('admin_menu', 'add_verity_product_menu');



// 后台页面内容:上传 CSV 文件并批量管理防伪码
function verity_product_page() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'auth_codes';

    // 每页显示的防伪码数量
    $per_page = 10;

    // 获取当前页
    $paged = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
    $offset = ($paged - 1) * $per_page;

    // 获取防伪码数据(分页)
    $auth_codes = $wpdb->get_results(
        $wpdb->prepare("SELECT * FROM $table_name LIMIT %d OFFSET %d", $per_page, $offset)
    );

    // 获取总记录数
    $total_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");

    // 计算总页数
    $total_pages = ceil($total_count / $per_page);

    // 处理删除操作
    if (isset($_POST['action']) && $_POST['action'] == 'delete' && isset($_POST['auth_codes'])) {
        // 获取选中的防伪码 ID
        $auth_codes_to_delete = array_map('intval', $_POST['auth_codes']);

        // 删除选中的防伪码
        $wpdb->query(
            "DELETE FROM $table_name WHERE id IN (" . implode(',', $auth_codes_to_delete) . ")"
        );

        // 显示删除成功消息
        echo '<div class="updated"><p>防伪码已删除。</p></div>';
		 echo '<script>window.location.reload();</script>'; // 刷新页面
    }

    // 文件上传和处理
    if (isset($_FILES['csv_file']) && $_FILES['csv_file']['error'] == 0) {
        // 获取文件信息
        $file_tmp = $_FILES['csv_file']['tmp_name'];
        $file_name = $_FILES['csv_file']['name'];

        // 检查文件扩展名是否为 CSV
        $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);
        if ($file_extension !== 'csv') {
            echo '<div class="error"><p>请上传 CSV 格式的文件!</p></div>';
            return;
        }

        // 检查文件是否为 UTF-8 编码
        $file_content = file_get_contents($file_tmp);
        if (!mb_check_encoding($file_content, 'UTF-8')) {
            echo '<div class="error"><p>文件必须是 UTF-8 编码!</p></div>';
            return;
        }

        // 读取 CSV 文件并处理
        if (($handle = fopen($file_tmp, "r")) !== FALSE) {
            $header = fgetcsv($handle);  // 跳过文件头部

            while (($data = fgetcsv($handle)) !== FALSE) {
                // 处理 CSV 文件数据
                $auth_code = sanitize_text_field($data[0]); // 假设防伪码在第一列

                // 插入数据到数据库
                $wpdb->insert(
                    $table_name,
                    array('auth_code' => $auth_code),
                    array('%s')
                );
            }

            fclose($handle);
        }

        echo '<div class="updated"><p>CSV 文件已成功上传并保存!</p></div>';
		echo '<script>window.location.reload();</script>';
    }

    ?>
    <div class="wrap">
        <h1>上传防伪码</h1>
        <!-- 上传表单 -->
        <form id="upload_form" method="post" enctype="multipart/form-data">
            <input type="file" id="csv_file" name="csv_file" accept=".csv" />
            <input type="submit" name="upload_csv" value="上传 CSV" class="button button-primary" />
        </form>

        <!-- 显示上传进度 -->
        <div id="progress_wrapper" style="display: none;">
            <label for="progress_bar">数据写入进度:</label>
            <progress id="progress_bar" value="0" max="100" style="width: 100%;"></progress>
            <p id="progress_text">0%</p>
        </div>

        <div id="upload_message"></div>

        <h2>防伪码管理</h2>

        <form method="post">
            <table class="wp-list-table widefat fixed striped">
                <thead>
                    <tr>
                        <th class="manage-column column-cb check-column">
                            <input type="checkbox" />
                        </th>
                        <th class="manage-column">防伪码</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($auth_codes as $auth_code) : ?>
                    <tr>
                        <th class="check-column">
                            <input type="checkbox" name="auth_codes[]" value="<?php echo $auth_code->id; ?>" />
                        </th>
                        <td><?php echo esc_html($auth_code->auth_code); ?></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>

            <div class="bulk-actions alignleft">
                <select name="action">
                    <option value="-1">批量操作</option>
                    <option value="delete">删除</option>
                </select>
                <input type="submit" value="应用" class="button action" />
            </div>
        </form>

        <div class="tablenav">
            <div class="tablenav-pages">
                <?php
                echo paginate_links(array(
                    'total' => $total_pages,
                    'current' => $paged,
                    'format' => '?paged=%#%',
                    'prev_text' => '« 上一页',
                    'next_text' => '下一页 »',
                ));
                ?>
            </div>
        </div>
    </div>
<?php
}






标签

🧐发表评论

您必须启用javascript才能在此处查看验证码