PointsTransformer.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace App\Transformer\Points;
  3. use App\Libs\PointsDisplay;
  4. class PointsTransformer
  5. {
  6. const TYPE_LABELS = [
  7. 'video' => '视频生成',
  8. 'video_refund' => '视频生成退款',
  9. 'image' => '图片生成',
  10. 'image_refund' => '图片生成退款',
  11. 'chat' => 'AI对话',
  12. 'chat_refund' => 'AI对话退款',
  13. 'system' => '平台发放',
  14. 'company' => '组织发放',
  15. ];
  16. /**
  17. * 积分流水列表
  18. *
  19. * @param $data
  20. * @return array
  21. */
  22. public function newBuildPointsRecords($data): array
  23. {
  24. return [
  25. 'meta' => getMeta($data),
  26. 'list' => $this->newEachPointsRecord($data),
  27. ];
  28. }
  29. /**
  30. * 单条积分流水
  31. *
  32. * 模型名统一做展示映射(隐藏百度/快快等供应商字样);
  33. * 分辨率按类型展示:视频 480p/720p/1080p/4k 与 超分720p/超分1080p,图片 实际宽*高,其余为空。
  34. * 名称字段只返回一个 anime_name:动漫名优先,其次剧本名(与动漫/剧本无关时为空)。
  35. * 分集序号 episode_number:与分集无关的记录返回 0。
  36. * 模型名保持原键名 charge_info.model 不变,值改为展示名(隐藏供应商字样),前端无需调整取数位置。
  37. *
  38. * @param $list
  39. * @return array
  40. */
  41. public function newEachPointsRecord($list): array
  42. {
  43. $result = [];
  44. if (empty($list)) return $result;
  45. foreach ($list as $item) {
  46. $chargeInfo = getProp($item, 'charge_info');
  47. if (is_string($chargeInfo)) {
  48. $chargeInfo = json_decode($chargeInfo, true);
  49. }
  50. $chargeInfo = is_array($chargeInfo) ? $chargeInfo : [];
  51. $type = getProp($item, 'type', '');
  52. $apiType = (string)getProp($item, 'api_type', '');
  53. $rawModel = (string)getProp($chargeInfo, 'model', '');
  54. $modelName = PointsDisplay::modelName($rawModel);
  55. $resolution = PointsDisplay::resolution($type, $chargeInfo);
  56. // 名称只保留一个:动漫名优先,其次剧本名
  57. $animeName = trim((string)getProp($item, 'anime_name', ''));
  58. $scriptName = trim((string)getProp($item, 'script_name', ''));
  59. $displayName = $animeName !== '' ? $animeName : $scriptName;
  60. // 展示层隐藏供应商字样(库中原始 charge_info 不变)
  61. if ($rawModel !== '' && $modelName !== '') {
  62. $chargeInfo['model'] = $modelName;
  63. }
  64. $pointsConsumed = (float)getProp($item, 'points_consumed', 0);
  65. if ($pointsConsumed > 0) {
  66. // 消耗:带负号
  67. $pointsChange = '-' . $pointsConsumed;
  68. } elseif ($pointsConsumed < 0) {
  69. // 赠送/入账:带正号
  70. $pointsChange = '+' . abs($pointsConsumed);
  71. } else {
  72. $pointsChange = '0';
  73. }
  74. $result[] = [
  75. 'id' => (int)getProp($item, 'id'),
  76. 'type' => $type,
  77. 'type_label' => self::TYPE_LABELS[$type] ?? $type,
  78. 'account' => (string)getProp($item, 'account', ''),
  79. 'api_type' => $apiType,
  80. 'task_id' => (int)getProp($item, 'task_id'),
  81. 'resolution' => $resolution,
  82. 'anime_id' => (int)getProp($item, 'anime_id', 0),
  83. 'episode_number' => (int)getProp($item, 'episode_number', 0),
  84. 'script_id' => (int)getProp($item, 'script_id', 0),
  85. 'anime_name' => $displayName,
  86. // 来源展示:1=资产、2=画布、0 且有动漫/剧本归属=动漫/剧本,其余=默认
  87. 'source_from' => PointsDisplay::sourceFrom($chargeInfo, getProp($item, 'anime_id', 0), getProp($item, 'script_id', 0)),
  88. 'charge_info' => $chargeInfo,
  89. 'points_consumed' => $pointsConsumed,
  90. 'points_change' => $pointsChange,
  91. 'points_before' => (float)getProp($item, 'points_before', 0),
  92. 'points_after' => (float)getProp($item, 'points_after', 0),
  93. 'tokens_consumed' => (int)getProp($item, 'tokens_consumed', 0),
  94. 'remark' => getProp($item, 'remark'),
  95. 'created_at' => transDate(getProp($item, 'created_at')),
  96. ];
  97. }
  98. return $result;
  99. }
  100. }