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,115 @@
<?php
namespace plugin\shortplay\utils;
class PricingCalculator
{
protected array $formRules;
protected array $formData;
protected int $baseCost; // 👈 系统级基础积分
protected int $extraPoint = 0; // 规则附加积分
protected float $multiplier = 1.0;
protected array $chargeableComponents = [
'select',
'radio',
'checkbox',
'switch',
];
public function __construct(array $formRules, array $formData, int $baseCost)
{
$this->formRules = $formRules;
$this->formData = $formData;
$this->baseCost = $baseCost;
}
/**
* 主入口
*/
public function calculate(): int
{
foreach ($this->formRules as $rule) {
if (!in_array($rule['component'], $this->chargeableComponents, true)) {
continue;
}
$value = $this->getSubmittedValue($rule);
if ($value === null) {
continue;
}
// Field 级计费(switch
$this->applyFieldPricing($rule, $value);
// Option 级计费
if (!empty($rule['options'])) {
$this->applyOptionPricing($rule, $value);
}
}
return (int) ceil($this->baseCost * $this->multiplier + $this->extraPoint);
}
protected function getSubmittedValue(array $rule)
{
$field = $rule['helper_field'];
$data = $this->formData;
if (isset($data[$field])) {
return $data[$field];
}
return null;
}
/**
* Field 级计费(switch
*/
protected function applyFieldPricing(array $rule, $value): void
{
if ($rule['component'] === 'switch' && $value !== true) {
return;
}
if (isset($rule['base_point']) && $rule['base_point'] > 0) {
$this->extraPoint += (int)$rule['base_point'];
}
if (isset($rule['multiplier']) && $rule['multiplier'] > 0) {
$this->multiplier *= (float)$rule['multiplier'];
}
}
/**
* Option 级计费
*/
protected function applyOptionPricing(array $rule, $value): void
{
foreach ($rule['options'] as $option) {
if (!$this->optionMatched($rule['component'], $option, $value)) {
continue;
}
if (isset($option['base_point'])) {
if (is_numeric($value)) {
$this->extraPoint += (int)$option['base_point'] * (int)$value;
} else {
$this->extraPoint += (int)$option['base_point'];
}
}
if (isset($option['multiplier'])) {
$this->multiplier *= (float)$option['multiplier'];
}
}
}
protected function optionMatched(string $component, array $option, $value): bool
{
if ($component === 'checkbox') {
return is_array($value) && in_array($option['value'], $value, true);
}
return (string)$option['value'] === (string)$value;
}
}
@@ -0,0 +1,29 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class ActorAge extends Enum
{
const CHILD = [
'label' => '儿童',
'value' => 'child',
];
const TEENAGER = [
'label' => '少年',
'value' => 'teenager',
];
const YOUNG = [
'label' => '青年',
'value' => 'young',
];
const MIDDLE_AGE = [
'label' => '中年',
'value' => 'middle_age',
];
const OLD = [
'label' => '老年',
'value' => 'old',
];
}
@@ -0,0 +1,21 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class ActorGender extends Enum
{
const MALE = [
'label' => '男性',
'value' => 'male',
];
const FEMALE = [
'label' => '女性',
'value' => 'female',
];
const NONE = [
'label' => '无性别',
'value' => 'none',
];
}
@@ -0,0 +1,45 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class ActorSpeciesType extends Enum
{
const HUMAN = [
'label' => '人类',
'value' => 'human',
];
const ANIMAL = [
'label' => '动物',
'value' => 'animal',
];
const PLANT = [
'label' => '植物',
'value' => 'plant',
];
const ROBOT = [
'label' => '机器人',
'value' => 'robot',
];
const VIRTUAL_PERSON = [
'label' => '虚拟人',
'value' => 'virtual_person',
];
const DOLL = [
'label' => '玩偶',
'value' => 'doll',
];
const SPRITE = [
'label' => '精灵',
'value' => 'sprite',
];
const GHOST = [
'label' => '鬼怪',
'value' => 'ghost',
];
const OTHER = [
'label' => '其他',
'value' => 'other',
];
}
@@ -0,0 +1,44 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class ActorStatus extends Enum
{
const INITIALIZING = [
'label' => '待初始化',
'value' => 'initializing',
'props' => [
'type' => 'primary'
]
];
const PENDING = [
'label' => '初始化中',
'value' => 'pending',
'props' => [
'type' => 'warning'
]
];
const GENERATED = [
'label' => '已生成',
'value' => 'generated',
'props' => [
'type' => 'success'
]
];
const FAILED = [
'label' => '生成失败',
'value' => 'failed',
'props' => [
'type' => 'danger'
]
];
const CANCELLED = [
'label' => '已取消',
'value' => 'cancelled',
'props' => [
'type' => 'info'
]
];
}
@@ -0,0 +1,44 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class PropStatus extends Enum
{
const INITIALIZING = [
'label' => '待初始化',
'value' => 'initializing',
'props' => [
'type' => 'primary'
]
];
const PENDING = [
'label' => '初始化中',
'value' => 'pending',
'props' => [
'type' => 'warning'
]
];
const GENERATED = [
'label' => '已生成',
'value' => 'generated',
'props' => [
'type' => 'success'
]
];
const FAILED = [
'label' => '生成失败',
'value' => 'failed',
'props' => [
'type' => 'danger'
]
];
const CANCELLED = [
'label' => '已取消',
'value' => 'cancelled',
'props' => [
'type' => 'info'
]
];
}
@@ -0,0 +1,29 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class StyleClassify extends Enum
{
const ANIME = [
'label' => '动漫风格',
'value' => 'anime',
];
const REALISTIC = [
'label' => '写实风格',
'value' => 'realistic',
];
const PORTRAIT = [
'label' => '肖像风格',
'value' => 'portrait',
];
const COMIC = [
'label' => '漫画风格',
'value' => 'comic',
];
const OTHER = [
'label' => '其他风格',
'value' => 'other',
];
}
@@ -0,0 +1,37 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class VoiceEmotion extends Enum
{
const NEUTRAL = [
'label' => '中性',
'value' => 'neutral'
];
const FEARFUL = [
'label' => '恐惧',
'value' => 'fearful'
];
const ANGRY = [
'label' => '愤怒',
'value' => 'angry'
];
const SAD = [
'label' => '悲伤',
'value' => 'sad'
];
const SURPRISED = [
'label' => '惊讶',
'value' => 'surprised'
];
const HAPPY = [
'label' => '高兴',
'value' => 'happy'
];
const DISGUSTED = [
'label' => '厌恶',
'value' => 'disgusted'
];
}
@@ -0,0 +1,73 @@
<?php
namespace plugin\shortplay\utils\enum;
use app\expose\enum\builder\Enum;
class VoiceLanguage extends Enum
{
const ZH = [
'label' => '中文',
'value' => 'zh'
];
const EN = [
'label' => '英语',
'value' => 'en'
];
const JA = [
'label' => '日语',
'value' => 'ja'
];
const KO = [
'label' => '韩语',
'value' => 'ko'
];
const FR = [
'label' => '法语',
'value' => 'fr'
];
const DE = [
'label' => '德语',
'value' => 'de'
];
const IT = [
'label' => '意大利语',
'value' => 'it'
];
const RU = [
'label' => '俄语',
'value' => 'ru'
];
const SV = [
'label' => '瑞典语',
'value' => 'sv'
];
const DA = [
'label' => '丹麦语',
'value' => 'da'
];
const NO = [
'label' => '挪威语',
'value' => 'no'
];
const PT = [
'label' => '葡萄牙语',
'value' => 'pt'
];
const TR = [
'label' => '土耳其语',
'value' => 'tr'
];
const AR = [
'label' => '阿拉伯语',
'value' => 'ar'
];
const ES = [
'label' => '西班牙语',
'value' => 'es'
];
const HI = [
'label' => '印地语',
'value' => 'hi'
];
}