用deepseek写了一个简单的排队叫号系统

要实现一个基于 ThinkPHP 6.1 的排队叫号系统,我们可以按照以下步骤进行开发。系统将使用 Redis 作为队列存储,WebSocket 实现实时推送,并提供 API 接口供用户和管理员操作。

1. 环境准备

首先,确保你已经安装了以下组件:

PHP 7.4+ ThinkPHP 6.1 Redis MySQL(可选,用于持久化历史记录) WebSocket 服务器(如 Swoole 或 Workerman)

2. 安装依赖

在 ThinkPHP 6.1 项目中,安装 Redis 和 WebSocket 相关的扩展包。

代码语言:javascript代码运行次数:0运行复制
composer require topthink/think-redis
 
 composer require workerman/workerman

3. 配置 Redis

在 config/cache.php 中配置 Redis 连接:

代码语言:javascript代码运行次数:0运行复制
return [
'default' => 'redis',
'stores'  => [
     'redis' => [
         'type'       => 'redis',
         'host'       => '127.0.0.1',
         'port'       => 6379,
         'password'   => '',
         'select'    => 0,
         'timeout'    => 0,
         'persistent' => false,
     ],
 ],
];

4. 创建队列管理类

创建一个队列管理类 app\service\QueueService.php,用于管理 Redis 队列。

代码语言:javascript代码运行次数:0运行复制
namespace app\service;

usethink\facade\Cache;

class QueueService
{
protected$queueKey = 'queue:numbers';
protected$webSocketService;

publicfunction __construct()
 {
     $this->webSocketService = newWebSocketService();
 }

// 取号
publicfunction getNumber()
 {
     $number = Cache::incr('queue:counter');
     Cache::rPush($this->queueKey, $number);
     return$number;
 }

// 叫号
publicfunction callNumber()
 {
     $number = Cache::lPop($this->queueKey);
     if ($number) {
         // 推送叫号信息到 WebSocket
         $this->webSocketService->pushToAll(['type' => 'call', 'number' => $number]);
     }
     return$number;
 }

// 获取当前排队状态
publicfunction getQueueStatus()
 {
     returnCache::lRange($this->queueKey, 0, -1);
 }

}

5. 创建 WebSocket 服务类

在 app\service 目录下创建一个 WebSocketService.php 文件,用于封装 WebSocket 服务器的逻辑。

代码语言:javascript代码运行次数:0运行复制
namespace app\service;

useWorkerman\Worker;
useWorkerman\Connection\TcpConnection;

class WebSocketService
{
protected$worker;

publicfunction __construct($address = 'websocket://0.0.0.0:2346')
 {
     $this->worker = newWorker($address);

     $this->worker->onConnect = function(TcpConnection $connection) {
         echo"New connection\n";
     };

     $this->worker->onMessage = function(TcpConnection $connection, $data) {
         // 处理客户端发送的消息
         $connection->send(json_encode(['type' => 'message', 'content' => 'Hello']));
     };

     $this->worker->onClose = function(TcpConnection $connection) {
         echo"Connection closed\n";
     };
 }

// 启动 WebSocket 服务器
publicfunction start()
 {
     Worker::runAll();
 }

// 推送消息到所有客户端
publicfunction pushToAll($message)
 {
     foreach ($this->worker->connections as$connection) {
         $connection->send(json_encode($message));
     }
 }

}

6. 创建 API 接口

在 app\controller\QueueController.php 中创建 API 接口。

代码语言:javascript代码运行次数:0运行复制
namespace app\controller;

useapp\service\QueueService;
usethink\facade\Request;

