FastMovieAI AI短剧创作平台 二开基线

- 源码: xhadmincn/FastMovieAI (Apache 2.0)
- 二开: Docker部署, Swoole改Select, route.php修复, 补update/VERSION
- vendor/示例资源已gitignore
This commit is contained in:
李建琦
2026-08-26 18:37:36 +08:00
commit eae151fd57
888 changed files with 105571 additions and 0 deletions
@@ -0,0 +1,127 @@
<?php
namespace plugin\control\expose\middleware;
use app\expose\enum\ResponseCode;
use app\expose\helper\Config;
use app\expose\trait\Json;
use Exception;
use loong\oauth\exception\LockException;
use loong\oauth\exception\TokenExpireException;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use loong\oauth\facade\Auth;
use support\Log;
/**
* 中台应用必须继承此中间件,否者无法正常访问
*/
class ControlAuth implements MiddlewareInterface
{
use Json;
public function process(Request $request, callable $next): Response
{
if ($request->method() == 'OPTIONS') {
return response('', 204);
}
// 鉴权检测
try {
$this->Icode($request);
$this->Authorization($request);
$response = $next($request);
} catch (\Throwable $th) {
if ($request->expectsJson()) {
$response = $this->exception($th);
} else {
if (config('app.debug')) {
Log::error($th->getTraceAsString());
throw $th;
} else {
$response = response($th->getMessage(), 500);
}
}
}
return $response;
}
public function Icode(Request $request)
{
$icode = $request->header('x-icode');
if (!$icode) {
return true;
}
$request->icode = $icode;
}
/**
* 业务逻辑
* @author 贵州猿创科技有限公司
* @Email 416716328@qq.com
* @DateTime 2023-03-11
*/
public function Authorization(Request $request)
{
# 无控制器地址
if (!$request->controller) {
return true;
}
# 获取控制器鉴权信息
$controller = new \ReflectionClass($request->controller);
$properties = $controller->getDefaultProperties();
# 无需登录方法
$notNeedLogin = $properties['notNeedLogin'] ?? [];
# 是否强制登录
$isForceLogin = true;
if (in_array($request->action, $notNeedLogin)) {
$isForceLogin = false;
}
try {
# 令牌验证
$token = $request->header('Authorization');
if (!$token) {
throw new Exception('请先登录', ResponseCode::NEED_LOGIN);
}
$user = Auth::setPrefix('CONTROL')->decrypt($token);
if (!$user) {
throw new TokenExpireException();
}
$request->uid = $user['uid'];
$request->channels_uid = $user['channels_uid'];
$request->token = $token;
} catch (TokenExpireException $e) {
if ($isForceLogin) {
throw new Exception('登录已过期,请重新登录', ResponseCode::NEED_LOGIN);
}
} catch (LockException $e) {
if ($isForceLogin) {
throw new Exception($e->getMessage(), ResponseCode::LOCK);
}
} catch (\Throwable $th) {
if ($isForceLogin) {
throw new \Exception($th->getMessage(), ResponseCode::NEED_LOGIN);
}
}
if (!$isForceLogin) {
return true;
}
if ($user['is_system']) {
return true;
}
if (empty($user['permissions'])) {
throw new Exception('您没有权限访问', ResponseCode::NO_PERMISSION);
}
$plugin = $request->plugin;
// plugin\api\app\admin\controller\IndexController,只取Index
$controllers = explode('\\', $request->controller);
$controller = str_replace('Controller', '', end($controllers));
$action = str_replace(['GetTable', 'GetGrid'], ['', ''], $request->action);
$rule = $controller . '/' . $action;
if ($plugin) {
$app = $request->app;
$rule = "/app/{$plugin}/{$app}/{$rule}";
}
if (!in_array($rule, $user['permissions'])) {
throw new Exception('您没有权限访问', ResponseCode::NO_PERMISSION);
}
}
}
@@ -0,0 +1,80 @@
<?php
namespace plugin\control\expose\middleware;
use app\expose\enum\State;
use plugin\control\app\model\PluginChannelsDomain;
use plugin\control\utils\LRUCache;
use support\Redis;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class DomainMapping implements MiddlewareInterface
{
private static ?LRUCache $cache = null;
public function __construct()
{
if (!self::$cache) {
self::$cache = new LRUCache(2000);
}
}
public function process(Request $request, callable $next): Response
{
$headersKeys=['Authorization','X-ICODE','X-Platform','lang','X-developer','content-type'];
// 1. 优先 Origin
if ($origin = $request->header('origin')) {
$domain = parse_url($origin, PHP_URL_HOST);
}
// 2. 再尝试 Referer
elseif ($referer = $request->header('referer')) {
$domain = parse_url($referer, PHP_URL_HOST);
} elseif ($request->host()) {
$domain = $request->host();
} else {
return response('Domain not found', 401);
}
$corsHeaders = [
'Access-Control-Allow-Origin' => $origin,
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS, PATCH',
'Access-Control-Allow-Headers' => strtolower(implode(',', $headersKeys)),
];
// 1. LRU 进程缓存
$userId = self::$cache->get($domain);
if ($userId) {
$request->channels_uid = $userId;
$response = $next($request);
# 允许跨域
$response->withHeaders($corsHeaders);
return $response;
}
// 2. Redis Hash
$userId = Redis::hGet('domain_map', $domain);
if ($userId) {
self::$cache->set($domain, $userId);
$request->channels_uid = $userId;
$response = $next($request);
# 允许跨域
$response->withHeaders($corsHeaders);
return $response;
}
// 3. MySQL 兜底
$PluginChannelsDomain = PluginChannelsDomain::where('domain', $domain)->where('state', State::YES['value'])->find();
if ($PluginChannelsDomain) {
Redis::hSet('domain_map', $domain, $PluginChannelsDomain->channels_uid);
self::$cache->set($domain, $PluginChannelsDomain->channels_uid);
$request->channels_uid = $PluginChannelsDomain->channels_uid;
$response = $next($request);
# 允许跨域
$response->withHeaders($corsHeaders);
return $response;
}
return response('Domain not found', 401);
}
}