You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
9.2 KiB

  1. <?php
  2. namespace App\Service\v3\Implementations;
  3. use App\Commons\Log;
  4. use App\Constants\v3\LogLabel;
  5. use App\Constants\v3\OrderState;
  6. use App\Model\v3\FinancialRecord;
  7. use App\Model\v3\Order;
  8. use App\Model\v3\OrderMain;
  9. use App\Model\v3\ServiceReward;
  10. use App\Model\v3\Store;
  11. use App\Model\v3\UserRelationBind;
  12. use App\Model\v3\User;
  13. use App\Service\v3\Interfaces\FinancialRecordServiceInterface;
  14. use App\Service\v3\Interfaces\MiniprogramServiceInterface;
  15. use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
  16. use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
  17. use App\Service\v3\Interfaces\UserServiceInterface;
  18. use Hyperf\DbConnection\Db;
  19. use Hyperf\Di\Annotation\Inject;
  20. class SeparateAccountsService implements SeparateAccountsServiceInterface
  21. {
  22. /**
  23. * @Inject
  24. * @var Log
  25. */
  26. protected $log;
  27. /**
  28. * @Inject
  29. * @var UserServiceInterface
  30. */
  31. protected $userService;
  32. /**
  33. * @Inject
  34. * @var FinancialRecordServiceInterface
  35. */
  36. protected $financialRecordService;
  37. /**
  38. * @Inject
  39. * @var MiniprogramServiceInterface
  40. */
  41. protected $miniprogramService;
  42. /**
  43. * @Inject
  44. * @var OrderOnlineServiceInterface
  45. */
  46. protected $orderOnlineService;
  47. /**
  48. * @inheritDoc
  49. */
  50. public function orderOnlinePaid($globalOrderId)
  51. {
  52. try {
  53. // 线上订单支付完成
  54. // 订单
  55. $orderMain = OrderMain::query()->where(['global_order_id' => $globalOrderId])->first();
  56. if (empty($orderMain)) {
  57. return false;
  58. }
  59. // =======用户支付流水 / Start=======
  60. $this->financialRecordService->userByOLOrderPaid($orderMain->user_id, $orderMain->global_order_id, $orderMain->money);
  61. // =======用户支付流水 / End=======
  62. return true;
  63. } catch (\Exception $e) {
  64. $this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage()]);
  65. return false;
  66. }
  67. }
  68. /**
  69. * @inheritDoc
  70. */
  71. public function orderOnlineCompleted($globalOrderId, $userId)
  72. {
  73. // 线上订单完成(用户点击确认收货完成/管理后台点击完成/配送员点击完成/自动收货等),进行相关分账
  74. // 订单
  75. $orderMain = $this->orderOnlineService->check($globalOrderId, $userId,OrderState::FINISH);
  76. $currentTime = time();
  77. Db::beginTransaction();
  78. try {
  79. // =======商户订单收入流水 / Start=======
  80. // 查询子订单
  81. $orders = Order::query()
  82. ->where(['order_main_id' => $orderMain->global_order_id])
  83. ->get()->toArray();
  84. // 新商户流水
  85. foreach ($orders as $key => &$order) {
  86. $store = Store::query()->find($order['store_id']);
  87. $this->financialRecordService->storeByOLOrderComp($store->user_id, $orderMain->global_order_id ,$order['money']);
  88. }
  89. // =======商户订单收入流水 / End=======
  90. // =======社区服务点分账 / Start=======
  91. // 前提:用户线上下单并且订单完成
  92. // 奖励规则A:用户是平台新用户,奖励社区服务点平台新用户奖励x元+平台新用户首单奖励y元+订单商品金额z%的分成
  93. // 奖励规则B:用户是非新用户,奖励社区服务点订单实际支付金额z%的分成
  94. // =======社区服务点分账 / Start=======
  95. // 当前用户的社区服务点绑定关系
  96. $communityBind = UserRelationBind::query()
  97. ->where(['bind_type' => UserRelationBind::BIND_TYPE_COMMUNITY, 'user_id' => $orderMain->user_id])
  98. ->first();
  99. if ($communityBind) {
  100. // 奖励/分账金额
  101. $award = ServiceReward::query()->where(['type' => ServiceReward::TYPE_COMMUNITY])->first();
  102. if (empty($award)) {
  103. Db::rollBack();
  104. return false;
  105. }
  106. $award = $award->set_reward;
  107. // 平台新用户
  108. if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->global_order_id)) {
  109. $this->financialRecordService->communityAwardByPlatNewUser(
  110. $communityBind->source_id,
  111. $orderMain->global_order_id,
  112. $award['new_user_reward']
  113. );
  114. $this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder(
  115. $communityBind->source_id,
  116. $orderMain->global_order_id,
  117. $award['first_reward']
  118. );
  119. }
  120. // 账单分成
  121. $money = bcmul($orderMain->money, bcdiv($award['flow_reward'], 100, 6), 2);
  122. $this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $orderMain->global_order_id, $money);
  123. }
  124. // =======社区服务点分账 / End=======
  125. Db::commit();
  126. return true;
  127. } catch (\Exception $e) {
  128. $this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
  129. Db::rollBack();
  130. return false;
  131. }
  132. }
  133. /**
  134. * @inheritDoc
  135. */
  136. public function orderOfflinePaid($globalOrderId)
  137. {
  138. // 线下订单支付完成
  139. // 订单
  140. $orderMain = OrderMain::query()->where(['global_order_id' => $globalOrderId]);
  141. if (empty($orderMain)) {
  142. return false;
  143. }
  144. // 查询子订单,当面付目前实际上只有一个子订单
  145. $order = Order::query()
  146. ->where(['order_main_id' => $orderMain->global_order_id])
  147. ->first();
  148. if (empty($order)) {
  149. return false;
  150. }
  151. $currentTime = time();
  152. Db::beginTransaction();
  153. try {
  154. // =======用户支付流水 / Start=======
  155. $this->financialRecordService->userByOFLOrderPaid($orderMain->user_id, $orderMain->global_order_id, $orderMain->money);
  156. // =======用户支付流水 / End=======
  157. // =======线下订单支付完成商户分账 / Start=======
  158. // 前提:用户线上下单并且支付完成
  159. // 奖励规则A:用户是平台新用户,奖励商户2元
  160. // 奖励规则B:用户是非新用户,但是是商户当日首单,奖励商户0.05元
  161. // =======线下订单支付完成商户分账 / Start=======
  162. $message = [];
  163. // 商户
  164. $store = Store::find($order->store_id);
  165. // 新商户订单流水
  166. $this->financialRecordService->storeByOFLOrderComp($store->user_id, $orderMain->global_order_id, $order->money);
  167. $needAward = false;
  168. $awardAmount = 0;
  169. // 新用户商户奖励
  170. if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->global_order_id)) {
  171. $awardAmount = 2;
  172. // 旧商户流水 TODO 直接移除或后续考虑移除
  173. $message = [
  174. 'money' => $awardAmount,
  175. 'note' => '新用户下单成功,平台奖励',
  176. ];
  177. // 新商户流水
  178. $this->financialRecordService->storeAwardByPlatNewUserOFLOrder($store->user_id, $orderMain->global_order_id, $awardAmount);
  179. $needAward = true;
  180. } else {
  181. // 商户当日首单奖励
  182. if (
  183. $this->userService->isStoreFirstOrderToday(
  184. $order->user_id,
  185. $order->store_id,
  186. $order->id,
  187. FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
  188. )
  189. && $order->money >= FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
  190. ) {
  191. $awardAmount = 0.05;
  192. // 旧商户流水 TODO 直接移除或后续考虑移除
  193. $message = [
  194. 'money' => $awardAmount,
  195. 'note' => '用户下单成功,平台奖励',
  196. ];
  197. // 新商户流水
  198. $this->financialRecordService->storeAwardByTodayFirstOFLOrder($store->user_id, $orderMain->global_order_id, $awardAmount);
  199. $needAward = true;
  200. }
  201. }
  202. if ($needAward && $awardAmount) {
  203. // 发模板消息
  204. $openid = User::query()->where(['id' => $store['user_id']])->value('openid');
  205. $res = $this->miniprogramService->sendTemMsgForAward($message['money'], $message['note'], $openid, date('Y-m-d H:i:s', $currentTime));
  206. }
  207. // =======线下订单支付完成商户分账 / End=======
  208. Db::commit();
  209. return true;
  210. } catch (\Exception $e) {
  211. $this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
  212. Db::rollBack();
  213. return false;
  214. }
  215. }
  216. }