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

基于MySQL数据库的人员区域拖拽分配功能优化咨询

问题描述

我需要制作一个网页,通过拖拽人员到对应区域来分配访问权限,同时同步更新MySQL数据库。目前已实现JavaScript拖拽功能,也能从数据库获取人员列表,但存在两个待解决的需求:

  1. 找到页面加载时人员按对应区域分类显示的最优方案——原本计划用三个独立PHP页面分别执行SELECT ... WHERE zoneAccess = 1/2/3查询,但认为该方案效率低下,希望优化。
  2. 实现人员被拖拽至区域后,将对应区域编号写入数据库的zoneAccess字段。

现有代码如下:

主页面HTML

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>📌 Drag and Drop</title>
        <link rel="stylesheet" href="css/style.css" />
    </head>
    <body>
        <main class="board">
            <div class="column column-zone1" ondrop="drop(event)" ondragover="allowDrop(event)">
                <h2>Zone 1</h2>
                <div class="container">
                    <table>
                        <div class="column column-ip" ondrop="drop(event)" ondragover="allowDrop(event)">
                            <?php include('EmployesDrag.php') ?>
                        </div>
                    </table>
                </div>
            </div>
            <div class="column column-zone2" ondrop="drop(event)" ondragover="allowDrop(event)">
                <h2>Zone 2</h2>
            </div>
            <div class="column column-zone3" ondrop="drop(event)" ondragover="allowDrop(event)">
                <h2>Zone 3</h2>
            </div>
        </main>
        <script src="js/DragDrop.js"></script>
    </body>
</html>

人员列表PHP(EmployesDrag.php)

<?php 
include_once "connexion.php";               
// 查询人员信息
$sql="SELECT prenom , nom FROM personnel";
$result=mysqli_query($con,$sql);

if ($result) {
    $rowcount=mysqli_num_rows($result);
}

if($rowcount == 0){
    echo "Il n'y a pas encore d'employé ajouter !";
}else {
    while($row=$result->fetch_assoc()){
        ?>
        <tr>
            <article class="card" draggable="true" ondragstart="drag(event)" data-id="1"><?=$row['nom']?></td>
        </tr>
        <?php
    }
    mysqli_free_result($result);
}
?>

拖拽逻辑JavaScript(DragDrop.js)

const dragStart = target => {
    target.classList.add('dragging');
};

const dragEnd = target => {
    target.classList.remove('dragging');
};

const dragEnter = event => {
    event.currentTarget.classList.add('drop');
};

const dragLeave = event => {
    event.currentTarget.classList.remove('drop');
};

const drag = event => {
    event.dataTransfer.setData('text/html', event.currentTarget.outerHTML);
    event.dataTransfer.setData('text/plain', event.currentTarget.dataset.id);
};

const drop = event => {
    document.querySelectorAll('.column').forEach(column => column.classList.remove('drop'));
    document.querySelector(`[data-id="${event.dataTransfer.getData('text/plain')}"]`).remove();

    event.preventDefault();
    event.currentTarget.innerHTML = event.currentTarget.innerHTML + event.dataTransfer.getData('text/html');
};

const allowDrop = event => {
    event.preventDefault();
};

document.querySelectorAll('.column').forEach(column => {
    column.addEventListener('dragenter', dragEnter);
    column.addEventListener('dragleave', dragLeave);
});

document.addEventListener('dragstart', e => {
    if (e.target.className.includes('card')) {
        dragStart(e.target);
    }
});

document.addEventListener('dragend', e => {
    if (e.target.className.includes('card')) {
        dragEnd(e.target);
    }
});

优化方案

一、页面加载时按区域分类显示的最优实现

无需三次独立查询,只需一次完整查询+后端分组/按需渲染,减少数据库交互次数,提升性能同时保证安全性。

1. 优化人员列表PHP(EmployesDrag.php)

添加区域参数接收逻辑,通过单个PHP文件按需渲染对应区域的人员,同时使用预编译语句防止SQL注入:

