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.

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