更新若干功能

This commit is contained in:
2026-08-19 08:16:49 +08:00
parent 4979bb83d2
commit 72bc6502eb
56 changed files with 3627 additions and 343 deletions

View File

@@ -46,6 +46,8 @@ class MaterialController extends BaseController
*/
public function syncFromOss(): JsonResponse
{
// 七牛要先查区域再列举,再加一批 insert默认 30s 很容易被网关/PHP 掐死
cc_set_time_limit();
$this->insertField = ['oss_config_id'];
$this->notRequest = ['prefix', 'marker', 'limit'];
$params = $this->checkRequiredFields(request()->post());

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\Api;
use App\BaseApp\BaseController;
use App\Service\business\PackageService;
use Illuminate\Http\JsonResponse;
/**
* 后台套餐搭配
*/
class PackageController extends BaseController
{
public function __construct()
{
parent::__construct();
$this->service = PackageService::getInstance();
$this->insertField = ['name'];
$this->updateField = ['id', 'name'];
$this->notRequest = ['cover', 'subtitle', 'remark', 'is_hot', 'sort', 'status', 'package_amount'];
}
/**
* 上架 / 下架
* @Method POST
*/
public function status(): JsonResponse
{
return jok(
$this->service->status((int) request()->post('id'), request()->post('status')),
'操作成功'
);
}
/**
* 保存搭配明细并重算原价 / 补差价
* @Method POST
*/
public function saveItems(): JsonResponse
{
return jok($this->service->saveItems(request()->post()), '搭配已保存');
}
/**
* 搭配搜索:带回封面和规格,无有效报价的规格 selectable=false
* @Method GET
*/
public function searchCatalog(): JsonResponse
{
return jok($this->service->searchCatalog());
}
}

View File

@@ -19,7 +19,7 @@ class WxAppController extends BaseController
$this->updateField = ['id'];
$this->notRequest = [
'app_secret', 'mch_id', 'mch_key', 'mch_serial_no', 'mch_private_key',
'platform_public_key', 'notify_url', 'template_code', 'remark', 'name', 'app_id',
'platform_public_key', 'notify_url', 'template_code', 'package_enabled', 'remark', 'name', 'app_id',
];
}

View File

@@ -0,0 +1,61 @@
<?php
namespace App\Http\Controllers\Api;
use App\BaseApp\BaseController;
use App\Service\business\WxCardSchemeService;
use App\Service\business\WxTemplateSchemaService;
use Illuminate\Http\JsonResponse;
/**
* 小程序卡片画布方案
*/
class WxCardSchemeController extends BaseController
{
public function __construct()
{
parent::__construct();
$this->service = WxCardSchemeService::getInstance();
$this->insertField = ['name', 'code'];
$this->updateField = ['id'];
$this->notRequest = [
'preview', 'layers', 'is_preset', 'app_code', 'sort', 'name', 'code', 'status',
];
}
/**
* 另存为自定义方案
* @Method POST
*/
public function saveAs(): JsonResponse
{
return jok($this->service->saveAs(request()->post()), '已另存为方案');
}
/**
* 灌入 15 套内置预设
* @Method POST
*/
public function initPresets(): JsonResponse
{
return jok(
$this->service->initPresets((bool) request()->post('overwrite', false)),
'卡片预设初始化完成'
);
}
/**
* 图层白名单,画布编辑器渲染控件用
* @Method GET
*/
public function schema(): JsonResponse
{
return jok([
'types' => WxTemplateSchemaService::LAYER_TYPES,
'binds' => WxTemplateSchemaService::LAYER_BINDS,
'fonts' => WxTemplateSchemaService::LAYER_FONTS,
'faces' => WxTemplateSchemaService::LAYER_FACES,
'assets' => WxTemplateSchemaService::DECO_ASSETS,
]);
}
}

View File

@@ -66,7 +66,7 @@ class WxTemplateController extends BaseController
}
/**
* 用内置 20 套预设初始化模板库
* 用内置 4 轻奢预设初始化模板库,并顺带灌 15 套卡片方案
* @Method POST
*/
public function initPresets(): JsonResponse
@@ -78,14 +78,11 @@ class WxTemplateController extends BaseController
}
/**
* 令牌与布局的可选项,前端渲染编辑表单用
* 令牌与布局的可选项,装修工作室渲染表单用
* @Method GET
*/
public function schema(): JsonResponse
{
return jok([
'tokens' => WxTemplateSchemaService::TOKEN_SCHEMA,
'layout' => WxTemplateSchemaService::LAYOUT_SCHEMA,
]);
return jok(WxTemplateSchemaService::getInstance()->describe());
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers\Wx;
use App\BaseApp\BaseController;
use App\Service\wx\WxPackageService;
use Illuminate\Http\JsonResponse;
/**
* 小程序套餐(热门/列表/详情免登录,一件加入走 Service 内登录校验)
*/
class PackageController extends BaseController
{
protected array $exceptRoute = ['option', 'create', 'update', 'delete'];
public function __construct()
{
parent::__construct();
$this->service = WxPackageService::getInstance();
}
/**
* 首页热门套餐
* @Method GET
*/
public function hot(): JsonResponse
{
return jok($this->service->hot());
}
/**
* 套餐详情p_user_id 为代理商分享来源(与商品详情同一套)
* @Method GET
*/
public function detail(): JsonResponse
{
return jok($this->service->detail(
(int) request()->get('id', 0),
(int) request()->get('p_user_id', 0)
));
}
/**
* 一件加入清单
* @Method POST
*/
public function toList(): JsonResponse
{
return jok($this->service->toList(request()->post()), '已加入清单');
}
}

View File

@@ -128,7 +128,8 @@ class ApiOpLogMiddleware
$secret = hash('sha256', $secret !== '' ? $secret : 'nl_admin_jwt_fallback_secret');
}
$decoded = JWT::decode($token, new Key($secret, 'HS256'));
return (int) ($decoded->data->id ?? 0);
$data = \App\Service\common\JWTService::getInstance()->extractUserData($decoded);
return (int) ($data['id'] ?? 0);
} catch (\Throwable $e) {
return 0;
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* 小程序响应 HTTPS 改写
*
* 对齐老 lgp-wx-api ApiMiddleware::checkHttp成功包code=0)里递归把
* result 中的 http:// 换成 https://,满足微信小程序对图片等资源的 HTTPS 要求。
* 仅挂在 /api/wx/*,不改管理端接口;不写库,只做出站改写。
*/
class WxHttpsRewriteMiddleware
{
/**
* 处理完控制器后改写成功响应的 result
*/
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
if (!$response instanceof JsonResponse) {
return $response;
}
$payload = $response->getData(true);
if (!is_array($payload)) {
return $response;
}
// 与 jok 约定一致:成功 code 为 0字符串 "0" 一并兼容
if (($payload['code'] ?? null) != 0 || !array_key_exists('result', $payload)) {
return $response;
}
$payload['result'] = $this->checkHttp($payload['result']);
$response->setData($payload);
return $response;
}
/**
* 递归把字符串/数组/对象中的 http:// 换成 https://
* 不用 PHPUnit isObject对象先转数组再走
*/
private function checkHttp(mixed $data): mixed
{
if (is_object($data)) {
$data = json_decode(json_encode($data), true);
}
if (is_string($data)) {
return str_replace('http://', 'https://', $data);
}
if (is_array($data)) {
array_walk_recursive($data, function (&$value) {
if (is_string($value)) {
$value = str_replace('http://', 'https://', $value);
}
});
return $data;
}
return $data;
}
}