Files
chatroom/DEVELOPMENT.md
2026-02-26 12:02:00 +08:00

20 KiB
Raw Blame History

ChatRoom 开发计划与注意事项

技术栈Laravel 12 · PHP 8.4 · Laravel Reverb (WebSocket) · Redis · MySQL 8.0 · Laravel Horizon 原项目/Users/pllx/Web/chat/hp0709VBScript ASP + MS Access 聊天室) 目标域名http://chatroom.testHerd 自动配置)


一、环境版本要求

组件 版本
PHP 8.4.5+
Laravel Framework v12.x
Laravel Reverb latestWebSocket 服务器)
Laravel Horizon v5Redis 队列可视化管理)
PHPUnit v11测试框架
Node.js 20.x LTS
MySQL 8.0+
Redis 7.x

二、代码规范(强制执行)

2.1 Laravel Pint 格式化

# 提交代码前必须运行,修复格式问题
vendor/bin/pint --dirty

# 检查格式问题(不修复)
vendor/bin/pint --test

# 格式化整个项目
vendor/bin/pint

2.2 PHP 8.4 类型系统(必须遵守)

// ✅ 正确:构造函数属性提升 (Constructor Property Promotion)
class ChatController extends Controller
{
    public function __construct(
        private readonly ChatStateService    $chatState,
        private readonly MessageFilterService $filter,
    ) {}
}

// ❌ 错误:不允许无参空构造函数
class SomeClass
{
    public function __construct() {} // 禁止!
}

// ✅ 正确:显式返回类型 + 参数类型提示
public function send(SendMessageRequest $request): JsonResponse
{
    // ...
}

// ✅ 正确:使用 PHP 8.4 新特性
// 联合类型
public function findUser(int|string $id): User|null {}

// readonly 属性
class MessageDto
{
    public function __construct(
        public readonly string $content,
        public readonly string $fromUser,
        public readonly int    $roomId,
    ) {}
}

2.3 Laravel 12 中间件配置(重要)

Important

Laravel 12 已废弃 Kernel.php,中间件在 bootstrap/app.php 中配置。

// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',          // API 路由
        channels: __DIR__.'/../routes/channels.php', // WebSocket 频道
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        // 注册聊天室登录验证中间件
        $middleware->alias([
            'chat.auth'    => \App\Http\Middleware\ChatAuthenticate::class,
            'chat.level'   => \App\Http\Middleware\LevelRequired::class,
        ]);

        // Session 中间件Web 路由自动携带)
        $middleware->web(append: [
            \App\Http\Middleware\HandleInertiaRequests::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })->create();

2.4 中文注释规范(每个文件必须)

<?php

/**
 * 文件功能:[本文件的业务职责描述]
 *
 * 对应原 ASP 文件:[原文件名.asp]
 *
 * @package  App\[命名空间]
 * @author   ChatRoom Laravel
 * @version  1.0.0
 */

namespace App\Services;

class ChatStateService
{
    /**
     * 用户进入聊天房间,将其信息写入 Redis。
     *
     * 替代原 ASP 的 Application("_user_list") 字符串拼接操作。
     *
     * @param  int    $roomId    房间 ID
     * @param  string $username  用户名
     * @param  array  $userInfo  用户信息(等级、头像、性别等)
     */
    public function userJoin(int $roomId, string $username, array $userInfo): void
    {
        // 将用户信息序列化后存入 Redis HashKey 为 "room:{房间ID}:users"
        $this->redis->hset("room:{$roomId}:users", $username, json_encode($userInfo));
    }
}

三、首次启动(必须先执行)

cd /Users/pllx/Web/Herd/chatroom

# 安装 Reverb WebSocket 服务器(已经完成)
composer require laravel/reverb predis/predis

# 安装 Horizon 队列管理(替代 queue:work提供 Web 监控面板)
composer require laravel/horizon

# 发布配置文件
php artisan reverb:install
php artisan horizon:install

# 创建数据库(已经完成)
mysql -u root -proot -e "CREATE DATABASE IF NOT EXISTS chatroom CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# 运行数据库迁移(迁移前检查原有迁移文件是否有用)
php artisan migrate

# 安装前端依赖
npm install (已经完成)
npm install laravel-echo pusher-js已经完成
npm run dev

开发时运行的服务

php artisan reverb:start --debug   # WebSocket 服务器 :8080
php artisan horizon                 # 队列 Worker含 Web 监控 /horizon
npm run dev                        # Vite 热更新
# HTTP 由 Herd 自动提供 chatroom.test

四、数据库迁移对照表

原 Access 表Laravel Migration 对应关系:

