PointOrderModel.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. namespace App\Module\Point\Models;
  3. use App\Module\Point\Enums\POINT_TYPE;
  4. use App\Module\Point\Enums\EXTERNAL_STATUS;
  5. use UCore\ModelCore;
  6. /**
  7. * 积分订单表
  8. *
  9. * 记录积分相关的订单信息,如积分兑换、积分消费等
  10. * 专注于整数积分处理,不涉及小数运算
  11. *
  12. * field start
  13. * @property int $id 自增
  14. * @property string $order_no 订单号
  15. * @property int $user_id 用户ID
  16. * @property \App\Module\Point\Enums\POINT_TYPE $point_id 积分类型ID
  17. * @property int $amount 积分数量
  18. * @property string $order_type 订单类型
  19. * @property string $title 订单标题
  20. * @property string $description 订单描述
  21. * @property \App\Module\Point\Enums\EXTERNAL_STATUS $status 订单状态
  22. * @property array $extra_data 额外数据(JSON格式)
  23. * @property int $create_time 创建时间
  24. * @property int $update_time 更新时间
  25. * field end
  26. */
  27. class PointOrderModel extends ModelCore
  28. {
  29. protected $table = 'point_order';
  30. // attrlist start
  31. protected $fillable = [
  32. 'id',
  33. 'order_no',
  34. 'user_id',
  35. 'point_id',
  36. 'amount',
  37. 'order_type',
  38. 'title',
  39. 'description',
  40. 'status',
  41. 'extra_data',
  42. 'create_time',
  43. 'update_time',
  44. ];
  45. // attrlist end
  46. public $timestamps = false;
  47. protected $casts = [
  48. 'point_id' => POINT_TYPE::class,
  49. 'status' => EXTERNAL_STATUS::class,
  50. 'extra_data' => 'array',
  51. ];
  52. // 订单类型常量
  53. const TYPE_EXCHANGE = 'exchange'; // 积分兑换
  54. const TYPE_CONSUME = 'consume'; // 积分消费
  55. const TYPE_REWARD = 'reward'; // 积分奖励
  56. const TYPE_REFUND = 'refund'; // 积分退款
  57. /**
  58. * 创建积分订单
  59. *
  60. * @param int $userId 用户ID
  61. * @param int $pointId 积分类型ID
  62. * @param int $amount 积分数量
  63. * @param string $orderType 订单类型
  64. * @param string $title 订单标题
  65. * @param string $description 订单描述
  66. * @param array $extraData 额外数据
  67. * @return PointOrderModel|false 成功返回模型,失败返回false
  68. */
  69. public static function createOrder(
  70. int $userId,
  71. int $pointId,
  72. int $amount,
  73. string $orderType,
  74. string $title,
  75. string $description = '',
  76. array $extraData = []
  77. ) {
  78. $order = new self();
  79. $order->order_no = self::generateOrderNo();
  80. $order->user_id = $userId;
  81. $order->point_id = $pointId;
  82. $order->amount = $amount;
  83. $order->order_type = $orderType;
  84. $order->title = $title;
  85. $order->description = $description;
  86. $order->status = EXTERNAL_STATUS::PENDING;
  87. $order->extra_data = $extraData;
  88. $order->create_time = time();
  89. $order->update_time = time();
  90. if ($order->save()) {
  91. return $order;
  92. }
  93. return false;
  94. }
  95. /**
  96. * 生成订单号
  97. *
  98. * @return string 订单号
  99. */
  100. private static function generateOrderNo(): string
  101. {
  102. return 'PO' . date('YmdHis') . mt_rand(1000, 9999);
  103. }
  104. /**
  105. * 根据订单号获取订单
  106. *
  107. * @param string $orderNo 订单号
  108. * @return PointOrderModel|null 订单模型
  109. */
  110. public static function getByOrderNo(string $orderNo): ?PointOrderModel
  111. {
  112. return self::where('order_no', $orderNo)->first();
  113. }
  114. /**
  115. * 更新订单状态
  116. *
  117. * @param EXTERNAL_STATUS $status 状态
  118. * @return bool 是否成功
  119. */
  120. public function updateStatus(EXTERNAL_STATUS $status): bool
  121. {
  122. $this->status = $status;
  123. $this->update_time = time();
  124. return $this->save();
  125. }
  126. /**
  127. * 标记为已完成
  128. *
  129. * @return bool 是否成功
  130. */
  131. public function markCompleted(): bool
  132. {
  133. return $this->updateStatus(EXTERNAL_STATUS::COMPLETED);
  134. }
  135. /**
  136. * 标记为已失败
  137. *
  138. * @return bool 是否成功
  139. */
  140. public function markFailed(): bool
  141. {
  142. return $this->updateStatus(EXTERNAL_STATUS::FAILED);
  143. }
  144. /**
  145. * 标记为已取消
  146. *
  147. * @return bool 是否成功
  148. */
  149. public function markCancelled(): bool
  150. {
  151. return $this->updateStatus(EXTERNAL_STATUS::CANCELLED);
  152. }
  153. /**
  154. * 获取用户订单
  155. *
  156. * @param int $userId 用户ID
  157. * @param int $limit 限制数量
  158. * @return \Illuminate\Database\Eloquent\Collection 订单集合
  159. */
  160. public static function getUserOrders(int $userId, int $limit = 50)
  161. {
  162. return self::where('user_id', $userId)
  163. ->orderBy('create_time', 'desc')
  164. ->limit($limit)
  165. ->get();
  166. }
  167. /**
  168. * 获取指定类型的订单
  169. *
  170. * @param int $userId 用户ID
  171. * @param string $orderType 订单类型
  172. * @param int $limit 限制数量
  173. * @return \Illuminate\Database\Eloquent\Collection 订单集合
  174. */
  175. public static function getUserOrdersByType(int $userId, string $orderType, int $limit = 50)
  176. {
  177. return self::where('user_id', $userId)
  178. ->where('order_type', $orderType)
  179. ->orderBy('create_time', 'desc')
  180. ->limit($limit)
  181. ->get();
  182. }
  183. /**
  184. * 获取订单类型名称
  185. *
  186. * @return string 订单类型名称
  187. */
  188. public function getOrderTypeName(): string
  189. {
  190. return match($this->order_type) {
  191. self::TYPE_EXCHANGE => '积分兑换',
  192. self::TYPE_CONSUME => '积分消费',
  193. self::TYPE_REWARD => '积分奖励',
  194. self::TYPE_REFUND => '积分退款',
  195. default => '未知类型',
  196. };
  197. }
  198. /**
  199. * 获取状态名称
  200. *
  201. * @return string 状态名称
  202. */
  203. public function getStatusName(): string
  204. {
  205. return $this->status->getStatusName();
  206. }
  207. /**
  208. * 判断是否为最终状态
  209. *
  210. * @return bool 是否为最终状态
  211. */
  212. public function isFinalStatus(): bool
  213. {
  214. return $this->status->isFinalStatus();
  215. }
  216. /**
  217. * 获取积分类型名称
  218. *
  219. * @return string 积分类型名称
  220. */
  221. public function getPointTypeName(): string
  222. {
  223. return $this->point_id->getTypeName();
  224. }
  225. /**
  226. * 判断是否为积分支出订单
  227. *
  228. * @return bool 是否为支出订单
  229. */
  230. public function isExpenseOrder(): bool
  231. {
  232. return in_array($this->order_type, [self::TYPE_EXCHANGE, self::TYPE_CONSUME]);
  233. }
  234. /**
  235. * 判断是否为积分收入订单
  236. *
  237. * @return bool 是否为收入订单
  238. */
  239. public function isIncomeOrder(): bool
  240. {
  241. return in_array($this->order_type, [self::TYPE_REWARD, self::TYPE_REFUND]);
  242. }
  243. }