no message
This commit is contained in:
parent
8d680d9698
commit
e551f8a0f9
@ -444,16 +444,28 @@ return static function (Slim\App $app): void {
|
||||
//})->add(new NodeApi());
|
||||
|
||||
$app->group('/api/nasa/v1', function (RouteCollectorProxy $group): void {
|
||||
$group->get('/node', App\Controllers\Api\Nasa\V1\NodeController::class . ':index');
|
||||
$group->get('/node/detail/{id}', App\Controllers\Api\Nasa\V1\NodeController::class . ':detail');
|
||||
$group->put('/node/detail/{id}', App\Controllers\Api\Nasa\V1\NodeController::class . ':detailSave');
|
||||
$group->delete('/node/detail/{id}', App\Controllers\Api\Nasa\V1\NodeController::class . ':delete');
|
||||
$group->get('/node/add', App\Controllers\Api\Nasa\V1\NodeController::class . ':add');
|
||||
$group->put('/node/add', App\Controllers\Api\Nasa\V1\NodeController::class . ':addSave');
|
||||
$group->get('/node/clone/{id}', App\Controllers\Api\Nasa\V1\NodeController::class . ':clone');
|
||||
$group->put('/node/clone/', App\Controllers\Api\Nasa\V1\NodeController::class . ':cloneSave');
|
||||
$group->get('/node/hit/{id}/{field}', App\Controllers\Api\Nasa\V1\NodeController::class . ':hit');
|
||||
})->add(new VerifyNasaToken());
|
||||
|
||||
$group->get('/node/base', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':index');
|
||||
$group->get('/node/base/detail/{id}', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':detail');
|
||||
$group->put('/node/base/detail/save/{id}', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':detailSave');
|
||||
$group->delete('/node/base/delete/save/{id}', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':delete');
|
||||
$group->get('/node/base/add', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':add');
|
||||
$group->put('/node/base/add/save', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':addSave');
|
||||
$group->get('/node/base/clone/{id}', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':clone');
|
||||
// $group->put('/node/base/clone/', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':cloneSave');
|
||||
$group->get('/node/base/hit/{id}/{field}', App\Controllers\Api\Nasa\V1\NodeBaseController::class . ':hit');
|
||||
|
||||
$group->get('/env/config', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':index');
|
||||
$group->get('/env/config/detail/{id}', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':detail');
|
||||
$group->put('/env/config/detail/save/{id}', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':detailSave');
|
||||
$group->delete('/env/config/delete/save/{id}', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':delete');
|
||||
$group->get('/env/config/add', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':add');
|
||||
$group->put('/env/config/add/save', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':addSave');
|
||||
$group->get('/env/config/clone/{id}', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':clone');
|
||||
// $group->put('/env/config/clone/', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':cloneSave');
|
||||
$group->get('/env/config/hit/{id}/{field}', App\Controllers\Api\Nasa\V1\EnvConfigController::class . ':hit');
|
||||
|
||||
})->add(new VerifyNasaToken());// get可以其他不可以?
|
||||
|
||||
|
||||
// Route::prefix('setting')->group(function() {
|
||||
|
||||
@ -94,6 +94,13 @@ final class TicketController extends BaseController
|
||||
|
||||
$user = (new User())->find($ticket->userid);
|
||||
|
||||
// MailHub::start()
|
||||
// ->setScene("tk_ry")
|
||||
// ->setTitle($_ENV['appName'] . ' - 工单被回复')
|
||||
// ->setView("one", $a)
|
||||
// ->setTo($email)
|
||||
// ->send();
|
||||
|
||||
Notification::notifyUser(
|
||||
$user,
|
||||
$_ENV['appName'] . ' - 工单被回复',
|
||||
|
||||
@ -61,6 +61,15 @@ abstract class ListController
|
||||
}
|
||||
}
|
||||
|
||||
public function getMapAll()
|
||||
{
|
||||
if (method_exists($this->oModel, 'getMapAll')) {
|
||||
return $this->oModel->getMapAll();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function index(Request $oRequest, Response $oResponse, $args)
|
||||
{
|
||||
if (! $this->oModel) {
|
||||
@ -162,7 +171,7 @@ abstract class ListController
|
||||
'cList' => $oPaginatedData->items(),
|
||||
'aListField' => $this->getListFields(),
|
||||
'aFieldTypes' => $this->aFieldTypes,
|
||||
'aMap' => $this->oModel->getMapAll(),
|
||||
'aMap' => $this->getMapAll(),
|
||||
'aValueStyle' => $this->aValueStyle,
|
||||
'aSelectField' => $this->aSelectFields,
|
||||
'aFilterParam' => $this->aFilterParams,
|
||||
@ -245,37 +254,34 @@ abstract class ListController
|
||||
return $s;
|
||||
}
|
||||
|
||||
public function add(Request $oRequest, Response $oResponse, $args): \Illuminate\Http\JsonResponse
|
||||
public function add(Request $oRequest, Response $oResponse, $args)
|
||||
{
|
||||
// 1. 获取表名
|
||||
$sTableName = $this->oModel->getTable();
|
||||
$aRawFields = Schema::getColumnListing($sTableName);
|
||||
|
||||
$sClassName = get_class($this->oModel);
|
||||
// 2. 修复 500 报错:改用连接对象的 Schema 构建器,彻底解耦门面
|
||||
// 变量命名:oSchemaBuilder (Schema构建器对象) -> 【欧 斯基玛 标德儿】
|
||||
$oSchemaBuilder = $this->oModel->getConnection()->getSchemaBuilder();
|
||||
$aRawFields = $oSchemaBuilder->getColumnListing($sTableName);
|
||||
|
||||
$aKickFields = [];
|
||||
// 3. 大厂正统手法:利用模型原生方法安全获取时间戳字段名(自动处理关闭时间戳的情况)
|
||||
// 变量命名:aKickFields (要剔除的字段数组) -> 【诶 踢客 费尔茨】
|
||||
$aKickFields = ['id'];
|
||||
|
||||
if (defined($sClassName . '::UPDATED_AT')) {
|
||||
$aKickFields[] = constant($sClassName . '::UPDATED_AT');
|
||||
if ($this->oModel->timestamps) {
|
||||
$aKickFields[] = $this->oModel->getCreatedAtColumn();
|
||||
$aKickFields[] = $this->oModel->getUpdatedAtColumn();
|
||||
}
|
||||
|
||||
if (defined($sClassName . '::CREATED_AT')) {
|
||||
$aKickFields[] = constant($sClassName . '::CREATED_AT');
|
||||
}
|
||||
|
||||
$aKickFields[] = "id";
|
||||
|
||||
$aRawFieldsClear = [];
|
||||
foreach ($aRawFields as $aRawField) {
|
||||
if (in_array($aRawField, $aKickFields)) {
|
||||
continue;
|
||||
}
|
||||
$aRawFieldsClear[] = $aRawField;
|
||||
}
|
||||
|
||||
|
||||
// 4. 高效数组过滤:干掉 foreach,改用内置函数完成差集计算
|
||||
// 变量命名:aCleanFields (干净的字段数组) -> 【诶 克林 费尔茨】
|
||||
$aCleanFields = array_values(array_diff($aRawFields, $aKickFields));
|
||||
|
||||
// 5. 标准响应返回
|
||||
return $oResponse->withJson([
|
||||
'iCode' => 200,
|
||||
'aData' => [
|
||||
'cList' => $aRawFieldsClear,
|
||||
'aData' => [
|
||||
'cList' => $aCleanFields, // 保持你原有的前端 Key 兼容
|
||||
'sPageName' => $this->sPageName
|
||||
]
|
||||
], 200);
|
||||
@ -283,44 +289,85 @@ abstract class ListController
|
||||
|
||||
public function clone(Request $oRequest, Response $oResponse, $args)
|
||||
{
|
||||
$iId = $args['id'];
|
||||
// 1. 安全获取参数并查询
|
||||
$iId = $args['id'] ?? 0;
|
||||
// 确保使用 findOrFail,找不到直接抛出 404 异常(由框架底层捕获)
|
||||
$oModelResult = $this->oModel->findOrFail($iId);
|
||||
$cList = $oModelResult->getRawOriginal();
|
||||
|
||||
$sTableName = $this->oModel->getTable();
|
||||
$aStatus = DB::select("SHOW TABLE STATUS LIKE '{$sTableName}'");
|
||||
// 2. 匈牙利命名法修正:获取原始属性数组
|
||||
// 变量命名:aRowAttributes (行属性数组) -> 【诶 柔 艾特里比茨】
|
||||
$aRowAttributes = $oModelResult->getRawOriginal();
|
||||
|
||||
// 3. 修复 500 报错:抛弃 DB 门面,改用解耦的实例调用
|
||||
// 变量命名:oConnection (连接对象) -> 【欧 康内克闪】
|
||||
$oConnection = $this->oModel->getConnection();
|
||||
$sTableName = $this->oModel->getTable();
|
||||
|
||||
// 防御性编程:将原生 SQL 占位绑定,防止潜在注入风险
|
||||
// 直接把表名变量拼进单引号里
|
||||
$aStatus = $oConnection->select("SHOW TABLE STATUS LIKE '{$sTableName}'");
|
||||
$iNextId = $aStatus[0]->Auto_increment ?? 1;
|
||||
|
||||
$cList['id'] = $iNextId;
|
||||
// 4. 移除旧主键,赋予预测的自增 ID(注:若无特殊业务强需求,大厂更倾向于 unset($aRowAttributes['id']))
|
||||
$aRowAttributes['id'] = (int)$iNextId; // 强制强类型转换
|
||||
|
||||
// 5. 健壮的方法存在性检查(呼应你上一条的需求)
|
||||
// 变量命名:aMapData (映射数据数组) -> 【诶 迈普 数据】
|
||||
$aMapData = method_exists($this->oModel, 'getMapAll') ? $this->oModel->getMapAll() : [];
|
||||
|
||||
// 6. 统一标准的 JSON 响应输出
|
||||
return $oResponse->withJson([
|
||||
'iCode' => 200,
|
||||
'aData' => [
|
||||
'cList' => $cList,
|
||||
'aMap' => $this->oModel->getMapAll(),
|
||||
'aData' => [
|
||||
'cList' => $aRowAttributes, // 保持你前端需要的 Key 命名不变
|
||||
'aMap' => $aMapData,
|
||||
'aListField' => $this->getListFields(),
|
||||
'sPageName' => $this->sPageName
|
||||
'sPageName' => $this->sPageName
|
||||
]
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function cloneSave(Request $oRequest, Response $oResponse, $args)
|
||||
{
|
||||
$iId = $args['id'];
|
||||
|
||||
$aParams = $oRequest->getParams();
|
||||
|
||||
foreach ($aParams as $k => $v) {
|
||||
$this->oModal->{$k} = $v;
|
||||
}
|
||||
$this->oModel->create();
|
||||
|
||||
return $oResponse->withJson([
|
||||
'iCode' => 200,
|
||||
'aData' => [],
|
||||
'sMsg' => "保存成功:id ".$this->oModel->id
|
||||
], 200);
|
||||
}
|
||||
// public function clone(Request $oRequest, Response $oResponse, $args)
|
||||
// {
|
||||
// $iId = $args['id'];
|
||||
// $oModelResult = $this->oModel->findOrFail($iId);
|
||||
// $cList = $oModelResult->getRawOriginal();
|
||||
//
|
||||
// $sTableName = $this->oModel->getTable();
|
||||
// $aStatus = DB::select("SHOW TABLE STATUS LIKE '{$sTableName}'");
|
||||
// $iNextId = $aStatus[0]->Auto_increment ?? 1;
|
||||
//
|
||||
// $cList['id'] = $iNextId;
|
||||
//
|
||||
// return $oResponse->withJson([
|
||||
// 'iCode' => 200,
|
||||
// 'aData' => [
|
||||
// 'cList' => $cList,
|
||||
// 'aMap' => $this->oModel->getMapAll(),
|
||||
// 'aListField' => $this->getListFields(),
|
||||
// 'sPageName' => $this->sPageName
|
||||
// ]
|
||||
// ], 200);
|
||||
// } // 原代码是这样
|
||||
|
||||
// public function cloneSave(Request $oRequest, Response $oResponse, $args)
|
||||
// {
|
||||
//// tt(123);
|
||||
// $iId = $args['id'];
|
||||
////dd(123);
|
||||
// $aParams = $oRequest->getParams();
|
||||
//
|
||||
// foreach ($aParams as $k => $v) {
|
||||
// $this->oModel->{$k} = $v;
|
||||
// }
|
||||
// $this->oModel->create();
|
||||
//
|
||||
// return $oResponse->withJson([
|
||||
// 'iCode' => 200,
|
||||
// 'aData' => [],
|
||||
// 'sMsg' => "保存成功:id ".$this->oModel->id
|
||||
// ], 200);
|
||||
// } // 也不行?
|
||||
|
||||
public function detail(Request $oRequest, Response $oResponse, $args)
|
||||
{
|
||||
@ -332,7 +379,7 @@ abstract class ListController
|
||||
'iCode' => 200,
|
||||
'aData' => [
|
||||
'cList' => $cList,
|
||||
'aMap' => $this->oModel->getMapAll(),
|
||||
'aMap' => $this->getMapAll(),
|
||||
'aListField' => $this->getListFields(),
|
||||
'sPageName' => $this->sPageName
|
||||
]
|
||||
@ -365,6 +412,7 @@ abstract class ListController
|
||||
|
||||
public function delete(Request $oRequest, Response $oResponse, $args)
|
||||
{
|
||||
|
||||
$iId = $args['id'];
|
||||
|
||||
$this->oModel->findOrFail($iId)->delete();
|
||||
|
||||
101
src/Controllers/Api/Nasa/V1/EnvConfigController.php
Executable file
101
src/Controllers/Api/Nasa/V1/EnvConfigController.php
Executable file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controllers\Api\Nasa\V1;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Controllers\Api\Nasa\V1\Base\ListController;
|
||||
|
||||
final class EnvConfigController extends ListController
|
||||
{
|
||||
protected string $sModelName = 'Config';
|
||||
protected array $aFilterFields = [ // 允许where的字段,不设视为全允许
|
||||
// 's_name',
|
||||
// 'i_status'
|
||||
];
|
||||
|
||||
protected string $sPageName = "config";
|
||||
|
||||
protected array $aListFields = [ // list展示的字段和名字映射
|
||||
'id' => 'id',
|
||||
'item' => '配置项',
|
||||
'value' => '配置值',
|
||||
'class' => '配置类别',
|
||||
'is_public' => '是否为公共参数',
|
||||
'type' => '配置值类型',
|
||||
'default' => '默认值',
|
||||
'mark' => '备注',
|
||||
];
|
||||
|
||||
// protected array $aValueStyle = [ // 特定文字渲染样式
|
||||
// '关闭' => "<span class='text-danger'>关闭</span>",
|
||||
// '开启' => "<span class='text-success'>开启</span>"
|
||||
// ];
|
||||
|
||||
// protected array $aFieldTypes = [
|
||||
// 'custom_config' => 'json',
|
||||
// 'prev_day_width' => 'byte',
|
||||
// 'node_bandwidth' => 'byte',
|
||||
// 'node_bandwidth_limit' => 'byte'
|
||||
// ];
|
||||
|
||||
protected array $aOrderBy = [
|
||||
[
|
||||
"sField" => "id",
|
||||
"sSort" => "desc",
|
||||
]
|
||||
];
|
||||
|
||||
protected array $aJsonFields = [ // json字段
|
||||
|
||||
];
|
||||
|
||||
protected array $aDateFields = [ // date字段
|
||||
// 'dtUpdatedAt'
|
||||
];
|
||||
|
||||
protected array $aLenthFields = [ // 限制长度的字段
|
||||
// "xx" => 100,
|
||||
];
|
||||
|
||||
protected array $aSelectFields = [ // 作为默认select的字段
|
||||
// 'iStatus',
|
||||
// 'sComponentType',
|
||||
];
|
||||
|
||||
// protected array $aValueFields = [ // 值映射
|
||||
// 'sComponentType' => [
|
||||
// 'TOP_BAR' => '顶级菜单',
|
||||
// 'SIDEBAR_MENU' => '次级菜单',
|
||||
// 'INNER_PAGE_TAB' => '页内菜单',
|
||||
// ]
|
||||
// ];
|
||||
|
||||
protected array $aCcExtFields = [
|
||||
// 'dtCreatedAt' => '创建时间'
|
||||
];
|
||||
|
||||
// protected array $aLimit = [3, 15, 40, 100]; // list长度,第一个为默认
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//CREATE TABLE `nasa_navigation` (
|
||||
// `iId` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
// `iParentId` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '父级ID(0代表顶级导航)',
|
||||
// `sName` varchar(64) NOT NULL COMMENT '导航菜单名称',
|
||||
// `sSlug` varchar(128) NOT NULL DEFAULT '' COMMENT 'Laravel 路由别名(Route Name)',
|
||||
// `sIcon` varchar(64) NOT NULL DEFAULT '' COMMENT '图标 Class/Svg 标识',
|
||||
// `sGroup` varchar(128) NOT NULL DEFAULT '',
|
||||
// `sComponentType` varchar(32) NOT NULL DEFAULT 'SIDEBAR_MENU' COMMENT '渲染组件类型:TOP_BAR, SIDEBAR_MENU, INNER_PAGE_TAB',
|
||||
// `iSort` int(11) NOT NULL DEFAULT 0 COMMENT '排序权重(数值越小越靠前)',
|
||||
// `iStatus` tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否可见:1-显示, 0-隐藏',
|
||||
// `sPermissionSlug` varchar(64) DEFAULT NULL COMMENT '权限标识(用于中间件拦截校验)',
|
||||
// `dtCreatedAt` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '创建时间',
|
||||
// `dtUpdatedAt` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '更新时间',
|
||||
// PRIMARY KEY (`iId`),
|
||||
// KEY `idx_status_parent_sort` (`iStatus`,`iParentId`,`iSort`),
|
||||
// KEY `idx_permission` (`sPermissionSlug`)
|
||||
//) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统功能导航路由表';
|
||||
@ -6,7 +6,7 @@ namespace App\Controllers\Api\Nasa\V1;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Controllers\Api\Nasa\V1\Base\ListController;
|
||||
|
||||
final class NodeController extends ListController
|
||||
final class NodeBaseController extends ListController
|
||||
{
|
||||
protected string $sModelName = 'Node';
|
||||
protected array $aFilterFields = [ // 允许where的字段,不设视为全允许
|
||||
@ -25,10 +25,11 @@ final class NodeController extends ListController
|
||||
'sort' => 'sort',
|
||||
'traffic_rate' => '倍率',
|
||||
'node_class' => 'node_class',
|
||||
'node_speedlimit' => '限速',
|
||||
'prev_day_width' => 'prev_day_width',
|
||||
'node_bandwidth' => 'node_bandwidth',
|
||||
'node_bandwidth_limit' => 'node_bandwidth_limit',
|
||||
'bandwidthlimit_resetday'=> 'bandwidthlimit_resetday',
|
||||
'node_speedlimit' => '限速',
|
||||
'node_heartbeat' => 'node_heartbeat',
|
||||
'online_user' => 'online_user',
|
||||
'ipv4' => 'ipv4',
|
||||
@ -46,7 +47,6 @@ final class NodeController extends ListController
|
||||
'memo_front' => 'memo_front',
|
||||
'fly' => 'fly',
|
||||
'pid' => 'pid',
|
||||
'prev_day_width' => 'prev_day_width',
|
||||
'country_code' => 'country_code',
|
||||
'country_emoji' => 'country_emoji',
|
||||
];
|
||||
@ -8,6 +8,7 @@ use App\Models\Config;
|
||||
use App\Utils\Tools;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
use RedisException;
|
||||
use App\Services\MailHub;
|
||||
|
||||
final class Password
|
||||
{
|
||||
@ -25,13 +26,25 @@ final class Password
|
||||
$subject = $_ENV['appName'] . ' - 重置密码';
|
||||
$resetUrl = $_ENV['baseUrl'] . '/password/token/' . $token;
|
||||
|
||||
Mail::send(
|
||||
$email,
|
||||
$subject,
|
||||
'password_reset.tpl',
|
||||
[
|
||||
'resetUrl' => $resetUrl,
|
||||
]
|
||||
);
|
||||
$a = [
|
||||
'resetUrl' => $resetUrl,
|
||||
];
|
||||
|
||||
MailHub::start()
|
||||
->setScene("pwd_reset")
|
||||
->setTitle($subject)
|
||||
->setView("password_reset", $a)
|
||||
->setTo($email)
|
||||
->send();
|
||||
|
||||
// Mail::send(
|
||||
// $email,
|
||||
// $subject,
|
||||
// 'password_reset.tpl',
|
||||
// [
|
||||
// 'resetUrl' => $resetUrl,
|
||||
// ]
|
||||
// );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user