PHP项目如何实现用户投诉处理?

wen java案例 1

本文目录导读:

PHP项目如何实现用户投诉处理?

  1. 数据库设计 (MySQL)
  2. 用户端:提交投诉页面 (PHP + HTML)
  3. 管理后台:投诉列表与处理
  4. 用户查看自己的投诉状态
  5. 进阶功能与建议

在PHP项目中实现用户投诉处理功能,通常需要涵盖前端提交后端接收与存储管理后台处理通知与反馈这几个核心环节。

以下是一个完整的实现方案,包含数据库设计、代码示例和关键流程。


数据库设计 (MySQL)

首先创建一张投诉表,用于存储所有投诉信息。

CREATE TABLE `complaints` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) unsigned DEFAULT NULL COMMENT '投诉人ID(如果用户已登录)',
  `complaint_type` varchar(50) NOT NULL DEFAULT 'other' COMMENT '投诉类型:product, service, user, other',
  `order_id` varchar(100) DEFAULT NULL COMMENT '关联订单号(可选)', varchar(255) NOT NULL COMMENT '投诉标题',
  `content` text NOT NULL COMMENT '投诉内容',
  `images` text COMMENT '上传的图片路径,JSON数组或逗号分隔',
  `contact` varchar(100) DEFAULT NULL COMMENT '联系方式(邮箱/手机)',
  `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态:0=待处理, 1=处理中, 2=已完结, -1=已关闭',
  `handler_id` int(11) unsigned DEFAULT NULL COMMENT '处理人ID(管理员)',
  `handle_result` text COMMENT '处理结果/回复',
  `handle_time` datetime DEFAULT NULL COMMENT '处理时间',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_status` (`status`),
  KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

用户端:提交投诉页面 (PHP + HTML)

前端表单 (complaints/submit.php)

<?php
session_start();
// 假设用户已登录,$userId = $_SESSION['user_id'];
$userId = $_SESSION['user_id'] ?? null;
?>
<!DOCTYPE html>
<html>
<head>提交投诉</title>
</head>
<body>
    <form action="submit_action.php" method="POST" enctype="multipart/form-data">
        <h2>用户投诉</h2>
        <label>投诉类别</label>
        <select name="complaint_type" required>
            <option value="product">商品问题</option>
            <option value="service">服务问题</option>
            <option value="user">用户纠纷</option>
            <option value="other">其他</option>
        </select><br>
        <label>关联订单号(可选)</label>
        <input type="text" name="order_id" placeholder="如有请填写"><br>
        <label>投诉标题 *</label>
        <input type="text" name="title" required><br>
        <label>投诉内容 *</label>
        <textarea name="content" rows="5" required></textarea><br>
        <label>上传图片(可选,最多3张)</label>
        <input type="file" name="images[]" accept="image/*" multiple><br>
        <label>联系方式 *</label>
        <input type="text" name="contact" required placeholder="手机号或邮箱"><br>
        <button type="submit">提交投诉</button>
    </form>
</body>
</html>

后端处理 (submit_action.php)

