Circulation.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. namespace App\Module\Point\Logic;
  3. use App\Module\Point\Models\PointCirculationModel;
  4. /**
  5. * 积分流转逻辑类
  6. *
  7. * 处理同一用户不同积分账户间的流转操作
  8. * 专注于整数积分处理,不涉及小数运算
  9. */
  10. class Circulation
  11. {
  12. /**
  13. * 处理积分流转
  14. *
  15. * @param int $userId 用户ID
  16. * @param int $fromPointId 源积分类型ID
  17. * @param int $toPointId 目标积分类型ID
  18. * @param int $amount 流转积分数量
  19. * @param int $reId 关联ID
  20. * @param string $reType 关联类型
  21. * @param string $remark 备注
  22. * @return int|string 成功返回流转记录ID,失败返回错误信息
  23. */
  24. public static function handle(int $userId, int $fromPointId, int $toPointId, int $amount, int $reId, string $reType, string $remark)
  25. {
  26. # 参数验证
  27. if ($userId <= 0) {
  28. return '用户ID无效';
  29. }
  30. if ($fromPointId === $toPointId) {
  31. return '源积分类型和目标积分类型不能相同';
  32. }
  33. if ($amount <= 0) {
  34. return '流转积分数量必须大于0';
  35. }
  36. if (empty($reType)) {
  37. return '关联类型不能为空';
  38. }
  39. # 创建流转记录
  40. $circulation = PointCirculationModel::createRecord(
  41. $userId,
  42. $fromPointId,
  43. $toPointId,
  44. $amount,
  45. $reId,
  46. $reType,
  47. $remark
  48. );
  49. if (!$circulation) {
  50. return '创建流转记录失败';
  51. }
  52. return $circulation->id;
  53. }
  54. /**
  55. * 批量处理积分流转
  56. *
  57. * @param array $circulations 流转操作数组
  58. * @return array 处理结果数组
  59. */
  60. public static function batchHandle(array $circulations): array
  61. {
  62. $results = [];
  63. foreach ($circulations as $index => $circulation) {
  64. if (!isset(
  65. $circulation['user_id'],
  66. $circulation['from_point_id'],
  67. $circulation['to_point_id'],
  68. $circulation['amount'],
  69. $circulation['re_id'],
  70. $circulation['re_type'],
  71. $circulation['remark']
  72. )) {
  73. $results[$index] = '流转参数不完整';
  74. continue;
  75. }
  76. $result = self::handle(
  77. $circulation['user_id'],
  78. $circulation['from_point_id'],
  79. $circulation['to_point_id'],
  80. $circulation['amount'],
  81. $circulation['re_id'],
  82. $circulation['re_type'],
  83. $circulation['remark']
  84. );
  85. $results[$index] = $result;
  86. }
  87. return $results;
  88. }
  89. /**
  90. * 完成流转操作
  91. *
  92. * @param int $circulationId 流转记录ID
  93. * @return bool|string 成功返回true,失败返回错误信息
  94. */
  95. public static function complete(int $circulationId)
  96. {
  97. $circulation = PointCirculationModel::find($circulationId);
  98. if (!$circulation) {
  99. return '流转记录不存在';
  100. }
  101. if ($circulation->isCompleted()) {
  102. return '流转记录已完成';
  103. }
  104. if ($circulation->isFailed()) {
  105. return '流转记录已失败,无法完成';
  106. }
  107. return $circulation->markCompleted();
  108. }
  109. /**
  110. * 标记流转失败
  111. *
  112. * @param int $circulationId 流转记录ID
  113. * @return bool|string 成功返回true,失败返回错误信息
  114. */
  115. public static function fail(int $circulationId)
  116. {
  117. $circulation = PointCirculationModel::find($circulationId);
  118. if (!$circulation) {
  119. return '流转记录不存在';
  120. }
  121. if ($circulation->isCompleted()) {
  122. return '流转记录已完成,无法标记为失败';
  123. }
  124. if ($circulation->isFailed()) {
  125. return '流转记录已失败';
  126. }
  127. return $circulation->markFailed();
  128. }
  129. /**
  130. * 获取用户流转记录
  131. *
  132. * @param int $userId 用户ID
  133. * @param int $limit 限制数量
  134. * @return array 流转记录数组
  135. */
  136. public static function getUserRecords(int $userId, int $limit = 50): array
  137. {
  138. $records = PointCirculationModel::getUserRecords($userId, $limit);
  139. $result = [];
  140. foreach ($records as $record) {
  141. $result[] = [
  142. 'id' => $record->id,
  143. 'user_id' => $record->user_id,
  144. 'from_point_id' => $record->from_point_id,
  145. 'to_point_id' => $record->to_point_id,
  146. 'amount' => $record->amount,
  147. 're_id' => $record->re_id,
  148. 're_type' => $record->re_type,
  149. 'remark' => $record->remark,
  150. 'status' => $record->status,
  151. 'status_name' => $record->getStatusName(),
  152. 'create_time' => $record->create_time,
  153. 'update_time' => $record->update_time,
  154. ];
  155. }
  156. return $result;
  157. }
  158. /**
  159. * 获取指定积分类型的流转记录
  160. *
  161. * @param int $userId 用户ID
  162. * @param int $pointId 积分类型ID
  163. * @param int $limit 限制数量
  164. * @return array 流转记录数组
  165. */
  166. public static function getPointRecords(int $userId, int $pointId, int $limit = 50): array
  167. {
  168. $records = PointCirculationModel::getPointRecords($userId, $pointId, $limit);
  169. $result = [];
  170. foreach ($records as $record) {
  171. $result[] = [
  172. 'id' => $record->id,
  173. 'user_id' => $record->user_id,
  174. 'from_point_id' => $record->from_point_id,
  175. 'to_point_id' => $record->to_point_id,
  176. 'amount' => $record->amount,
  177. 're_id' => $record->re_id,
  178. 're_type' => $record->re_type,
  179. 'remark' => $record->remark,
  180. 'status' => $record->status,
  181. 'status_name' => $record->getStatusName(),
  182. 'create_time' => $record->create_time,
  183. 'update_time' => $record->update_time,
  184. ];
  185. }
  186. return $result;
  187. }
  188. /**
  189. * 验证流转操作的有效性
  190. *
  191. * @param int $userId 用户ID
  192. * @param int $fromPointId 源积分类型ID
  193. * @param int $toPointId 目标积分类型ID
  194. * @param int $amount 流转积分数量
  195. * @return bool|string 有效返回true,无效返回错误信息
  196. */
  197. public static function validate(int $userId, int $fromPointId, int $toPointId, int $amount)
  198. {
  199. # 检查用户ID
  200. if ($userId <= 0) {
  201. return '用户ID无效';
  202. }
  203. # 检查积分类型
  204. if ($fromPointId === $toPointId) {
  205. return '源积分类型和目标积分类型不能相同';
  206. }
  207. # 检查积分数量
  208. if ($amount <= 0) {
  209. return '流转积分数量必须大于0';
  210. }
  211. # 检查源积分余额
  212. $checkResult = User::checkBalance($userId, $fromPointId, $amount);
  213. if ($checkResult !== true) {
  214. return $checkResult;
  215. }
  216. return true;
  217. }
  218. }