原 ASP 表 Laravel 迁移文件 Model 类 说明
user create_users_table User 主用户表(默认迁移文件,需修改)
room create_rooms_table Room 聊天房间
(内存) create_messages_table Message 消息归档(原用 Application 内存)
sysparam create_sys_params_table SysParam 系统参数
ip_lock create_ip_locks_table IpLock IP 封锁
record create_audit_logs_table AuditLog 管理操作日志
guestbook create_guestbooks_table Guestbook 留言板
calls create_friend_calls_table FriendCall 好友呼叫
friendrq create_friend_requests_table FriendRequest 好友申请
action create_actions_table Action 表情/动作定义
admincz create_admin_logs_table AdminLog 管理员操作统计
gg create_user_items_table UserItem 道具(封口令等)
scrollad create_scroll_ads_table ScrollAd 滚动公告
hy / lh create_marriages_table Marriage 婚姻关系
ip create_ip_logs_table IpLog IP 登录日志
room_des create_room_descriptions_table RoomDescription 房间描述模板

批量生成迁移命令

php artisan make:migration create_rooms_table
php artisan make:migration create_messages_table
php artisan make:migration create_sys_params_table
php artisan make:migration create_ip_locks_table
php artisan make:migration create_audit_logs_table
php artisan make:migration create_guestbooks_table
php artisan make:migration create_friend_calls_table
php artisan make:migration create_friend_requests_table
php artisan make:migration create_actions_table
php artisan make:migration create_admin_logs_table
php artisan make:migration create_user_items_table
php artisan make:migration create_scroll_ads_table
php artisan make:migration create_marriages_table
php artisan make:migration create_ip_logs_table
php artisan make:migration create_room_descriptions_table

五、推荐目录结构

app/
├── Events/                         # WebSocket 广播事件ShouldBroadcast
│   ├── MessageSent.php             # 消息发送(替代 NEWSAY.ASP
│   ├── UserJoined.php              # 用户进房(替代 INIT.ASP
│   ├── UserLeft.php                # 用户离开(替代 LEAVE.ASP
│   ├── UserKicked.php              # 踢人
│   ├── UserMuted.php               # 封口
│   └── RoomTitleUpdated.php        # 房间标题更新
│
├── Services/                       # 业务逻辑服务层(纯 PHP不含 HTTP 逻辑)
│   ├── ChatStateService.php        # Redis 全局状态(替代 Application 对象)
│   ├── MessageFilterService.php    # 敏感词/HTML 过滤
│   ├── AuthService.php             # 登录验证逻辑
│   └── UserLevelService.php        # 等级权限判断(替代 getLevel()
│
├── Http/
│   ├── Controllers/
│   │   ├── AuthController.php      # DEFAULT.asp + CHECK.asp + CLOSE.ASP
│   │   ├── RegisterController.php  # Reg.asp + addnewuser.asp
│   │   ├── ChatController.php      # NEWSAY.ASP + INIT.ASP + LEAVE.ASP
│   │   ├── RoomController.php      # ROOM*.ASP 系列
│   │   ├── UserController.php      # USERSET + DOUSER + KILLUSER
│   │   ├── FriendController.php    # addfriend + agreefriend 等
│   │   ├── GuestbookController.php # GUEST.ASP
│   │   └── Admin/
│   │       ├── AdminController.php
│   │       ├── UserManagerController.php
│   │       └── SystemController.php # VIEWSYS.ASP
│   │
│   ├── Middleware/
│   │   ├── ChatAuthenticate.php    # 聊天室登录验证
│   │   └── LevelRequired.php       # 等级权限中间件用法chat.level:5
│   │
│   └── Requests/                   # Form Request 验证
│       ├── LoginRequest.php
│       ├── SendMessageRequest.php
│       └── CreateRoomRequest.php
│
├── Models/
│   ├── User.php
│   ├── Room.php
│   ├── Message.php
│   ├── SysParam.php
│   ├── IpLock.php
│   └── ...
│
└── Jobs/
    └── SaveMessageJob.php          # 异步将消息持久化到 MySQL

bootstrap/
└── app.php                         # ⚠ Laravel 12中间件/路由在此配置(无 Kernel.php

routes/
├── web.php                         # 所有 HTTP 路由
├── api.php                         # API 路由Horizon 监控等)
└── channels.php                    # WebSocket Presence Channel 鉴权

resources/
├── views/
│   ├── index.blade.php             # 登录页DEFAULT.asp
│   ├── chat/
│   │   ├── frame.blade.php         # 聊天主框架CHAT.ASP
│   │   └── room.blade.php          # 消息区
│   └── ...
└── js/
    ├── app.js
    └── chat.js                     # Laravel Echo 替代 newChat.js