class QueueController
{
protected$queueService;

publicfunction __construct()
 {
     $this->queueService = newQueueService();
 }

// 取号
publicfunction getNumber()
 {
     $number = $this->queueService->getNumber();
     returnjson(['code' => 200, 'message' => '取号成功', 'number' => $number]);
 }

// 叫号
publicfunction callNumber()
 {
     $number = $this->queueService->callNumber();
     returnjson(['code' => 200, 'message' => '叫号成功', 'number' => $number]);
 }

// 查看当前排队状态
publicfunction getQueueStatus()
 {
     $status = $this->queueService->getQueueStatus();
     returnjson(['code' => 200, 'message' => '获取成功', 'status' => $status]);
 }

}`

7. 路由配置

在 route/route.php 中配置路由。

代码语言:javascript代码运行次数:0运行复制
use think\facade\Route;
Route::get('queue/getNumber', 'QueueController/getNumber');
Route::get('queue/callNumber', 'QueueController/callNumber');
Route::get('queue/getQueueStatus', 'QueueController/getQueueStatus');

8. 前端实现

在前端页面中,使用 WebSocket 连接服务器,并实时接收叫号信息。

代码语言:javascript代码运行次数:0运行复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>排队叫号系统</title>
    <!-- Bootstrap CSS -->
    <link href="@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Font Awesome -->
    <link href=".0.0-beta3/css/all.min.css" rel="stylesheet">
    <style>
        body {
            background-color: #f8f9fa;
            padding: 20px;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
        }
        .card {
            margin-top: 20px;
            box-shadow: 04px8pxrgba(0, 0, 0, 0.1);
        }
        .card-header {
            background-color: #007bff;
            color: white;
            font-size: 1.5rem;
            font-weight: bold;
        }
        .btn-primary {
            background-color: #007bff;
            border-color: #007bff;
        }
        .btn-primary:hover {
            background-color: #0056b3;
            border-color: #0056b3;
        }
        .btn-success {
            background-color: #28a745;
            border-color: #28a745;
        }
        .btn-success:hover {
            background-color: #218838;
            border-color: #218838;
        }
        .status-box {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 04px8pxrgba(0, 0, 0, 0.1);
            margin-top: 20px;
        }
        .status-boxh3 {
            margin-bottom: 15px;
            font-size: 1.25rem;
            color: #333;
        }
        .status-boxul {
            list-style-type: none;
            padding: 0;
        }
        .status-boxulli {
            padding: 10px;
            border-bottom: 1px solid #eee;
            font-size: 1rem;
            color: #555;
        }
        .status-boxulli:last-child {
            border-bottom: none;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="card">
        <div class="card-header text-center">
            排队叫号系统
        </div>
        <div class="card-body">
            <div class="d-grid gap-2">
                <button class="btn btn-primary btn-lg" onclick="getNumber()">
                    <i class="fas fa-ticket-alt"></i> 取号
                </button>
                <button class="btn btn-success btn-lg" onclick="callNumber()">
                    <i class="fas fa-bullhorn"></i> 叫号
                </button>
            </div>
            <div class="status-box">
                <h3>当前排队状态</h3>
                <ul id="status"></ul>
            </div>
        </div>
    </div>
</div>

<script>
    const ws = newWebSocket('ws://127.0.0.1:2346');

    ws.onmessage = function(event) {
        const data = JSON.parse(event.data);
        if (data.type === 'call') {
            alert(`叫号:${data.number}`);
        }
    };

    functiongetNumber() {
        fetch('api/queue/getNumber')
            .then(response => response.json())
            .then(data => {
                alert(`取号成功:${data.number}`);
            });
    }

    functioncallNumber() {
        fetch('api/queue/callNumber')
            .then(response => response.json())
            .then(data => {
                alert(`叫号成功:${data.number}`);
            });
    }

    functiongetQueueStatus() {
        fetch('api/queue/getQueueStatus')
            .then(response => response.json())
            .then(data => {
                const statusList = document.getElementById('status');
                statusList.innerHTML = data.status.map(number =>`<li>号码:${number}</li>`).join('');
            });
    }

    // 定时获取排队状态
    setInterval(getQueueStatus, 5000);
</script>

<!-- Bootstrap JS and dependencies -->
<script src="/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="@5.3.0/dist/js/bootstrap.min.js"></script>
</body>
</html>

9. 运行 WebSocket 服务器

在命令行中运行 WebSocket 服务器:

代码语言:javascript代码运行次数:0运行复制
php websocket.php start

10. 运行 ThinkPHP 项目

代码语言:javascript代码运行次数:0运行复制
启动 ThinkPHP 项目:
php websocket.php start
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-03-26,如有侵权请联系 cloudcommunity@tencent 删除DeepSeek服务器管理配置系统