<?php 
include_once "connexion.php";               
// 接收目标区域参数,默认值为0
$targetZone = $_GET['zone'] ?? 0;
// 验证区域参数合法性
if(!in_array($targetZone, [1,2,3])){
    echo "<p>Aucun employé dans cette zone</p>";
    exit;
}

// 预编译查询语句,避免SQL注入
$sql = "SELECT id, prenom, nom FROM personnel WHERE zoneAccess = ?";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, "i", $targetZone);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

if(mysqli_num_rows($result) == 0){
    echo "<p>Aucun employé dans cette zone</p>";
}else {
    while($row=$result->fetch_assoc()){
        ?>
        <article class="card" draggable="true" ondragstart="drag(event)" data-id="<?= $row['id'] ?>">
            <?= $row['prenom'] ?> <?= $row['nom'] ?>
        </article>
        <?php
    }
    mysqli_free_result($result);
}
mysqli_stmt_close($stmt);
?>

2. 调整主HTML页面结构

给每个区域容器添加data-zone标识,同时按需引入对应区域的人员列表:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>📌 Drag and Drop</title>
    <link rel="stylesheet" href="css/style.css" />
</head>
<body>
    <main class="board">
        <!-- Zone 1 -->
        <div class="column column-zone1" data-zone="1" ondrop="drop(event)" ondragover="allowDrop(event)">
            <h2>Zone 1</h2>
            <div class="container">
                <?php include('EmployesDrag.php?zone=1') ?>
            </div>
        </div>
        <!-- Zone 2 -->
        <div class="column column-zone2" data-zone="2" ondrop="drop(event)" ondragover="allowDrop(event)">
            <h2>Zone 2</h2>
            <div class="container">
                <?php include('EmployesDrag.php?zone=2') ?>
            </div>
        </div>
        <!-- Zone 3 -->
        <div class="column column-zone3" data-zone="3" ondrop="drop(event)" ondragover="allowDrop(event)">
            <h2>Zone 3</h2>
            <div class="container">
                <?php include('EmployesDrag.php?zone=3') ?>
            </div>
        </div>
    </main>
    <script src="js/DragDrop.js"></script>
</body>
</html>

二、拖拽后更新数据库zoneAccess字段

通过AJAX在拖拽完成后发送异步请求,更新数据库对应字段,保证页面显示与数据一致性。

1. 修改JavaScript的drop函数

添加AJAX请求逻辑,获取目标区域编号并发送更新请求:

const drop = event => {
    document.querySelectorAll('.column').forEach(column => column.classList.remove('drop'));
    const employeeId = event.dataTransfer.getData('text/plain');
    const targetZone = event.currentTarget.dataset.zone;
    const draggedElement = document.querySelector(`[data-id="${employeeId}"]`);
    
    // 移除原元素并添加到目标区域
    draggedElement.remove();
    event.preventDefault();
    event.currentTarget.querySelector('.container').innerHTML += event.dataTransfer.getData('text/html');
    
    // 发送AJAX请求更新数据库
    fetch('update_zone.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `employee_id=${employeeId}&zone=${targetZone}`
    })
    .then(response => response.text())
    .then(data => {
        console.log('更新状态:', data);
        // 可在此添加成功提示
    })
    .catch(error => {
        console.error('更新失败:', error);
        // 失败时可回滚操作,将元素放回原区域
    });
};

2. 创建数据库更新PHP(update_zone.php)

处理AJAX请求,使用预编译语句更新数据库:

<?php
include_once "connexion.php";

// 获取请求参数
$employeeId = $_POST['employee_id'] ?? 0;
$zone = $_POST['zone'] ?? 0;

// 验证参数合法性
if(!in_array($zone, [1,2,3]) || !is_numeric($employeeId)){
    echo "参数无效";
    exit;
}

// 预编译更新语句
$sql = "UPDATE personnel SET zoneAccess = ? WHERE id = ?";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, "ii", $zone, $employeeId);

if(mysqli_stmt_execute($stmt)){
    echo "更新成功";
}else {
    echo "更新失败: " . mysqli_error($con);
}

mysqli_stmt_close($stmt);
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:30:47