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,57 @@
<?php
namespace app\expose\utils\wechat;
use app\expose\utils\wechat\modules\Event;
use app\expose\utils\wechat\modules\Reply;
use support\Log;
class OfficialAccount
{
use Reply;
use Event;
public function handle($request, $config)
{
$data = $this->getData($request, $config);
if ($data['MsgType'] === 'event') {
return $this->handleEvent($data);
} else {
return $this->replyText($data, 'hello world');
}
}
public function checkSignature($request, $config)
{
$signature = $request->get("signature");
$timestamp = $request->get("timestamp");
$nonce = $request->get("nonce");
$token = $config['token'];
$tmpArr = [$token, $timestamp, $nonce];
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
return true;
}
throw new \Exception('signature error');
}
private function getData($request, $config)
{
$xml = $request->rawBody();
$json = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$data = json_decode(json_encode($json), true);
if ($request->get('encrypt_type') === 'aes') {
$Encrypt = base64_decode($data['Encrypt']);
$aes_key = $config['aes_key'];
$aes_key = base64_decode($aes_key . '=');
$iv = substr($aes_key, 0, 16);
$xml = openssl_decrypt($Encrypt, 'aes-256-cbc', $aes_key, OPENSSL_RAW_DATA, $iv);
$filterHeader = substr($xml, 20);
$xml = preg_replace('/' . $config['app_id'] . '/', '', $filterHeader);
$json = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$data = json_decode(json_encode($json), true);
return $data;
} else {
return $data;
}
}
}
@@ -0,0 +1,73 @@
<?php
namespace app\expose\utils\wechat\modules;
use app\expose\enum\EventName;
use support\Redis;
use Webman\Event\Event as EventEvent;
trait Event
{
private function handleEvent($data)
{
switch ($data['Event']) {
// case 'subscribe':
// EventEvent::emit(EventName::WECHAT_OFFICIAL_ACCOUNT_SUBSCRLBE['value'],$data);
// return $this->replyText($data,'欢迎关注');
// case 'unsubscribe':
// EventEvent::emit(EventName::WECHAT_OFFICIAL_ACCOUNT_UNSUBSCRLBE['value'],$data);
// return $this->replyText($data,'路远,再会。');
case 'subscribe':
case 'unsubscribe':
case 'SCAN':
$scene = str_replace('qrscene_', '', $data['EventKey']);
$Scene = Redis::get($scene);
if ($Scene) {
$Scene = json_decode($Scene, true);
if (count($Scene) < 2) {
return $this->replyText($data, '二维码参数错误');
}
$class = $Scene[0];
$method = $Scene[1];
if (class_exists($class)) {
$class = new $class();
$class->FromUserName = $data['FromUserName'];
$class->ToUserName = $data['ToUserName'];
$class->MsgType = $data['MsgType'];
$class->Event = $data['Event'];
$class->EventKey = $scene;
$class->data = $data;
if (method_exists($class, $method)) {
$params = null;
if (isset($Scene[2])) {
$params = $Scene[2];
}
return $this->replyText($data, $class->$method($params));
}
}
return $this->replyText($data, '扫码成功,但未找到对应处理类或方法');
}
return $this->replyText($data, '二维码已过期');
case 'LOCATION':
return $this->replyText($data, '上报地理位置');
case 'CLICK':
return $this->replyText($data, '点击菜单');
case 'VIEW':
return $this->replyText($data, '点击菜单跳转链接');
case 'scancode_push':
return $this->replyText($data, '扫码推事件');
case 'scancode_waitmsg':
return $this->replyText($data, '扫码推事件且弹出“消息接收中”提示框');
case 'pic_sysphoto':
return $this->replyText($data, '弹出系统拍照发图');
case 'pic_photo_or_album':
return $this->replyText($data, '弹出拍照或者相册发图');
case 'pic_weixin':
return $this->replyText($data, '弹出微信相册发图器');
case 'location_select':
return $this->replyText($data, '弹出地理位置选择器');
case 'view_miniprogram':
return $this->replyText($data, '点击菜单跳转小程序');
}
}
}
@@ -0,0 +1,94 @@
<?php
namespace app\expose\utils\wechat\modules;
trait Reply
{
private function replyText($data,$content)
{
$result=[
'ToUserName' => "<![CDATA[{$data['FromUserName']}]]>",
'FromUserName' => "<![CDATA[{$data['ToUserName']}]]>",
'CreateTime' => time(),
'MsgType' => '<![CDATA[text]]>',
'Content' => "<![CDATA[{$content}]]>"
];
return xml(arrayToXml($result));
}
private function replyImage($data,$media_id)
{
$result=[
'ToUserName' => "<![CDATA[{$data['FromUserName']}]]>",
'FromUserName' => "<![CDATA[{$data['ToUserName']}]]>",
'CreateTime' => time(),
'MsgType' => '<![CDATA[image]]>',
'Image' => [
'MediaId' => "<![CDATA[{$media_id}]]>"
]
];
return xml(arrayToXml($result));
}
private function replyVoice($data,$media_id)
{
$result=[
'ToUserName' => "<![CDATA[{$data['FromUserName']}]]>",
'FromUserName' => "<![CDATA[{$data['ToUserName']}]]>",
'CreateTime' => time(),
'MsgType' => '<![CDATA[voice]]>',
'Voice' => [
'MediaId' => "<![CDATA[{$media_id}]]>"
]
];
return xml(arrayToXml($result));
}
private function replyVideo($data,$media_id,$title='',$description='')
{
$result=[
'ToUserName' => "<![CDATA[{$data['FromUserName']}]]>",
'FromUserName' => "<![CDATA[{$data['ToUserName']}]]>",
'CreateTime' => time(),
'MsgType' => '<![CDATA[video]]>',
'Video' => [
'MediaId' => "<![CDATA[{$media_id}]]>",
'Title' => "<![CDATA[{$title}]]>",
'Description' => "<![CDATA[{$description}]]>"
]
];
return xml(arrayToXml($result));
}
private function replyMusic($data,$thumb_media_id,$title='',$description='',$music_url='',$hq_music_url='')
{
$result=[
'ToUserName' => "<![CDATA[{$data['FromUserName']}]]>",
'FromUserName' => "<![CDATA[{$data['ToUserName']}]]>",
'CreateTime' => time(),
'MsgType' => '<![CDATA[music]]>',
'Music' => [
'Title' => "<![CDATA[{$title}]]>",
'Description' => "<![CDATA[{$description}]]>",
'MusicUrl' => "<![CDATA[{$music_url}]]>",
'HQMusicUrl' => "<![CDATA[{$hq_music_url}]]>",
'ThumbMediaId' => "<![CDATA[{$thumb_media_id}]]>"
]
];
return xml(arrayToXml($result));
}
private function replyNews($data,$articles)
{
$result=[
'ToUserName' => "<![CDATA[{$data['FromUserName']}]]>",
'FromUserName' => "<![CDATA[{$data['ToUserName']}]]>",
'CreateTime' => time(),
'MsgType' => '<![CDATA[news]]>',
'ArticleCount' => count($articles),
'Articles' => []
];
foreach ($articles as $article) {
$result['Articles'][]=[
'Title' => "<![CDATA[{$article['title']}]]>",
'Description' => "<![CDATA[{$article['description']}]]>",
'PicUrl' => "<![CDATA[{$article['picurl']}]]>",
'Url' => "<![CDATA[{$article['url']}]]>"
];
}
return xml(arrayToXml($result));
}
}