六、具体开发任务计划

已完成

  • 创建 Laravel 12 项目
  • 安装 laravel/reverbpredis/predis
  • 创建 MySQL 数据库 chatroom
  • 配置 .envMySQL root/root · Redis · Reverb · 时区 Asia/Shanghai

🔲 第一阶段:数据库层(预计 1-2 天)

目标:所有表创建完毕,并完成基础 Seeder。

  • 修改默认 users 迁移,对应 ASP user 表字段username/passwd/sex/user_level/exp_num/friends/headface/等)
  • 创建 rooms 迁移room_name/owner/auto/des/title/permit_level/door_open
  • 创建 messages 迁移room_id/from_user/to_user/content/is_secret/font_color/action/sent_at
  • 创建 sys_params 迁移alias/guidetxt/body
  • 创建 ip_locks 迁移ip/end_time/act_level
  • 创建 audit_logs 迁移occ_time/occ_env/stype
  • 创建 guestbooks 迁移who/towho/secret/ip/post_time/text_title/text_body
  • 创建 friend_calls 迁移who/towho/callmess/calltime/read
  • 创建 friend_requests 迁移who/towho/sub_time
  • 创建 actions 迁移act_name/alias/toall/toself/toother
  • 创建 user_items 迁移name/gg/times/dayy/lx — 对应道具/封口令等)
  • 创建 scroll_ads 迁移ad_title/ad_link/ad_new_flag
  • 创建 marriages 迁移hyname/hyname1/hytime/hygb/hyjb
  • 创建 ip_logs 迁移ip/sdate/uuname
  • 创建所有 Model 文件(含 $fillable$casts、关联关系、中文 DocBlock
  • 创建 SysParamSeeder写入系统默认参数maxpeople/namelength/maxsayslength 等)
  • 运行 php artisan migrate --seed,验证建表成功

🔲 第二阶段Auth 认证(预计 1-2 天)

