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.
 
 

262 lines
9.2 KiB

<?php
namespace App\Service\v3\Implementations;
use App\Commons\Log;
use App\Constants\v3\LogLabel;
use App\Constants\v3\OrderState;
use App\Model\v3\FinancialRecord;
use App\Model\v3\Order;
use App\Model\v3\OrderMain;
use App\Model\v3\ServiceReward;
use App\Model\v3\Store;
use App\Model\v3\StoreAccount;
use App\Model\v3\SystemConfig;
use App\Model\v3\UserBalance;
use App\Model\v3\UserRelationBind;
use App\Model\v3\User;
use App\Service\v3\Interfaces\FinancialRecordServiceInterface;
use App\Service\v3\Interfaces\MiniprogramServiceInterface;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use App\Service\v3\Interfaces\UserServiceInterface;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
class SeparateAccountsService implements SeparateAccountsServiceInterface
{
/**
* @Inject
* @var Log
*/
protected $log;
/**
* @Inject
* @var UserServiceInterface
*/
protected $userService;
/**
* @Inject
* @var FinancialRecordServiceInterface
*/
protected $financialRecordService;
/**
* @Inject
* @var MiniprogramServiceInterface
*/
protected $miniprogramService;
/**
* @Inject
* @var OrderOnlineServiceInterface
*/
protected $orderOnlineService;
/**
* @inheritDoc
*/
public function orderOnlinePaid($orderMainId)
{
try {
// 线上订单支付完成
// 订单
$orderMain = OrderMain::query()->find($orderMainId);
if (empty($orderMain)) {
return false;
}
// =======用户支付流水 / Start=======
$this->financialRecordService->userByOLOrderPaid($orderMain->user_id, $orderMain->global_order_id, $orderMain->money);
// =======用户支付流水 / End=======
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage()]);
return false;
}
}
/**
* @inheritDoc
*/
public function orderOnlineCompleted($orderMainId, $userId)
{
// 线上订单完成(用户点击确认收货完成/管理后台点击完成/配送员点击完成/自动收货等),进行相关分账
// 订单
$orderMain = $this->orderOnlineService->check($orderMainId, $userId,OrderState::FINISH);
$currentTime = time();
Db::beginTransaction();
try {
// =======商户订单收入流水 / Start=======
// 查询子订单
$orders = Order::query()
->where(['order_main_id' => $orderMain->id])
->get()->toArray();
// 新商户流水
foreach ($orders as $key => &$order) {
$store = Store::query()->find($order['store_id']);
$this->financialRecordService->storeByOLOrderComp($store->user_id, $orderMain->global_order_id ,$order['money']);
}
// =======商户订单收入流水 / End=======
// =======社区服务点分账 / Start=======
// 前提:用户线上下单并且订单完成
// 奖励规则A:用户是平台新用户,奖励社区服务点平台新用户奖励x元+平台新用户首单奖励y元+订单商品金额z%的分成
// 奖励规则B:用户是非新用户,奖励社区服务点订单实际支付金额z%的分成
// =======社区服务点分账 / Start=======
// 当前用户的社区服务点绑定关系
$communityBind = UserRelationBind::query()
->where(['bind_type' => UserRelationBind::BIND_TYPE_COMMUNITY, 'user_id' => $orderMain->user_id])
->first();
if ($communityBind) {
// 奖励/分账金额
$award = ServiceReward::query()->where(['type' => ServiceReward::TYPE_COMMUNITY])->first();
if (empty($award)) {
Db::rollBack();
return false;
}
$award = $award->set_reward;
// 平台新用户
if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
$this->financialRecordService->communityAwardByPlatNewUser(
$communityBind->source_id,
$orderMain->global_order_id,
$award['new_user_reward']
);
$this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder(
$communityBind->source_id,
$orderMain->global_order_id,
$award['first_reward']
);
}
// 账单分成
$money = bcmul($orderMain->money, bcdiv($award['flow_reward'], 100, 6), 2);
$this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $orderMain->global_order_id, $money);
}
// =======社区服务点分账 / End=======
Db::commit();
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
Db::rollBack();
return false;
}
}
/**
* @inheritDoc
*/
public function orderOfflinePaid($orderMainId)
{
// 线下订单支付完成
// 订单
$orderMain = OrderMain::query()->find($orderMainId);
$global_order_id = $orderMain->global_order_id;
if (empty($orderMain)) {
return false;
}
// 查询子订单,当面付目前实际上只有一个子订单
$order = Order::query()
->where(['order_main_id' => $orderMain->id])
->first();
if (empty($order)) {
return false;
}
$currentTime = time();
Db::beginTransaction();
try {
// =======用户支付流水 / Start=======
$this->financialRecordService->userByOFLOrderPaid($orderMain->user_id, $global_order_id, $orderMain->money);
// =======用户支付流水 / End=======
// =======线下订单支付完成商户分账 / Start=======
// 前提:用户线上下单并且支付完成
// 奖励规则A:用户是平台新用户,奖励商户2元
// 奖励规则B:用户是非新用户,但是是商户当日首单,奖励商户0.05元
// =======线下订单支付完成商户分账 / Start=======
$message = [];
// 商户
$store = Store::find($order->store_id);
// 新商户订单流水
$this->financialRecordService->storeByOFLOrderComp($store->user_id, $global_order_id, $order->money);
$needAward = false;
$awardAmount = 0;
// 新用户商户奖励
if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
$awardAmount = 2;
// 旧商户流水 TODO 直接移除或后续考虑移除
$message = [
'money' => $awardAmount,
'note' => '新用户下单成功,平台奖励',
];
// 新商户流水
$this->financialRecordService->storeAwardByPlatNewUserOFLOrder($store->user_id, $global_order_id, $awardAmount);
$needAward = true;
} else {
// 商户当日首单奖励
if (
$this->userService->isStoreFirstOrderToday(
$order->user_id,
$order->store_id,
$order->id,
FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
)
&& $order->money >= FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
) {
$awardAmount = 0.05;
// 旧商户流水 TODO 直接移除或后续考虑移除
$message = [
'money' => $awardAmount,
'note' => '用户下单成功,平台奖励',
];
// 新商户流水
$this->financialRecordService->storeAwardByTodayFirstOFLOrder($store->user_id, $global_order_id, $awardAmount);
$needAward = true;
}
}
if ($needAward && $awardAmount) {
// 发模板消息
$openid = User::query()->where(['id' => $store['user_id']])->value('openid');
$res = $this->miniprogramService->sendTemMsgForAward($message['money'], $message['note'], $openid, date('Y-m-d H:i:s', $currentTime));
}
// =======线下订单支付完成商户分账 / End=======
Db::commit();
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
Db::rollBack();
return false;
}
}
}