FastMovieAI AI短剧创作平台 二开基线
- 源码: xhadmincn/FastMovieAI (Apache 2.0) - 二开: Docker部署, Swoole改Select, route.php修复, 补update/VERSION - vendor/示例资源已gitignore
This commit is contained in:
@@ -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'
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user