thinkphp需依赖统一数据库表think_task_state实现跨设备任务同步:通过device_id标识设备、行锁抢占执行权、状态机原子更新,确保多端任务状态一致。

ThinkPHP本身不提供跨设备任务同步能力,所谓“电脑与手机任务无缝衔接”必须依托外部状态服务实现:本地定时任务无法跨设备感知执行状态,模型事件触发的钩子只在当前请求生命周期内有效,所有设备共用同一数据库表时,需自行设计任务队列、唯一锁标识、设备上下文标记及心跳续期机制。
统一任务状态存储中心
所有设备必须读写同一个持久化任务状态表,不能依赖本地文件或内存缓存。否则手机标记“已完成”的任务,在电脑端仍显示“待处理”。
在主数据库中新建表think_task_state,字段至少包含:id(BIGINT主键)、task_code(VARCHAR(64),唯一业务码)、status(TINYINT,0=待执行/1=执行中/2=已完成/3=失败)、device_id(VARCHAR(128),记录最后操作设备标识)、updated_at(DATETIME,自动更新)。
执行SQL语句创建表:CREATE TABLE `think_task_state` (`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `task_code` VARCHAR(64) NOT NULL, `status` TINYINT NOT NULL DEFAULT 0, `device_id` VARCHAR(128) NOT NULL, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_task_code` (`task_code`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
确保该表在所有设备连接的数据库中均存在且结构一致——【不同设备连错库会导致状态彻底割裂】。
任务触发端:生成带设备指纹的原子任务
方法一:使用命令行任务 + 设备标识注入
在电脑端执行 php think task:sync --code=backup_report --device=pc-2026-06-06-001;手机端执行 php think task:sync --code=backup_report --device=mobile-xiaomi-13-pro。
在app/command/TaskSync.php中,获取--device参数后,先upsert到think_task_state表:Db::name('task_state')->update(['task_code' => $code, 'status' => 0, 'device_id' => $device, 'updated_at' => date('Y-m-d H:i:s')], ['task_code' => $code], ['task_code' => $code, 'status' => 0, 'device_id' => $device, 'updated_at' => date('Y-m-d H:i:s')], true)。
方法二:Web端提交时绑定UA与IP哈希生成设备指纹
控制器中调用md5($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'])作为device_id写入,避免用户手动伪造。注意:Nginx反向代理下需配置real_ip_header,否则REMOTE_ADDR始终是127.0.0.1。
任务执行端:多设备竞争锁与状态跃迁
第一步:查询并抢占任务
执行SELECT * FROM think_task_state WHERE task_code = 'backup_report' AND status = 0 FOR UPDATE;若返回空,则说明已被其他设备抢走,直接退出。
第二步:更新状态为“执行中”并绑定本机device_id
用UPDATE think_task_state SET status = 1, device_id = 'pc-2026-06-06-001', updated_at = NOW() WHERE task_code = 'backup_report' AND status = 0;MySQL行级锁保证仅一条UPDATE成功,其余返回影响行数0。
第三步:执行实际业务逻辑
例如调用ReportService::generateAndUpload()生成报表并上传至OSS;此过程可能耗时数秒,期间状态保持为1,其他设备轮询时不会重复触发。
第四步:根据结果原子更新终态
成功则UPDATE ... SET status = 2;失败则SET status = 3,并将错误信息写入扩展字段error_msg(需提前在表中添加该TEXT字段)。【禁止先查再更新——中间可能被其他设备修改,必须用WHERE条件+单条UPDATE保证一致性】。
任务监控端:跨设备实时状态拉取
手机App和PC Web管理后台都通过/api/v1/task/status?code=backup_report接口获取最新状态。
接口逻辑直接查think_task_state表,返回JSON:{"code":"backup_report","status":2,"device_id":"pc-2026-06-06-001","updated_at":"2026-06-06 11:42:18"}。
前端据此渲染按钮状态:status=0显示“开始同步”,status=1显示“同步中(由xxx设备执行)”,status=2显示绿色对勾+“已完成”,status=3显示红色叹号+“失败,请重试”。
轮询间隔设为5秒,首次加载后立即发起,避免用户手动刷新才看到变化。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