目标:用户能够登录、注册、退出。

  • LoginRequest验证username/password/captcha 验证码)
  • AuthController::index() — 登录页(含验证码生成,替代 session("regjm")
  • AuthController::check() — 登录验证(含 IP 封锁检查 + 密码 MD5/bcrypt 双模式)
  • AuthController::logout() — 退出并清理 Redis 用户状态
  • RegisterController::show() — 注册页
  • RegisterController::store() — 注册逻辑(含 IP 注册频率限制)
  • ChatAuthenticate 中间件 — 检查 Session 是否有效,无则跳转登录页
  • LevelRequired 中间件 — 检查用户等级,不足则拒绝(chat.level:5
  • bootstrap/app.php 注册以上中间件别名
  • 登录 Blade 视图 resources/views/index.blade.php(仿原 DEFAULT.asp 样式)
  • 测试:注册 → 登录 → 退出完整流程

🔲 第三阶段Redis 状态层(预计 1 天)

目标ChatStateService 完整实现,替代原 Application 对象。

  • ChatStateService 实现以下方法(全部带中文注释):
    • userJoin(int $roomId, string $username, array $info): void
    • userLeave(int $roomId, string $username): void
    • getRoomUsers(int $roomId): array
    • pushMessage(int $roomId, array $message): void
    • getNewMessages(int $roomId, int $lastId): array
    • nextMessageId(int $roomId): intRedis 自增计数器)
    • withLock(string $key, callable $callback): mixed(分布式锁)
    • getSysParam(string $alias): string读取系统参数缓存1分钟
  • MessageFilterService — 敏感词替换 + HTML 过滤(替代 TrStr() / SHTM() 函数)
  • UserLevelService — 从 Redis 读取当前用户等级

🔲 第四阶段WebSocket 广播(预计 1 天)

目标Reverb 正常运行,前端能收到实时消息。

  • MessageSent Eventimplement ShouldBroadcast)— 广播到 room.{id} Presence Channel
  • UserJoined Event — 用户进入广播
  • UserLeft Event — 用户离开广播
  • UserKicked Event — 踢人广播(私有频道,只发给被踢人)
  • UserMuted Event — 封口广播
  • RoomTitleUpdated Event — 标题更新广播
  • routes/channels.php — Presence Channel 鉴权(验证等级 + 返回用户信息)
  • resources/js/chat.js — Laravel Echo 接入(Echo.join('room.X').here().joining().leaving().listen()
  • 运行 php artisan reverb:start --debug,测试 WebSocket 连通性

🔲 第五阶段:聊天核心(预计 2-3 天)

目标:进房、发言、离开完整流程可用。

  • ChatController::init() — 进入房间(读取 Redis 用户列表 + 历史消息,替代 INIT.ASP
  • ChatController::send() — 发言(过滤 → 推 Redis → SaveMessageJob → 广播 Event
  • ChatController::leave() — 离开房间(清 Redis → 广播 UserLeft
  • SaveMessageJob — 实现 ShouldQueue,异步写消息到 messages
  • 聊天 Blade 视图 resources/views/chat/frame.blade.php(主框架,含 Vite 引入)
  • 测试:登录 → 进房 → 发言 → 另一浏览器实时收到消息

🔲 第六阶段:房间管理(预计 2 天)

  • RoomController::list() — 房间列表(替代 ROOMLIST.ASP
  • RoomController::create() / store() — 创建房间(替代 NEWROOM.ASP
  • RoomController::edit() / update() — 修改设置(替代 ROOMSET.ASP
  • RoomController::destroy() — 删除/解散房间(替代 CUTROOM.ASP
  • RoomController::transfer() — 转让房主(替代 OVERROOM.ASP
  • 对应 Blade 视图

🔲 第七阶段:用户管理(预计 2 天)

  • UserController::info() — 用户信息(替代 USERinfo.ASP
  • UserController::update() — 修改个人资料(替代 USERSET.ASP
  • UserController::kick() — 踢人(替代 KILLUSER.ASP广播 UserKicked
  • UserController::mute() — 封口(道具 user_items 表操作)
  • UserController::changePassword() — 改密码(替代 chpasswd.asp

🔲 第八阶段:管理后台(预计 3-5 天)

  • LevelRequired 中间件 保护 /admin 路由(需 level=15
  • Admin\SystemController — 系统参数配置(替代 VIEWSYS.ASP
  • Admin\UserManagerController — 用户管理列表(替代 gl/ 目录)
  • Admin\SqlController — 后台 SQL 执行(替代 SQL.asp⚠ 仅 SELECT
  • Horizon 面板 /horizon(队列监控,替代后台日志查看)
  • 对应 Blade 视图

🔲 第九阶段:附加功能(按需)

  • 好友系统FriendController
  • 留言板GuestbookController
  • 排行榜RankController
  • 会员系统(huiyuan/ 对应功能)
  • 滚动公告ScrollAd 管理)

七、注意事项

7.1 密码兼容策略

  • 导入旧数据时,password 字段存原始 MD5 值32位字符串
  • 登录时双模式验证:md5($input) === $storedPass 成功后升级为 bcrypt
  • 新注册用户直接用 bcryptHash::make()
  • 约 3 个月后移除 MD5 兼容分支

7.2 字符编码

  • 原 Access 数据库为 GBK 编码
  • 所有 MySQL 表必须 utf8mb4_unicode_ci
  • 导入历史数据前转换:
    iconv -f GBK -t UTF-8 原文件.csv > 目标文件_utf8.csv
    

7.3 REFRESH.ASP 已废弃

原系统的 6 秒 <meta http-equiv=refresh> 完全由 Reverb WebSocket 实时推送取代,无需任何轮询逻辑。

7.4 Application 对象替代

原 ASP Laravel 替代
Application("_user_list") Redis::hgetall("room:{id}:users")
Application("_says") 环形缓冲 Redis::lrange("room:{id}:messages", 0, 199)
Application("_room_list") Redis::get("room:{id}:info") + rooms
Application.Lock/Unlock Cache::lock("key", 10)->block(5, fn)

7.5 Flash 游戏(暂不处理)

game/pig/Gupiao/ 等目录内的 .swf Flash 文件现代浏览器已不支持,本期不做转换,后续单独用 HTML5/Canvas 重写。


八、常用命令速查

# 创建 Model + Migration-m 同时生成迁移)
php artisan make:model Room -m

# 创建 Controller-r 生成 RESTful 方法)
php artisan make:controller ChatController

# 创建广播 Event
php artisan make:event MessageSent

# 创建队列 Job
php artisan make:job SaveMessageJob

# 创建 Middleware
php artisan make:middleware ChatAuthenticate

# 创建 Form Request
php artisan make:request SendMessageRequest

# 重置迁移(开发阶段)
php artisan migrate:fresh --seed

# 查看路由列表
php artisan route:list --columns=method,uri,name,action

# 代码格式化(提交前必须运行)
vendor/bin/pint --dirty

# Horizon 队列监控(生产环境)
php artisan horizon

# 重启 Horizon更新代码后
php artisan horizon:terminate

# 清理所有缓存
php artisan optimize:clear

原 ASP 源码参考路径:/Users/pllx/Web/chat/hp0709/ 数据库 SQL 参考:/Users/pllx/Web/chat/hp0709_php/database.sql