Browse Source

下单流水和分账:用户、商户、商户奖励

master
weigang 6 years ago
parent
commit
e91ba2239b
  1. 11
      app/Constants/LogLabel.php
  2. 316
      app/Controller/NotifyController.php
  3. 11
      app/Model/FinancialRecord.php
  4. 33
      app/Model/UserBalance.php
  5. 184
      app/Service/FinancialRecordService.php
  6. 88
      app/Service/FinancialRecordServiceInterface.php
  7. 136
      app/Service/OrderService.php
  8. 15
      app/Service/OrderServiceInterface.php
  9. 184
      app/Service/SeparateAccountsService.php

11
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';
}

316
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);

11
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;
/**
* 状态

33
app/Model/UserBalance.php

@ -0,0 +1,33 @@
<?php
declare (strict_types=1);
namespace App\Model;
use Hyperf\DbConnection\Model\Model;
/**
*/
class UserBalance extends Model
{
const USER_TYPE_MP = 1;
const USER_TYPE_MM = 2;
const USER_TYPE_CS = 3;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_user_balance';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
}

184
app/Service/FinancialRecordService.php

@ -3,20 +3,21 @@
namespace App\Service;
use App\Model\FinancialRecord;
use App\Model\Store;
use App\Model\UserBalance;
use App\Model\Users;
class FinancialRecordService implements FinancialRecordServiceInterface
{
/**
* @inheritDoc
*/
public function communityAwardByPlatNewUser($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $desc='新用户奖励', $comment='社区服务点')
public function ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment='')
{
$this->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 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 communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $desc='用户订单分成', $comment='社区服务点')
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);
}
}

88
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='');
}

136
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;
}
}
}

15
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);
}

184
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;
}
}
}
Loading…
Cancel
Save