用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 相关的扩展包。

composer require topthink/think-redis
 
 composer require workerman/workerman

3. 配置 Redis

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

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 队列。

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 服务器的逻辑。

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 接口。

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 中配置路由。

use think\facade\Route;
Route::get('queue/getNumber', 'QueueController/getNumber');
Route::get('queue/callNumber', 'QueueController/callNumber');
Route::get('queue/getQueueStatus', 'QueueController/getQueueStatus');

8. 前端实现

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

<!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="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Font Awesome -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.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="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js"></script>
</body>
</html>

9. 运行 WebSocket 服务器

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

php websocket.php start

10. 运行 ThinkPHP 项目

启动 ThinkPHP 项目:
php websocket.php start

关注公众号回复“激活码”,获取2025年最新IDEA激活码

一个简单的银行排队叫号系统可以利用C++的基本结构设计。这里提供一个基本框架,使用线程模拟客户、柜员以及管理队列的过程: ```cpp #include <iostream> #include <thread> #include <queue> #include <mutex> // 客户类 class Customer { public: int id; void checkIn(); }; void Customer::checkIn() { std::cout << "Customer " << id << " checking in." << std::endl; std::unique_lock<std::mutex> lock(queue_mutex); queue.push(this); // 模拟处理时间 std::this_thread::sleep_for(std::chrono::seconds(5)); std::cout << "Customer " << id << " being served by counter " << current_counter << "." << std::endl; } // 柜员类,用于服务客户 class Teller { private: static std::queue<Customer*> queue; static std::mutex queue_mutex; static int current_counter; public: static void serveNext(); }; std::queue<Customer*> Teller::queue; std::mutex Teller::queue_mutex; int Teller::current_counter = 0; void Teller::serveNext() { if (not Teller::queue.empty()) { Customer* customer = Teller::queue.front(); Teller::queue.pop(); current_counter++; customer->checkIn(); } else { std::cout << "No customers waiting." << std::endl; } } int main() { for (int i = 1; i <= 10; ++i) { // 创建10位客户 std::thread customer_thread(Customer{i}, &Teller::serveNext); customer_thread.detach(); // 启动客户线程并立即返回主线程 } while (true) { Teller::serveNext(); // 主线程不断检查是否有新任务 } return 0; } ``` 在这个例子中,`Customer`类代表需要服务的客户,`Teller`类模拟柜员。每个客户线程会自动加入队列等待,然后柜员线程会循环处理队列中的客户。注意这只是一个基础模型,实际应用可能会包含更复杂的功能如叫号显示、客户状态跟踪等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值