展示名) */ const MODEL_NAME_FALLBACK = [ // 视频(Seedance 系列) 'doubao-seedance-1-5-pro-251215' => 'Seedance1.5pro', 'doubao-seedance-1-0-pro-250528' => 'Seedance1.0pro', 'doubao-seedance-1-0-pro-fast-251015' => 'Seedance1.0profast', 'doubao-seedance-2-0-260128' => 'Seedance2.0', 'doubao-seedance-2-0-fast-260128' => 'Seedance2.0fast', 'doubao-seedance-2.0' => 'Seedance2.0', 'baidu-doubao-seedance-2-0-260128' => 'Seedance2.0', 'baidu-doubao-seedance-2-0-fast-260128' => 'Seedance2.0fast', 'baidu-doubao-seedance-2-0-mini-260615' => 'Seedance2.0mini', 'baidu-doubao-seedance-2-5-260628' => 'Seedance2.5', 'baidu-dreamina-seedance-2-0-260128' => 'Seedance2.0(海外)', 'baidu-dreamina-seedance-2-0-fast-260128' => 'Seedance2.0fast(海外)', 'baidu-dreamina-seedance-2-0-mini-260615' => 'Seedance2.0mini(海外)', 'baidu-dreamina-seedance-2-5-260628' => 'Seedance2.5(海外)', 'zhizhen-20' => 'Seedance2.0', 'zhizhen-20-fast' => 'Seedance2.0fast', 'zhizhen-20-mini' => 'Seedance2.0mini', 'seed-2' => 'Seedance2.0', 'seed-2-fast' => 'Seedance2.0fast', 'seed-2-mini' => 'Seedance2.0mini', 'seed-2.5' => 'Seedance2.5', // 文本 'baidu-glm-5.2' => 'GLM-5.2', 'baidu-glm-5.3' => 'GLM-5.3', ]; /** * 视频分辨率取值 => 展示文案 */ const VIDEO_RESOLUTION_LABELS = [ '480p' => '480p', '720p' => '720p', '1080p' => '1080p', '4k' => '4k', '2160p' => '4k', '4096x2160' => '4k', 'sr_720p' => '超分720p', 'sr720p' => '超分720p', '超分720p' => '超分720p', 'sr_1080p' => '超分1080p', 'sr1080p' => '超分1080p', '超分1080p' => '超分1080p', ]; /** * 配置表读取的模型展示名缓存(单次请求内只查一次) * * @var array|null */ private static $modelNameMap = null; /** * 获取模型对外展示名(隐藏百度/快快等供应商字样) * * @param string $model 模型ID(charge_info.model) * @return string */ public static function modelName(string $model = ''): string { $model = trim($model); if ($model === '' || $model === 'unknown') { return ''; } $map = self::modelNameMap(); $name = $map[$model] ?? self::MODEL_NAME_FALLBACK[$model] ?? ''; if ($name === '') { $name = $model; } return self::stripVendor($name); } /** * 获取明细的分辨率展示文案 * * - 视频:480p/720p/1080p/4k、超分720p、超分1080p(来自 charge_info.video_resolution) * - 图片:实际宽*高,如 1600*2848(来自 charge_info.width / height) * - 其他类型或无数据:空串 * * @param string $type 明细类型(video/image/chat/system/company) * @param array $chargeInfo 计费信息 * @return string */ public static function resolution(string $type, array $chargeInfo = []): string { if ($type === MpUserPointsDetail::TYPE_VIDEO) { $resolution = strtolower(trim((string)getProp($chargeInfo, 'video_resolution', ''))); if ($resolution === '') { return ''; } return self::VIDEO_RESOLUTION_LABELS[$resolution] ?? $resolution; } if ($type === MpUserPointsDetail::TYPE_IMAGE) { $width = (int)getProp($chargeInfo, 'width', 0); $height = (int)getProp($chargeInfo, 'height', 0); if ($width <= 0 || $height <= 0) { return ''; } return $width . '*' . $height; } return ''; } /** * 仅保留名称主体:剥离供应商字样前缀(百度Seedance2.0 → Seedance2.0,baidu-xxx → xxx) * * @param string $name * @return string */ private static function stripVendor(string $name): string { $name = trim($name); // 英文前缀(模型ID形态) foreach (self::VENDOR_PREFIXES as $prefix) { if (stripos($name, $prefix) === 0) { $name = trim(substr($name, strlen($prefix))); } } // 中文前缀(配置表 name 形态),可能连续出现(如“百度智帧xxx”) $changed = true; while ($changed) { $changed = false; foreach (self::VENDOR_WORDS as $word) { if (mb_strpos($name, $word) === 0) { $name = trim(mb_substr($name, mb_strlen($word))); $changed = true; break; } } } return $name; } /** * 模型ID => 配置表展示名(读取失败或未命中时返回空数组,由调用方走兜底映射) * * @return array */ private static function modelNameMap(): array { if (self::$modelNameMap !== null) { return self::$modelNameMap; } $map = []; foreach (['mp_video_models', 'mp_image_models', 'mp_text_models'] as $table) { try { $rows = DB::table($table)->select('model', 'name')->get(); } catch (\Throwable $e) { continue; } foreach ($rows as $row) { $model = trim((string)getProp($row, 'model', '')); $name = trim((string)getProp($row, 'name', '')); if ($model !== '' && $name !== '') { $map[$model] = $name; } } } self::$modelNameMap = $map; return self::$modelNameMap; } }