<?php
session_start();
require_once 'db.php'; // 数据库连接
$userId = $_SESSION['user_id'] ?? null;
// 接收并过滤数据
$type       = $_POST['complaint_type'] ?? 'other';
$orderId    = $_POST['order_id'] ?? '';
$title      = trim($_POST['title']);
$content    = trim($_POST['content']);
$contact    = trim($_POST['contact']);
// 简单验证
if (empty($title) || empty($content) || empty($contact)) {
    die('请填写完整信息');
}
// 图片上传处理
$images = [];
if (!empty($_FILES['images']['name'][0])) {
    $uploadDir = 'uploads/complaints/';
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0777, true);
    }
    foreach ($_FILES['images']['tmp_name'] as $key => $tmpName) {
        if ($_FILES['images']['error'][$key] === UPLOAD_ERR_OK) {
            $ext = pathinfo($_FILES['images']['name'][$key], PATHINFO_EXTENSION);
            $newName = uniqid() . '.' . $ext;
            move_uploaded_file($tmpName, $uploadDir . $newName);
            $images[] = $uploadDir . $newName;
        }
    }
}
$imagesJson = json_encode($images);
// 插入数据库
$stmt = $pdo->prepare("INSERT INTO complaints (user_id, complaint_type, order_id, title, content, images, contact, created_at)
                        VALUES (?, ?, ?, ?, ?, ?, ?, NOW())");
$stmt->execute([$userId, $type, $orderId, $title, $content, $imagesJson, $contact]);
// 可选:发送通知给管理员(邮件/站内信)
// sendNotificationToAdmin('新投诉:' . $title);
// 跳转或提示
echo "<script>alert('投诉提交成功,请等待处理!');window.location.href='my_complaints.php';</script>";

管理后台:投诉列表与处理

管理员查看列表 (admin/complaints.php)

<?php
require_once 'admin_auth.php';
require_once 'db.php';
$stmt = $pdo->query("SELECT c.*, u.username AS user_name 
                     FROM complaints c 
                     LEFT JOIN users u ON c.user_id = u.id 
                     ORDER BY c.created_at DESC");
$complaints = $stmt->fetchAll();
?>
<!-- 简单表格展示 -->
<table border="1">
    <tr>
        <th>ID</th>
        <th>用户</th>
        <th>标题</th>
        <th>状态</th>
        <th>提交时间</th>
        <th>操作</th>
    </tr>
    <?php foreach ($complaints as $c): ?>
    <tr>
        <td><?= $c['id'] ?></td>
        <td><?= htmlspecialchars($c['user_name'] ?? '游客') ?></td>
        <td><?= htmlspecialchars($c['title']) ?></td>
        <td>
            <?php
            $statusMap = [0 => '待处理', 1 => '处理中', 2 => '已完结', -1 => '已关闭'];
            echo $statusMap[$c['status']] ?? '未知';
            ?>
        </td>
        <td><?= $c['created_at'] ?></td>
        <td><a href="handle_complaint.php?id=<?= $c['id'] ?>">处理</a></td>
    </tr>
    <?php endforeach; ?>
</table>

单个投诉处理页面 (admin/handle_complaint.php)

<?php
require_once 'admin_auth.php';
require_once 'db.php';
$id = $_GET['id'] ?? 0;
$stmt = $pdo->prepare("SELECT * FROM complaints WHERE id = ?");
$stmt->execute([$id]);
$complaint = $stmt->fetch();
if (!$complaint) {
    die('投诉不存在');
}
// 如果提交处理结果
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $status     = $_POST['status']; // 2 或 -1
    $result     = trim($_POST['handle_result']);
    $handlerId  = $_SESSION['admin_id'];
    $stmt = $pdo->prepare("UPDATE complaints SET 
                            status = ?, 
                            handle_result = ?, 
                            handler_id = ?, 
                            handle_time = NOW() 
                           WHERE id = ?");
    $stmt->execute([$status, $result, $handlerId, $id]);
    // 可选:通知用户处理完成(邮件/短信/站内信)
    // notifyUser($complaint['contact'], '您的投诉已处理');
    echo "<script>alert('处理完成');window.location.href='complaints.php';</script>";
    exit;
}
?>
<!-- 显示投诉详情和处理表单 -->
<div>
    <h3>投诉详情</h3>
    <p>用户:<?= htmlspecialchars($complaint['user_id'] ?: '游客') ?></p>
    <p>类型:<?= $complaint['complaint_type'] ?></p>
    <p>标题:<?= htmlspecialchars($complaint['title']) ?></p>
    <p>内容:<?= nl2br(htmlspecialchars($complaint['content'])) ?></p>
    <p>图片:<?php
        $images = json_decode($complaint['images'], true);
        if ($images) foreach ($images as $img) {
            echo "<img src='$img' width='100' style='margin:5px'>";
        }
    ?></p>
</div>
<form method="POST">
    <label>处理结果</label>
    <textarea name="handle_result" rows="5" required></textarea><br>
    <label>状态</label>
    <select name="status">
        <option value="2">已完结</option>
        <option value="-1">关闭(无效投诉)</option>
    </select><br>
    <button type="submit">提交处理</button>
</form>

用户查看自己的投诉状态

my_complaints.php

<?php
session_start();
require_once 'db.php';
$userId = $_SESSION['user_id'];
$stmt = $pdo->prepare("SELECT * FROM complaints WHERE user_id = ? ORDER BY created_at DESC");
$stmt->execute([$userId]);
$list = $stmt->fetchAll();
foreach ($list as $item) {
    echo "标题:{$item['title']} | 状态:{$statusMap[$item['status']]} | 处理结果:{$item['handle_result']}<br>";
}
?>

进阶功能与建议

功能 实现要点
通知机制 投诉提交后,用邮件(PHPMailer)、短信(腾讯云/阿里云)或站内信通知管理员;处理完成后通知用户。
防重复提交 结合数据库唯一约束或Redis限流,防止短时间内重复提交相同投诉。
敏感词过滤 使用 array_filter 或第三方敏感词库过滤投诉内容中的不当言论。
图片压缩 使用 GDImagick 对上传图片进行压缩,限制文件大小(例如最大2MB)。
分页与搜索 在管理后台实现分页(LIMIT)和按状态/时间/类型搜索。
权限控制 管理员才能访问后台处理页面,普通用户只能提交和查看自己的投诉。
自动超时提醒 用cron脚本检查超过48小时未处理的投诉,发送提醒给管理员。

一个完整的PHP投诉处理系统需要:

  1. 数据库设计:包含类型、状态、处理人、处理结果等字段。
  2. 用户端:提交表单 + 上传图片 + 防CSRF。
  3. 管理端:列表查看、筛选、处理表单 + 状态更新。
  4. 通知链路:确保投诉人和处理人能及时互动。

这套方案可以直接复制改造,适用于电商、社区、客服工单等多种场景。

抱歉,评论功能暂时关闭!