RechargeOrder.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. declare (strict_types=1);
  3. namespace app\model\api;
  4. use library\basic\BaseModel;
  5. use think\facade\Cache;
  6. use think\Model;
  7. /**
  8. * @mixin \think\Model
  9. */
  10. class RechargeOrder extends BaseModel
  11. {
  12. /**
  13. * 生成充值订单号
  14. * @param int $uid 用户UID
  15. * @return string
  16. */
  17. public function mkOrderSn($uid)
  18. {
  19. return 'RO' . time() . rand(1000, 9000) . $uid;
  20. }
  21. /**
  22. * 创建充值订单
  23. * @param int $uid 用户UID
  24. * @param int $rechargeId 充值配置ID(0为自定义充值)
  25. * @param float $price 充值金额
  26. * @param int $integral 获得积分
  27. * @param int $giveIntegral 赠送积分
  28. * @param string $payType 支付方式:wxpay/alipay/system
  29. * @param int $adminId 管理员ID(后台充值)
  30. * @param string $remark 备注
  31. * @param float $discount 折扣金额
  32. * @return string|null 订单号
  33. */
  34. public function createOrder($uid, $rechargeId, $price, $integral, $giveIntegral, $payType = 'wxpay', $adminId = 0, $remark = '', $discount = 0)
  35. {
  36. $orderSn = $this->mkOrderSn($uid);
  37. $totalIntegral = $integral + $giveIntegral;
  38. $bool = $this->insert([
  39. 'order_id' => $orderSn,
  40. 'uid' => $uid,
  41. 'recharge_id' => $rechargeId,
  42. 'price' => $price,
  43. 'integral' => $integral,
  44. 'give_integral' => $giveIntegral,
  45. 'total_integral' => $totalIntegral,
  46. 'pay_type' => $payType,
  47. 'paid' => 0,
  48. 'pay_time' => 0,
  49. 'remark' => $remark,
  50. 'admin_id' => $adminId,
  51. 'discount_amount' => $discount,
  52. 'status' => 0,
  53. 'add_time' => time(),
  54. 'update_time' => time()
  55. ]);
  56. return $bool ? $orderSn : null;
  57. }
  58. /**
  59. * 根据订单号获取订单
  60. * @param string $orderSn 订单号
  61. * @return array|null
  62. */
  63. public function getByOrderSn($orderSn)
  64. {
  65. return $this->where('order_id', $orderSn)->find();
  66. }
  67. /**
  68. * 根据ID获取订单
  69. * @param int $id 订单ID
  70. * @return array|null
  71. */
  72. public function getById($id)
  73. {
  74. return $this->where('id', $id)->find();
  75. }
  76. /**
  77. * 更新订单支付状态
  78. * @param string $orderSn 订单号
  79. * @param string $paySn 支付流水号
  80. * @param string $payJson 支付返回信息
  81. * @return bool
  82. */
  83. public function updatePayStatus($orderSn, $paySn, $payJson = '')
  84. {
  85. return $this->where('order_id', $orderSn)->update([
  86. 'paid' => 1,
  87. 'pay_sn' => $paySn,
  88. 'pay_json' => $payJson,
  89. 'pay_time' => time(),
  90. 'status' => 1,
  91. 'update_time' => time()
  92. ]);
  93. }
  94. /**
  95. * 获取用户充值订单列表
  96. * @param int $uid 用户UID
  97. * @param array $where 查询条件
  98. * @param string $field 查询字段
  99. * @param int $page 页码
  100. * @param int $pageCount 每页数量
  101. * @param string $order 排序
  102. * @return array
  103. */
  104. public function getUserList($uid, $where = [], $field = '*', $page = 1, $pageCount = 20, $order = 'add_time desc')
  105. {
  106. $where['uid'] = $uid;
  107. $data = $this
  108. ->where($where)
  109. ->field($field)
  110. ->order($order)
  111. ->paginate(['list_rows' => $pageCount, 'page' => $page])
  112. ->toArray();
  113. return [$data['total'], $data['data']];
  114. }
  115. /**
  116. * 获取充值订单列表(后台)
  117. * @param array $where 查询条件
  118. * @param string $field 查询字段
  119. * @param int $page 页码
  120. * @param int $pageCount 每页数量
  121. * @param string $order 排序
  122. * @return array
  123. */
  124. public function getAdminList($where = [], $field = '*', $page = 1, $pageCount = 20, $order = 'add_time desc')
  125. {
  126. $data = $this
  127. ->alias('ro')
  128. ->field($field)
  129. ->leftJoin('user u', 'u.uid = ro.uid')
  130. ->when(!empty($where), function ($query) use ($where) {
  131. if (!empty($where['order_id'])) {
  132. $query->where('ro.order_id', $where['order_id']);
  133. }
  134. if (!empty($where['uid'])) {
  135. $query->where('ro.uid', $where['uid']);
  136. }
  137. if (!empty($where['nickname'])) {
  138. $query->whereLike('u.nickname', "%{$where['nickname']}%");
  139. }
  140. if (!empty($where['mobile'])) {
  141. $query->where('u.mobile', $where['mobile']);
  142. }
  143. if (!empty($where['pay_type'])) {
  144. $query->where('ro.pay_type', $where['pay_type']);
  145. }
  146. if (!empty($where['paid'])) {
  147. $query->where('ro.paid', $where['paid']);
  148. }
  149. if (!empty($where['status'])) {
  150. $query->where('ro.status', $where['status']);
  151. }
  152. if (!empty($where['time']) && !empty($where['time'][0]) && !empty($where['time'][1])) {
  153. $startTime = strtotime($where['time'][0]);
  154. $endTime = strtotime($where['time'][1]);
  155. $query->whereBetween('ro.add_time', "{$startTime},{$endTime}");
  156. }
  157. })
  158. ->order($order)
  159. ->paginate(['list_rows' => $pageCount, 'page' => $page])
  160. ->toArray();
  161. return [$data['total'], $data['data']];
  162. }
  163. /**
  164. * 关闭订单
  165. * @param string $orderSn 订单号
  166. * @return bool
  167. */
  168. public function closeOrder($orderSn)
  169. {
  170. return $this->where('order_id', $orderSn)->update([
  171. 'status' => -1,
  172. 'update_time' => time()
  173. ]);
  174. }
  175. /**
  176. * 增加用户积分(内部调用)
  177. * @param int $uid 用户ID
  178. * @param int $totalIntegral 总积分
  179. * @param string $orderSn 订单号
  180. * @param float $price 充值金额
  181. * @param int $orderId 订单ID
  182. * @return bool
  183. */
  184. private function addUserIntegral($uid, $totalIntegral, $orderSn, $price, $orderId)
  185. {
  186. try {
  187. $userModel = new User();
  188. $user = $userModel->where('uid', $uid)->find();
  189. if ($user) {
  190. // 更新用户积分和累计充值金额
  191. $userModel->where('uid', $uid)->inc('score', $totalIntegral)->inc('score_in', $totalIntegral)->update();
  192. // 记录积分明细
  193. $scoreDetail = new UserScoreDetail();
  194. $scoreDetail->incomeScore($uid, $totalIntegral, $orderSn, 'income_score', [
  195. 'o_id' => $orderId
  196. ], $orderId);
  197. }
  198. // 清除用户折扣缓存,以便下次充值生成新的折扣金额
  199. Cache::store('redis')->delete('recharge_discount_' . $uid);
  200. return true;
  201. } catch (\Exception $e) {
  202. // 将错误信息保存到 quanju.txt 文件
  203. @file_put_contents('quanju.txt', $e->getLine() . $e->getMessage() . $e->getFile() . "-增加用户积分报错内容\r\n", 8);
  204. return false;
  205. }
  206. }
  207. /**
  208. * 充值成功回调处理(内部调用)
  209. * @param string $orderSn 订单号
  210. * @param string $paySn 支付流水号
  211. * @param string $payJson 支付返回信息
  212. * @return bool
  213. */
  214. public function paySuccess($orderSn, $paySn, $payJson = '')
  215. {
  216. try {
  217. $rechargeOrder = new RechargeOrder();
  218. $orderInfo = $rechargeOrder->getByOrderSn($orderSn);
  219. if (!$orderInfo) {
  220. return false;
  221. }
  222. // 更新订单支付状态
  223. $updateResult = $rechargeOrder->updatePayStatus($orderSn, $paySn, $payJson);
  224. if (!$updateResult) {
  225. return false;
  226. }
  227. // 增加用户积分
  228. $this->addUserIntegral($orderInfo['uid'], $orderInfo['total_integral'], $orderSn, $orderInfo['price'], $orderInfo['id']);
  229. return true;
  230. } catch (\Exception $e) {
  231. // 将错误信息保存到 quanju.txt 文件
  232. // $logMessage = date('Y-m-d H:i:s') . " [paySuccess Error] OrderSn: {$orderSn}, PaySn: {$paySn}, Error: " . $e->getMessage() . "\n";
  233. // file_put_contents('quanju.txt', $logMessage, FILE_APPEND);
  234. @file_put_contents('quanju.txt', $e->getLine() . $e->getMessage() . $e->getFile() . "-充值完成报错内容\r\n", 8);
  235. return false;
  236. }
  237. }
  238. }