From e91ba2239be2d136331b5eba5ed5233510847131 Mon Sep 17 00:00:00 2001 From: weigang Date: Fri, 21 Aug 2020 19:02:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8B=E5=8D=95=E6=B5=81=E6=B0=B4=E5=92=8C?= =?UTF-8?q?=E5=88=86=E8=B4=A6=EF=BC=9A=E7=94=A8=E6=88=B7=E3=80=81=E5=95=86?= =?UTF-8?q?=E6=88=B7=E3=80=81=E5=95=86=E6=88=B7=E5=A5=96=E5=8A=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Constants/LogLabel.php | 11 + app/Controller/NotifyController.php | 316 ++++++++++-------- app/Model/FinancialRecord.php | 11 +- app/Model/UserBalance.php | 33 ++ app/Service/FinancialRecordService.php | 186 +++++++---- .../FinancialRecordServiceInterface.php | 88 ++++- app/Service/OrderService.php | 136 ++++++++ app/Service/OrderServiceInterface.php | 15 + app/Service/SeparateAccountsService.php | 184 +++++++++- 9 files changed, 762 insertions(+), 218 deletions(-) create mode 100644 app/Model/UserBalance.php diff --git a/app/Constants/LogLabel.php b/app/Constants/LogLabel.php index 04b91be..d4b9f72 100644 --- a/app/Constants/LogLabel.php +++ b/app/Constants/LogLabel.php @@ -43,4 +43,15 @@ class LogLabel extends AbstractConstants * @Message("Online Order Complete Log Label") */ const ONLINE_COMPLETE_LOG = 'online_complete_log'; + + /** + * @Message("Online Paid Complete Log Label") + */ + const ONLINE_PAID_LOG = 'online_paid_log'; + + /** + * @Message("Offline Paid Complete Log Label") + */ + const OFFLINE_PAID_LOG = 'offline_paid_log'; + } diff --git a/app/Controller/NotifyController.php b/app/Controller/NotifyController.php index 8376952..1ddfb11 100644 --- a/app/Controller/NotifyController.php +++ b/app/Controller/NotifyController.php @@ -18,6 +18,8 @@ use App\Service\DeviceServiceInterface; use App\Service\FeiePrintServiceInterface; use App\Service\MiniprogramServiceInterface; use App\Service\MqttServiceInterface; +use App\Service\OrderServiceInterface; +use App\Service\SeparateAccountsServiceInterface; use App\Service\UserServiceInterface; use EasyWeChat\Factory; use Hyperf\DbConnection\Db; @@ -68,6 +70,18 @@ class NotifyController extends BaseController */ protected $couponRebateService; + /** + * @Inject + * @var OrderServiceInterface + */ + protected $orderService; + + /** + * @Inject + * @var SeparateAccountsServiceInterface + */ + protected $separateAccountsService; + public function wxminiOnline() { @@ -122,65 +136,68 @@ class NotifyController extends BaseController return true; } - // 修改订单、子订单状态 - $currentTime = time(); - $orderMain->state = OrderMain::ORDER_STATE_UNTAKE; - $orderMain->time_pay = $currentTime; - $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); - $orderMain->save(); - - $upOrder = Order::query() - ->where(['order_main_id' => $orderMain->id]) - ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]); - - // 更新商户销量 - $upStoreScore = Store::query() - ->whereIn('id', explode(',', $orderMain->store_ids)) - ->update(['score' => Db::raw('score+1')]); - - // 更新商品库存和销量 - $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) - ->where(['order_main_id' => $orderMain->id]) - ->get() - ->toArray(); - $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id']) - ->whereIn('order_id', array_values(array_column($orders, 'id'))) - ->get() - ->toArray(); - foreach ($orderGoods as $key => &$goodsItem) { - - $goods = Goods::find($goodsItem['id']); - - // 库存处理,有规格 - if ($goodsItem['combination_id']) { - $combination = SpecCombination::find($goodsItem['combination_id']); - $combination->number = $combination->number - $goodsItem['number']; - $combination->save(); - } else { - $goods->inventory = $goods->inventory - $goodsItem['number']; - } - - $goods->sales = $goods->sales - $goodsItem['number']; - $goods->save(); - - } - - // 月销流水 - $statistics = []; - foreach ($orders as $key => &$order) { - $statistics[] = [ - 'money' => $order['money'], - 'user_id' => $order['user_id'], - 'store_id' => $order['store_id'], - 'market_id' => $orderMain->market_id, - 'order_id' => $order['id'], - 'createtime' => strtotime($order['pay_time']), - ]; - } - - if (is_array($statistics) && !empty($statistics)) { - $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics); - } + $this->orderService->onlinePaid($message['out_trade_no']); + $this->separateAccountsService->orderOnlinePaid($message['out_trade_no']); + + // // 修改订单、子订单状态 + // $currentTime = time(); + // $orderMain->state = OrderMain::ORDER_STATE_UNTAKE; + // $orderMain->time_pay = $currentTime; + // $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); + // $orderMain->save(); + // + // $upOrder = Order::query() + // ->where(['order_main_id' => $orderMain->id]) + // ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]); + // + // // 更新商户销量 + // $upStoreScore = Store::query() + // ->whereIn('id', explode(',', $orderMain->store_ids)) + // ->update(['score' => Db::raw('score+1')]); + // + // // 更新商品库存和销量 + // $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) + // ->where(['order_main_id' => $orderMain->id]) + // ->get() + // ->toArray(); + // $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id']) + // ->whereIn('order_id', array_values(array_column($orders, 'id'))) + // ->get() + // ->toArray(); + // foreach ($orderGoods as $key => &$goodsItem) { + // + // $goods = Goods::find($goodsItem['id']); + // + // // 库存处理,有规格 + // if ($goodsItem['combination_id']) { + // $combination = SpecCombination::find($goodsItem['combination_id']); + // $combination->number = $combination->number - $goodsItem['number']; + // $combination->save(); + // } else { + // $goods->inventory = $goods->inventory - $goodsItem['number']; + // } + // + // $goods->sales = $goods->sales - $goodsItem['number']; + // $goods->save(); + // + // } + // + // // 月销流水 + // $statistics = []; + // foreach ($orders as $key => &$order) { + // $statistics[] = [ + // 'money' => $order['money'], + // 'user_id' => $order['user_id'], + // 'store_id' => $order['store_id'], + // 'market_id' => $orderMain->market_id, + // 'order_id' => $order['id'], + // 'createtime' => strtotime($order['pay_time']), + // ]; + // } + // + // if (is_array($statistics) && !empty($statistics)) { + // $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics); + // } // 优惠券返券 $this->couponRebateService->couponRebateInTask($orderMain->id); @@ -192,7 +209,7 @@ class NotifyController extends BaseController // 公众号模板消息 $res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->id); - // 打印订单,自动打印 TODO 后续优化调用逻辑 + // 打印订单,自动打印 $res = $this->feiePrintService->feiePrint($orderMain->global_order_id); Db::commit(); @@ -271,94 +288,97 @@ class NotifyController extends BaseController return true; } - // 修改订单、子订单状态 - $currentTime = time(); - $orderMain->state = OrderMain::ORDER_STATE_UNTAKE; - $orderMain->dm_state = OrderMain::ORDER_STATE_UNTAKE; - $orderMain->time_pay = $currentTime; - $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); - $orderMain->save(); - - $upOrder = Order::query() - ->where(['order_main_id' => $orderMain->id]) - ->update([ - 'state' => OrderMain::ORDER_STATE_UNTAKE, - 'dm_state' => OrderMain::ORDER_STATE_UNTAKE, - 'pay_time' => date('Y-m-d H:i:s', $currentTime) - ]); - - // 查询子订单,当面付目前实际上只有一个子订单 - $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) - ->where(['order_main_id' => $orderMain->id]) - ->get() - ->toArray(); - - // 商户钱包、流水资金、奖励、发布模板消息处理 - foreach ($orders as $key => $orderItem) { - - $recordBase = [ - 'user_id' => $orderItem['user_id'], - 'order_id' => $orderItem['id'], - 'store_id' => $orderItem['store_id'], - 'type' => 1, - 'time' => date('Y-m-d H:i:s', $currentTime), - 'add_time' => $currentTime, - ]; - - // 钱包 - $store = Store::find($orderItem['store_id']); - $store->store_wallet = bcadd($store->store_wallet, $orderItem['money'], 2); - $store->save(); - - // 流水 - $record = [ - 'money' => $orderItem['money'], - 'note' => '当面付订单收入', - 'category' => 2, - ]; - StoreAccount::query()->insert(array_merge($recordBase, $record)); - - // 平台新用户奖励给商户 - $isStageNewUser = $this->userService->isPlatformNewUser($orderItem['user_id'], $orderMain->id); - $needAward = false; - $awardAmount = 0; - if ($isStageNewUser) { - $awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_new_user'])->value('value'); - // 流水 - $record = [ - 'money' => $awardAmount, - 'note' => '新用户下单成功,平台奖励', - 'category' => 3, - ]; - $needAward = true; - } else { - $isStoreFirstOrderToday = $this->userService->isStoreFirstOrderToday($orderItem['user_id'],$orderItem['store_id'],$orderItem['id'], self::AWARD_LIMIT_AMOUNT); - if ($isStoreFirstOrderToday && $orderItem['money'] >= self::AWARD_LIMIT_AMOUNT) { - $awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_each_order'])->value('value'); - // 流水 - $record = [ - 'money' => $awardAmount, - 'note' => '用户下单成功,平台奖励', - 'category' => 4, - ]; - $needAward = true; - } - } - - if ($needAward && $awardAmount) { - // 奖励钱包 - $store->refresh(); - $store->award_money = bcadd($store->award_money, $awardAmount, 2); - $store->save(); - - // 流水 - StoreAccount::query()->insert(array_merge($recordBase, $record)); - - // 发布公众号消息 - $openid = Users::query()->where(['id' => $store['user_id']])->value('openid'); - $res = $this->miniprogramService->sendTemMsgForAward($record['money'], $record['note'], $openid, $recordBase['time']); - } - } + $orderPaid = $this->orderService->offlinePaid($message['out_trade_no']); + $separate = $this->separateAccountsService->orderOfflinePaid($message['out_trade_no']); + + // // 修改订单、子订单状态 + // $currentTime = time(); + // $orderMain->state = OrderMain::ORDER_STATE_UNTAKE; + // $orderMain->dm_state = OrderMain::ORDER_STATE_UNTAKE; + // $orderMain->time_pay = $currentTime; + // $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); + // $orderMain->save(); + // + // $upOrder = Order::query() + // ->where(['order_main_id' => $orderMain->id]) + // ->update([ + // 'state' => OrderMain::ORDER_STATE_UNTAKE, + // 'dm_state' => OrderMain::ORDER_STATE_UNTAKE, + // 'pay_time' => date('Y-m-d H:i:s', $currentTime) + // ]); + + // // 查询子订单,当面付目前实际上只有一个子订单 + // $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) + // ->where(['order_main_id' => $orderMain->id]) + // ->get() + // ->toArray(); + // + // // 商户钱包、流水资金、奖励、发布模板消息处理 + // foreach ($orders as $key => $orderItem) { + // + // $recordBase = [ + // 'user_id' => $orderItem['user_id'], + // 'order_id' => $orderItem['id'], + // 'store_id' => $orderItem['store_id'], + // 'type' => 1, + // 'time' => date('Y-m-d H:i:s', $currentTime), + // 'add_time' => $currentTime, + // ]; + // + // // 钱包 + // $store = Store::find($orderItem['store_id']); + // $store->store_wallet = bcadd($store->store_wallet, $orderItem['money'], 2); + // $store->save(); + // + // // 流水 + // $record = [ + // 'money' => $orderItem['money'], + // 'note' => '当面付订单收入', + // 'category' => 2, + // ]; + // StoreAccount::query()->insert(array_merge($recordBase, $record)); + // + // // 平台新用户奖励给商户 + // $isStageNewUser = $this->userService->isPlatformNewUser($orderItem['user_id'], $orderMain->id); + // $needAward = false; + // $awardAmount = 0; + // if ($isStageNewUser) { + // $awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_new_user'])->value('value'); + // // 流水 + // $record = [ + // 'money' => $awardAmount, + // 'note' => '新用户下单成功,平台奖励', + // 'category' => 3, + // ]; + // $needAward = true; + // } else { + // $isStoreFirstOrderToday = $this->userService->isStoreFirstOrderToday($orderItem['user_id'],$orderItem['store_id'],$orderItem['id'], self::AWARD_LIMIT_AMOUNT); + // if ($isStoreFirstOrderToday && $orderItem['money'] >= self::AWARD_LIMIT_AMOUNT) { + // $awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_each_order'])->value('value'); + // // 流水 + // $record = [ + // 'money' => $awardAmount, + // 'note' => '用户下单成功,平台奖励', + // 'category' => 4, + // ]; + // $needAward = true; + // } + // } + // + // if ($needAward && $awardAmount) { + // // 奖励钱包 + // $store->refresh(); + // $store->award_money = bcadd($store->award_money, $awardAmount, 2); + // $store->save(); + // + // // 流水 + // StoreAccount::query()->insert(array_merge($recordBase, $record)); + // + // // 发布公众号消息 + // $openid = Users::query()->where(['id' => $store['user_id']])->value('openid'); + // $res = $this->miniprogramService->sendTemMsgForAward($record['money'], $record['note'], $openid, $recordBase['time']); + // } + // } // 喇叭通知,兼容旧音响,MQTT+IOT $res = $this->mqttSpeakerService->speakToStore($orderMain->id); diff --git a/app/Model/FinancialRecord.php b/app/Model/FinancialRecord.php index d7343d2..0096c9a 100644 --- a/app/Model/FinancialRecord.php +++ b/app/Model/FinancialRecord.php @@ -7,6 +7,11 @@ namespace App\Model; */ class FinancialRecord extends Model { + /** + * 当面付商户首单奖励限制的订单金额 + */ + const OFL_FIRST_AWARD_LIMIT_AMOUNT = 3; + /** * 虚拟账户 */ @@ -50,7 +55,11 @@ class FinancialRecord extends Model */ const MONEY_TYPE_PLAT_NEW_USER = 1; const MONEY_TYPE_FIRST_ORDER = 2; - const MONEY_TYPE_OL_ORDER = 51; + const MONEY_TYPE_OL_ORDER = 3; + const MONEY_TYPE_STORE_PLAT_NEW_USER = 4; + const MONEY_TYPE_STORE_FIRST_ORDER = 5; + const MONEY_TYPE_USER_OFL_ORDER = 100; + const MONEY_TYPE_USER_OL_ORDER = 101; /** * 状态 diff --git a/app/Model/UserBalance.php b/app/Model/UserBalance.php new file mode 100644 index 0000000..62f988e --- /dev/null +++ b/app/Model/UserBalance.php @@ -0,0 +1,33 @@ +record( - $user_id, + return $this->record( + FinancialRecord::ACCOUNT_LEDGER, [ - 'user_id' => $user_id, - 'user_type' => $user_type, + 'user_id' => FinancialRecord::ACCOUNT_LEDGER, + 'user_type' => FinancialRecord::USER_TYPE_LEDGER, 'money' => $money, 'money_type' => $money_type, 'source_id' => $source_id, @@ -24,40 +25,107 @@ class FinancialRecordService implements FinancialRecordServiceInterface 'desc' => $desc, 'comment' => $comment, 'status' => FinancialRecord::STATUS_NORMAL, - ] + ], + true ); + } + + public function record($user_id, $record, $isLedger=false) + { + $financialRecord = new FinancialRecord(); + + if (!$isLedger) { + $mod = bcmod((string)$user_id, '5', 0); + $financialRecord->suffix($mod); + } + + return $financialRecord->fill( + [ + 'user_id' => $user_id, + 'user_type' => $record['user_type'], + 'money' => $record['money'], + 'money_type' => $record['money_type'], + 'source_id' => $record['source_id'], + 'source_type' => $record['source_type'], + 'desc' => $record['desc'], + 'comment' => $record['comment'], + 'status' => $record['status'], + ] + )->save(); - $this->ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment); } /** * @inheritDoc */ - public function communityAwardByPlatNewUserFirstOLOrder($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $desc='新用户首单奖励', $comment='社区服务点') + public function communityAwardByPlatNewUser($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $desc='新用户奖励', $comment='社区服务点') { - $this->record( - $user_id, - [ - 'user_id' => $user_id, - 'user_type' => $user_type, - 'money' => $money, - 'money_type' => $money_type, - 'source_id' => $source_id, - 'source_type' => $source_type, - 'desc' => $desc, - 'comment' => $comment, - 'status' => FinancialRecord::STATUS_NORMAL, - ] - ); + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + // 维护社区服务点余额 + $balance = UserBalance::firstOrNew([ + 'user_type' => UserBalance::USER_TYPE_CS, + 'source_id' => $source_id + ]); + $balance->balance = bcadd($balance->balance, $money); + $balance->save(); + } - $this->ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment); + /** + * @inheritDoc + */ + public function communityAwardByPlatNewUserFirstOLOrder($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $desc='新用户首单奖励', $comment='社区服务点') + { + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + // 维护社区服务点余额 + $balance = UserBalance::firstOrNew([ + 'user_type' => UserBalance::USER_TYPE_CS, + 'source_id' => $source_id + ]); + $balance->balance = bcadd($balance->balance, $money); + $balance->save(); + } + + /** + * @inheritDoc + */ + public function communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=3, $desc='用户订单分成', $comment='社区服务点') + { + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + // 维护社区服务点余额 + $balance = UserBalance::firstOrNew([ + 'user_type' => UserBalance::USER_TYPE_CS, + 'source_id' => $source_id + ]); + $balance->balance = bcadd($balance->balance, $money); + $balance->save(); } + /** * @inheritDoc */ - public function communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $desc='用户订单分成', $comment='社区服务点') + public function storeAwardByPlatNewUserOFLOrder($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=4, $desc='新用户下单奖励', $comment='用户当面付商户奖励') { + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + // 同时维护钱包 + $store = Store::query()->where(['user_id' => $user_id])->first(); + $store->award_money = bcadd($store->award_money, $money, 2); + $store->save(); + } + + /** + * @inheritDoc + */ + public function storeAwardByTodayFirstOFLOrder($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=5, $desc='用户店铺首单奖励', $comment='用户当面付商户奖励') + { + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + // 同时维护钱包 + $store = Store::query()->where(['user_id' => $user_id])->first(); + $store->award_money = bcadd($store->award_money, $money, 2); + $store->save(); + } + + public function recordAll($user_id, $source_id, $money, $user_type=1, $source_type=0, $money_type=0, $desc='', $comment='') { $this->record( $user_id, [ @@ -76,47 +144,39 @@ class FinancialRecordService implements FinancialRecordServiceInterface $this->ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment); } - public function ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment='') + /** + * @inheritDoc + */ + public function userByOFLOrderPaid($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=100, $desc='用户下单(线下)', $comment='用户下单') { - return $this->record( - FinancialRecord::ACCOUNT_LEDGER, - [ - 'user_id' => FinancialRecord::ACCOUNT_LEDGER, - 'user_type' => FinancialRecord::USER_TYPE_LEDGER, - 'money' => $money, - 'money_type' => $money_type, - 'source_id' => $source_id, - 'source_type' => $source_type, - 'desc' => $desc, - 'comment' => $comment, - 'status' => FinancialRecord::STATUS_NORMAL, - ], - true - ); + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); } - public function record($user_id, $record, $isLedger=false) + /** + * @inheritDoc + */ + public function userByOLOrderPaid($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=101, $desc='用户下单(线上)', $comment='用户下单') { - $financialRecord = new FinancialRecord(); - - if (!$isLedger) { - $mod = bcmod((string)$user_id, '5', 0); - $financialRecord->suffix($mod); - } + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + } - return $financialRecord->fill( - [ - 'user_id' => $user_id, - 'user_type' => $record['user_type'], - 'money' => $record['money'], - 'money_type' => $record['money_type'], - 'source_id' => $record['source_id'], - 'source_type' => $record['source_type'], - 'desc' => $record['desc'], - 'comment' => $record['comment'], - 'status' => $record['status'], - ] - )->save(); + /** + * @inheritDoc + */ + public function storeByOLOrderComp($user_id, $source_id, $money, $user_type = 1, $source_type = 1, $money_type = 6, $desc = '线上外卖订单收入', $comment = '用户订单完成') + { + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); + // 同时维护钱包 + $store = Store::query()->where(['user_id' => $user_id])->first(); + $store->store_wallet = bcadd($store->store_wallet, $money, 2); + $store->save(); + } + /** + * @inheritDoc + */ + public function storeByOFLOrderComp($user_id, $source_id, $money, $user_type = 1, $source_type = 1, $money_type = 7, $desc = '线下当面付订单收入', $comment = '用户订单完成') + { + $this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); } } \ No newline at end of file diff --git a/app/Service/FinancialRecordServiceInterface.php b/app/Service/FinancialRecordServiceInterface.php index 4078043..8a53628 100644 --- a/app/Service/FinancialRecordServiceInterface.php +++ b/app/Service/FinancialRecordServiceInterface.php @@ -31,7 +31,7 @@ interface FinancialRecordServiceInterface * @param string $desc * @return mixed */ - public function communityAwardByPlatNewUserFirstOLOrder($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $desc='新用户首单奖励', $comment=''); + public function communityAwardByPlatNewUserFirstOLOrder($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $desc='新用户首单奖励', $comment=''); /** * 社区服务点用户订单完成分账 @@ -45,7 +45,7 @@ interface FinancialRecordServiceInterface * @param string $desc * @return mixed */ - public function communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $desc='用户订单分成', $comment=''); + public function communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=3, $desc='用户订单分成', $comment=''); /** * 收支总账 @@ -59,4 +59,88 @@ interface FinancialRecordServiceInterface */ public function ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment=''); + /** + * 商户线下用户支付新用户奖励 + * @param $user_id + * @param $source_id + * @param $money + * @param int $user_type + * @param int $source_type + * @param int $money_type + * @param string $desc + * @param string $comment + * @return mixed + */ + public function storeAwardByPlatNewUserOFLOrder($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=4, $desc='新用户下单奖励', $comment=''); + + /** + * 商户线下用户支付用户当日首单奖励 + * @param $user_id + * @param $source_id + * @param $money + * @param int $user_type + * @param int $source_type + * @param int $money_type + * @param string $desc + * @param string $comment + * @return mixed + */ + public function storeAwardByTodayFirstOFLOrder($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=5, $desc='用户店铺首单奖励', $comment=''); + + /** + * 用户线下订单支付流水 + * @param $user_id + * @param $source_id + * @param $money + * @param int $user_type + * @param int $source_type + * @param int $money_type + * @param string $desc + * @param string $comment + * @return mixed + */ + public function userByOFLOrderPaid($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=100, $desc='用户下单(线下)', $comment=''); + + /** + * 用户线上订单支付流水 + * @param $user_id + * @param $source_id + * @param $money + * @param int $user_type + * @param int $source_type + * @param int $money_type + * @param string $desc + * @param string $comment + * @return mixed + */ + public function userByOLOrderPaid($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=101, $desc='用户下单(线上)', $comment=''); + + /** + * 商户线上订单完成收入流水 + * @param $user_id + * @param $source_id + * @param $money + * @param int $user_type + * @param int $source_type + * @param int $money_type + * @param string $desc + * @param string $comment + * @return mixed + */ + public function storeByOLOrderComp($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=6, $desc='线上外卖订单收入', $comment=''); + + /** + * 商户线下订单完成收入流水 + * @param $user_id + * @param $source_id + * @param $money + * @param int $user_type + * @param int $source_type + * @param int $money_type + * @param string $desc + * @param string $comment + * @return mixed + */ + public function storeByOFLOrderComp($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=7, $desc='线下当面付订单收入', $comment=''); + } \ No newline at end of file diff --git a/app/Service/OrderService.php b/app/Service/OrderService.php index 7aa31e1..fd918bd 100644 --- a/app/Service/OrderService.php +++ b/app/Service/OrderService.php @@ -11,7 +11,9 @@ use App\Model\Goods; use App\Model\Order; use App\Model\OrderGoods; use App\Model\OrderMain; +use App\Model\OrderSalesStatistic; use App\Model\SpecCombination; +use App\Model\Store; use Exception; use Hyperf\DbConnection\Db; use Hyperf\Snowflake\IdGeneratorInterface; @@ -564,4 +566,138 @@ class OrderService implements OrderServiceInterface } } + + /** + * @inheritDoc + */ + public function onlinePaid($global_order_id) + { + Db::beginTransaction(); + try { + // 查询订单 + $orderMain = OrderMain::query() + ->where([ + 'global_order_id' => $global_order_id, + 'type' => OrderMain::ORDER_TYPE_ONLINE + ]) + ->first(); + + // 修改订单、子订单状态 + $currentTime = time(); + $orderMain->state = OrderMain::ORDER_STATE_UNTAKE; + $orderMain->time_pay = $currentTime; + $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); + $orderMain->save(); + + $upOrder = Order::query() + ->where(['order_main_id' => $orderMain->id]) + ->update(['state' => OrderMain::ORDER_STATE_UNTAKE, 'pay_time' => $orderMain->pay_time]); + + // 更新商户销量 + $upStoreScore = Store::query() + ->whereIn('id', explode(',', $orderMain->store_ids)) + ->update(['score' => Db::raw('score+1')]); + + // 更新商品库存和销量 + $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) + ->where(['order_main_id' => $orderMain->id]) + ->get() + ->toArray(); + $orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id']) + ->whereIn('order_id', array_values(array_column($orders, 'id'))) + ->get() + ->toArray(); + foreach ($orderGoods as $key => &$goodsItem) { + + $goods = Goods::find($goodsItem['id']); + + // 库存处理,有规格 + if ($goodsItem['combination_id']) { + $combination = SpecCombination::find($goodsItem['combination_id']); + $combination->number = $combination->number - $goodsItem['number']; + $combination->save(); + } else { + $goods->inventory = $goods->inventory - $goodsItem['number']; + } + + $goods->sales = $goods->sales - $goodsItem['number']; + $goods->save(); + + } + + // 月销流水 + $statistics = []; + foreach ($orders as $key => &$order) { + $statistics[] = [ + 'money' => $order['money'], + 'user_id' => $order['user_id'], + 'store_id' => $order['store_id'], + 'market_id' => $orderMain->market_id, + 'order_id' => $order['id'], + 'createtime' => strtotime($order['pay_time']), + ]; + } + + if (is_array($statistics) && !empty($statistics)) { + $inSalesStatistics = OrderSalesStatistic::query()->insert($statistics); + } + + Db::commit(); + return true; + } catch (Exception $e) { + + $this->log->event(LogLabel::ONLINE_PAID_LOG, ['exception' => $e->getMessage()]); + Db::rollBack(); + return false; + } + } + + /** + * @inheritDoc + */ + public function offlinePaid($global_order_id) + { + Db::beginTransaction(); + try { + + // 主订单状态更新 + $orderMain = OrderMain::query() + ->where(['global_order_id' => $global_order_id, 'type' => OrderMain::ORDER_TYPE_OFFLINE]) + ->first(); + + if (empty($orderMain)) { + + $this->log->event( + LogLabel::PAY_NOTIFY_WXMINI, + ['order_not_found' => $global_order_id] + ); + Db::rollBack(); + return false; + } + + $currentTime = time(); + $orderMain->state = OrderMain::ORDER_STATE_UNTAKE; + $orderMain->dm_state = OrderMain::ORDER_STATE_UNTAKE; + $orderMain->time_pay = $currentTime; + $orderMain->pay_time = date('Y-m-d H:i:s', $currentTime); + $orderMain->save(); + + // 子订单状态更新 + $upOrder = Order::query() + ->where(['order_main_id' => $orderMain->id]) + ->update([ + 'state' => OrderMain::ORDER_STATE_UNTAKE, + 'dm_state' => OrderMain::ORDER_STATE_UNTAKE, + 'pay_time' => date('Y-m-d H:i:s', $currentTime) + ]); + + Db::commit(); + return true; + } catch (Exception $e) { + + $this->log->event(LogLabel::OFFLINE_PAID_LOG, ['exception' => $e->getMessage()]); + Db::rollBack(); + return false; + } + } } \ No newline at end of file diff --git a/app/Service/OrderServiceInterface.php b/app/Service/OrderServiceInterface.php index 92fa986..01cb413 100644 --- a/app/Service/OrderServiceInterface.php +++ b/app/Service/OrderServiceInterface.php @@ -28,9 +28,24 @@ interface OrderServiceInterface public function existsByGlobalOrderId($global_order_id); /** + * 订单完成 * @param $global_order_id * @return mixed */ public function onlineCompleted($global_order_id); + /** + * 线上订单支付完成 + * @param $global_order_id + * @return mixed + */ + public function onlinePaid($global_order_id); + + /** + * 线下订单支付完成 + * @param $global_order_id + * @return mixed + */ + public function offlinePaid($global_order_id); + } \ No newline at end of file diff --git a/app/Service/SeparateAccountsService.php b/app/Service/SeparateAccountsService.php index 4958584..994e1b4 100644 --- a/app/Service/SeparateAccountsService.php +++ b/app/Service/SeparateAccountsService.php @@ -4,8 +4,14 @@ namespace App\Service; use App\Commons\Log; use App\Constants\LogLabel; +use App\Model\FinancialRecord; +use App\Model\Order; use App\Model\OrderMain; use App\Model\ServiceReward; +use App\Model\Store; +use App\Model\StoreAccount; +use App\Model\SystemConfig; +use App\Model\UserBalance; use App\Model\UserRelationBind; use Hyperf\DbConnection\Db; use Hyperf\Di\Annotation\Inject; @@ -30,12 +36,30 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface */ protected $financialRecordService; + /** + * @Inject + * @var MiniprogramServiceInterface + */ + protected $miniprogramService; + /** * @inheritDoc */ public function orderOnlinePaid($global_order_id) { - // TODO: Implement orderOnlinePaid() method. + // 线上订单支付完成 + // 订单 + $orderMain = OrderMain::query() + ->where(['global_order_id' => $global_order_id]) + ->first(); + + if (empty($orderMain)) { + return false; + } + + // =======用户支付流水 / Start======= + $this->financialRecordService->userByOFLOrderPaid($orderMain->user_id, $orderMain->id, $orderMain->money); + // =======用户支付流水 / End======= } /** @@ -51,12 +75,47 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface ->first(); if (empty($orderMain)) { - return; + return false; } + $currentTime = time(); Db::beginTransaction(); try { + // =======商户订单收入流水 / Start======= + // 查询子订单 + $orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) + ->where(['order_main_id' => $orderMain->id]) + ->get()->toArray(); + + foreach ($orders as $key => &$order) { + + // 商户 + $store = Store::find($order['store_id']); + + // 旧商户流水基础数据 TODO 直接移除或后续考虑移除 + $storeAccountBase = [ + 'user_id' => $order['user_id'], + 'order_id' => $order['id'], + 'store_id' => $order['store_id'], + 'type' => 1, + 'time' => date('Y-m-d H:i:s', $currentTime), + 'add_time' => $currentTime, + ]; + + // 旧商户流水 TODO 直接移除或后续考虑移除 + $storeAccount = [ + 'money' => $order['money'], + 'note' => '线上订单', + 'category' => 1, + ]; + StoreAccount::query()->insert(array_merge($storeAccountBase, $storeAccount)); + + // 新商户流水 + $this->financialRecordService->storeByOLOrderComp($store->user_id, $orderMain->id ,$order['money']); + } + // =======商户订单收入流水 / End======= + // =======社区服务点分账 / Start======= // 前提:用户线上下单并且订单完成 // 奖励规则A:用户是平台新用户,奖励社区服务点平台新用户奖励x元+平台新用户首单奖励y元+订单商品金额z%的分成 @@ -86,7 +145,7 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface } // 账单分成 - $money = bcmul($orderMain->money, $award['flow_reward']); + $money = bcmul($orderMain->money, bcdiv($award['flow_reward'], 100, 6), 2); $this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $orderMain->global_order_id, $money); } @@ -109,6 +168,123 @@ class SeparateAccountsService implements SeparateAccountsServiceInterface */ public function orderOfflinePaid($global_order_id) { - // TODO: Implement orderOfflinePaid() method. + // 线下订单支付完成 + // 订单 + $orderMain = OrderMain::query() + ->where(['global_order_id' => $global_order_id]) + ->first(); + + if (empty($orderMain)) { + return false; + } + + // 查询子订单,当面付目前实际上只有一个子订单 + $order = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time']) + ->where(['order_main_id' => $orderMain->id]) + ->first(); + + if (empty($order)) { + return false; + } + + $currentTime = time(); + Db::beginTransaction(); + try { + + // =======用户支付流水 / Start======= + $this->financialRecordService->userByOFLOrderPaid($orderMain->user_id, $orderMain->id, $orderMain->money); + // =======用户支付流水 / End======= + + // =======线下订单支付完成商户分账 / Start======= + // 前提:用户线上下单并且支付完成 + // 奖励规则A:用户是平台新用户,奖励商户2元 + // 奖励规则B:用户是非新用户,但是是商户当日首单,奖励商户0.05元 + // =======线下订单支付完成商户分账 / Start======= + + // 旧商户订单流水基础数据 TODO 直接移除或后续考虑移除 + $storeAccountBase = [ + 'user_id' => $order->user_id, + 'order_id' => $order->id, + 'store_id' => $order->store_id, + 'type' => 1, + 'time' => date('Y-m-d H:i:s', $currentTime), + 'add_time' => $currentTime, + ]; + + // 旧商户订单流水 TODO 直接移除或后续考虑移除 + $storeAccount = [ + 'money' => $order->money, + 'note' => '当面付订单收入', + 'category' => 2, + ]; + StoreAccount::query()->insert(array_merge($storeAccountBase, $storeAccount)); + + // 商户 + $store = Store::find($order->store_id); + + // 新商户订单流水 + $this->financialRecordService->storeByOFLOrderComp($store->user_id, $orderMain->id, $order->money); + + $needAward = false; + $awardAmount = 0; + // 新用户商户奖励 + if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) { + + $awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_new_user'])->value('value'); + // 旧商户流水 TODO 直接移除或后续考虑移除 + $storeAccount = [ + 'money' => $awardAmount, + 'note' => '新用户下单成功,平台奖励', + 'category' => 3, + ]; + // 新商户流水 + $this->financialRecordService->storeAwardByPlatNewUserOFLOrder($store->user_id, $orderMain->id, $awardAmount); + $needAward = true; + + } else { + // 商户当日首单奖励 + if ( + $this->userService->isStoreFirstOrderToday( + $order->user_id, + $order->store_id, + $order->id, + FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT + ) + ) { + + $awardAmount = SystemConfig::query()->where(['type' => 1, 'menu_name' => 'award_each_order'])->value('value'); + // 旧商户流水 TODO 直接移除或后续考虑移除 + $storeAccount = [ + 'money' => $awardAmount, + 'note' => '用户下单成功,平台奖励', + 'category' => 4, + ]; + // 新商户流水 + $this->financialRecordService->storeAwardByTodayFirstOFLOrder($store->user_id, $orderMain->id, $awardAmount); + $needAward = true; + + } + } + + if ($needAward && $awardAmount) { + + // 旧商户流水 TODO 直接移除或后续考虑移除 + StoreAccount::query()->insert(array_merge($storeAccountBase, $storeAccount)); + + // 发模板消息 + $openid = Users::query()->where(['id' => $store['user_id']])->value('openid'); + $res = $this->miniprogramService->sendTemMsgForAward($storeAccount['money'], $storeAccount['note'], $openid, $storeAccountBase['time']); + } + + // =======线下订单支付完成商户分账 / 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; + } } } \ No newline at end of file