- 18 张公共表更名(addon/attachment/configure/links/spider_log/spider_stat/sms/notice/ad/task/prop/medal/help/card -> common_*,member_wallets->member_wallet,score_rule/score_log -> member_*,addon_config->common_addonconf),模型全部对齐新表名,Db 直引用清零 - Attachment 模型补 表名绑定,修复富文本上传查 wxapp_attachment 1146 隐患 - install.sql + 迁移 SQL:backend_admin/backend_role delete_at 默认 0,修复软删除(NULL != 0)误过滤导致后台菜单为空 - AppService::boot() 支持插件 info.php 声明 commands 自动注册插件命令(psr-4 自动加载,坏类名自动跳过) - 各插件(haonav/mqttbroker/wxchat/articles/blog/forum 等)字段与配置同步调整 - 框架版本 1.1.0 -> 1.1.1
111 lines
3.8 KiB
PHP
111 lines
3.8 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Author: ywxapp<admin@ywxapp.cn>
|
||
// +----------------------------------------------------------------------
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace addon\mqttbroker\controller\api;
|
||
|
||
use think\facade\Db;
|
||
use ywxapp\controller\ApiBase;
|
||
use addon\mqttbroker\service\Store;
|
||
|
||
/**
|
||
* App 端 MQTT API(需框架会员 JWT 登录)
|
||
* 路由前缀:/mqttbroker/api/...
|
||
*/
|
||
class App extends ApiBase
|
||
{
|
||
/**
|
||
* 当前会员账号(Broker 连接用户名通常为 member.account)
|
||
*/
|
||
protected function memberAccount(): string
|
||
{
|
||
return (string) ($this->auth->model->account ?? '');
|
||
}
|
||
|
||
/**
|
||
* 我的设备 / 连接列表
|
||
* GET /mqttbroker/api/devices
|
||
*/
|
||
public function devices()
|
||
{
|
||
$account = $this->memberAccount();
|
||
if ($account === '') {
|
||
return $this->result->error('无法获取当前会员账号');
|
||
}
|
||
$list = Db::name('mqttbroker_connection')
|
||
->where('username', $account)
|
||
->order('update_at', 'desc')
|
||
->limit(200)
|
||
->field('client_id,username,ip,status,create_at,update_at')
|
||
->select()
|
||
->toArray();
|
||
return $this->result->success(['list' => $list, 'total' => count($list)]);
|
||
}
|
||
|
||
/**
|
||
* 我的订阅主题列表
|
||
* GET /mqttbroker/api/subscriptions
|
||
*/
|
||
public function subscriptions()
|
||
{
|
||
$account = $this->memberAccount();
|
||
if ($account === '') {
|
||
return $this->result->error('无法获取当前会员账号');
|
||
}
|
||
$clientIds = Db::name('mqttbroker_connection')
|
||
->where('username', $account)
|
||
->column('client_id');
|
||
$list = [];
|
||
if ($clientIds) {
|
||
$list = Db::name('mqttbroker_topic')
|
||
->whereIn('client_id', $clientIds)
|
||
->order('id', 'desc')
|
||
->field('client_id,topic,qos,create_at')
|
||
->select()
|
||
->toArray();
|
||
}
|
||
return $this->result->success(['list' => $list, 'total' => count($list)]);
|
||
}
|
||
|
||
/**
|
||
* 发布消息(服务端代发,强制命名空间隔离)
|
||
* POST /mqttbroker/api/publish
|
||
* param: topic, payload, qos(0/1/2), retain(0/1)
|
||
*/
|
||
public function publish()
|
||
{
|
||
$account = $this->memberAccount();
|
||
if ($account === '') {
|
||
return $this->result->error('无法获取当前会员账号');
|
||
}
|
||
$topic = trim((string) $this->request->post('topic', ''));
|
||
$payload = (string) $this->request->post('payload', '');
|
||
$qos = (int) $this->request->post('qos', 0);
|
||
$retain = (int) $this->request->post('retain', 0);
|
||
|
||
if ($topic === '' || $topic[0] === '$') {
|
||
return $this->result->error('主题不能为空,且禁止发布到 $SYS 等系统主题');
|
||
}
|
||
// 命名空间隔离:topic 必须以 {username}/ 开头,避免越权发到他人主题
|
||
$prefix = $account . '/';
|
||
if (strncmp($topic, $prefix, strlen($prefix)) !== 0) {
|
||
return $this->result->error("主题必须以 {$prefix} 开头(命名空间隔离)");
|
||
}
|
||
if (!in_array($qos, [0, 1, 2], true)) {
|
||
$qos = 0;
|
||
}
|
||
$ok = Store::enqueueManual($topic, $payload, $qos, $retain, 'app');
|
||
if (!$ok) {
|
||
return $this->result->error('发布失败,请稍后重试');
|
||
}
|
||
return $this->result->success(['topic' => $topic]);
|
||
}
|
||
}
|