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.

261 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\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($orderMainId)
  54. {
  55. try {
  56. // 线上订单支付完成
  57. // 订单
  58. $orderMain = OrderMain::query()->find($orderMainId);
  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($orderMainId, $userId)
  75. {
  76. // 线上订单完成(用户点击确认收货完成/管理后台点击完成/配送员点击完成/自动收货等),进行相关分账
  77. // 订单
  78. $orderMain = $this->orderOnlineService->check($orderMainId, $userId,OrderState::FINISH);
  79. $currentTime = time();
  80. Db::beginTransaction();
  81. try {
  82. // =======商户订单收入流水 / Start=======
  83. // 查询子订单
  84. $orders = Order::query()
  85. ->where(['order_main_id' => $orderMain->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->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($orderMainId)
  140. {
  141. // 线下订单支付完成
  142. // 订单
  143. $orderMain = OrderMain::query()->find($orderMainId);
  144. $global_order_id = $orderMain->global_order_id;
  145. if (empty($orderMain)) {
  146. return false;
  147. }
  148. // 查询子订单,当面付目前实际上只有一个子订单
  149. $order = Order::query()
  150. ->where(['order_main_id' => $orderMain->id])
  151. ->first();
  152. if (empty($order)) {
  153. return false;
  154. }
  155. $currentTime = time();
  156. Db::beginTransaction();
  157. try {
  158. // =======用户支付流水 / Start=======
  159. $this->financialRecordService->userByOFLOrderPaid($orderMain->user_id, $global_order_id, $orderMain->money);
  160. // =======用户支付流水 / End=======
  161. // =======线下订单支付完成商户分账 / Start=======
  162. // 前提:用户线上下单并且支付完成
  163. // 奖励规则A:用户是平台新用户,奖励商户2元
  164. // 奖励规则B:用户是非新用户,但是是商户当日首单,奖励商户0.05元
  165. // =======线下订单支付完成商户分账 / Start=======
  166. $message = [];
  167. // 商户
  168. $store = Store::find($order->store_id);
  169. // 新商户订单流水
  170. $this->financialRecordService->storeByOFLOrderComp($store->user_id, $global_order_id, $order->money);
  171. $needAward = false;
  172. $awardAmount = 0;
  173. // 新用户商户奖励
  174. if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
  175. $awardAmount = 2;
  176. // 旧商户流水 TODO 直接移除或后续考虑移除
  177. $message = [
  178. 'money' => $awardAmount,
  179. 'note' => '新用户下单成功,平台奖励',
  180. ];
  181. // 新商户流水
  182. $this->financialRecordService->storeAwardByPlatNewUserOFLOrder($store->user_id, $global_order_id, $awardAmount);
  183. $needAward = true;
  184. } else {
  185. // 商户当日首单奖励
  186. if (
  187. $this->userService->isStoreFirstOrderToday(
  188. $order->user_id,
  189. $order->store_id,
  190. $order->id,
  191. FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
  192. )
  193. && $order->money >= FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
  194. ) {
  195. $awardAmount = 0.05;
  196. // 旧商户流水 TODO 直接移除或后续考虑移除
  197. $message = [
  198. 'money' => $awardAmount,
  199. 'note' => '用户下单成功,平台奖励',
  200. ];
  201. // 新商户流水
  202. $this->financialRecordService->storeAwardByTodayFirstOFLOrder($store->user_id, $global_order_id, $awardAmount);
  203. $needAward = true;
  204. }
  205. }
  206. if ($needAward && $awardAmount) {
  207. // 发模板消息
  208. $openid = User::query()->where(['id' => $store['user_id']])->value('openid');
  209. $res = $this->miniprogramService->sendTemMsgForAward($message['money'], $message['note'], $openid, date('Y-m-d H:i:s', $currentTime));
  210. }
  211. // =======线下订单支付完成商户分账 / End=======
  212. Db::commit();
  213. return true;
  214. } catch (\Exception $e) {
  215. $this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
  216. Db::rollBack();
  217. return false;
  218. }
  219. }
  220. }