Browse Source

社区服务点分账以及分账基础代码

master
weigang 6 years ago
parent
commit
cbb94cc714
  1. 3
      app/Amqp/Consumer/couponRebateConsumer.php
  2. 5
      app/Constants/ErrorCode.php
  3. 5
      app/Constants/LogLabel.php
  4. 2
      app/Controller/NotifyController.php
  5. 33
      app/JsonRpc/OrderService.php
  6. 8
      app/JsonRpc/OrderServiceInterface.php
  7. 89
      app/Model/FinancialRecord.php
  8. 12
      app/Model/Model.php
  9. 122
      app/Service/FinancialRecordService.php
  10. 62
      app/Service/FinancialRecordServiceInterface.php
  11. 104
      app/Service/SeparateAccountsService.php
  12. 28
      app/Service/SeparateAccountsServiceInterface.php
  13. 2
      app/Service/UserService.php
  14. 2
      app/Service/UserServiceInterface.php
  15. 6
      composer.json
  16. 4
      config/autoload/dependencies.php
  17. 10
      config/autoload/server.php

3
app/Amqp/Consumer/couponRebateConsumer.php

@ -37,6 +37,9 @@ class couponRebateConsumer extends ConsumerMessage
public function isEnable(): bool
{
if(env('APP_ENV') == 'local') {
return false;
}
return parent::isEnable();
}
}

5
app/Constants/ErrorCode.php

@ -54,4 +54,9 @@ class ErrorCode extends AbstractConstants
*/
const PAY_FAILURE = 400;
/**
* @Message("Separate Accounts Error!")
*/
const SEPARATE_ACCOUNTS_ERROR = 700;
}

5
app/Constants/LogLabel.php

@ -33,4 +33,9 @@ class LogLabel extends AbstractConstants
* @Message("Order Log Label")
*/
const ORDER_LOG = 'order_log';
/**
* @Message("Separate Accounts Log Label")
*/
const SEPARATE_ACCOUNTS_LOG = 'separate_accounts_log';
}

2
app/Controller/NotifyController.php

@ -332,7 +332,7 @@ class NotifyController extends BaseController
StoreAccount::query()->insert(array_merge($recordBase, $record));
// 平台新用户奖励给商户
$isStageNewUser = $this->userService->isStageNewUser($orderItem['user_id'], $orderMain->id);
$isStageNewUser = $this->userService->isPlatformNewUser($orderItem['user_id'], $orderMain->id);
$needAward = false;
$awardAmount = 0;
if ($isStageNewUser) {

33
app/JsonRpc/OrderService.php

@ -0,0 +1,33 @@
<?php
namespace App\JsonRpc;
use App\Constants\ErrorCode;
use App\Service\SeparateAccountsServiceInterface;
use Hyperf\RpcServer\Annotation\RpcService;
use Hyperf\Di\Annotation\Inject;
/**
* @RpcService(name="OrderService", protocol="jsonrpc-http", server="jsonrpc-http", publishTo="")
*/
class OrderService implements OrderServiceInterface
{
/**
* @Inject
* @var SeparateAccountsServiceInterface
*/
protected $separateAccService;
public function onlineComplete($global_order_id)
{
$data = $this->separateAccService->orderOnlineCompleted($global_order_id);
return [
"status" => 200,
"code" => $data ? 0 : ErrorCode::SEPARATE_ACCOUNTS_ERROR,
"result" => [],
"message" => $data ? '调用成功' : ErrorCode::getMessage(ErrorCode::SEPARATE_ACCOUNTS_ERROR)
];
}
}

8
app/JsonRpc/OrderServiceInterface.php

@ -0,0 +1,8 @@
<?php
namespace App\JsonRpc;
interface OrderServiceInterface
{
}

89
app/Model/FinancialRecord.php

@ -0,0 +1,89 @@
<?php
declare (strict_types=1);
namespace App\Model;
/**
*/
class FinancialRecord extends Model
{
/**
* 虚拟账户
*/
const ACCOUNT_LEDGER = -1;
/**
* 账户类型
*
* 总账
* USER_TYPE_LEDGER / -1
*
* 用户/商户账户
* USER_TYPE_USER / 1
*
* MP用户账户,服务商、市场经理、服务站点等
* USER_TYPE_MP / 2
*/
const USER_TYPE_LEDGER = -1;
const USER_TYPE_USER = 1;
const USER_TYPE_MP = 2;
/**
* 关联类型
*
* 订单
* SOURCE_TYPE_ORDER / 1
*/
const SOURCE_TYPE_ORDER = 1;
/**
* 流水类型,大的分类,<=50是奖励,>50是分账
*
* MONEY_TYPE_PLAT_NEW_USER
* 社区服务点新用户奖励(线上订单完成) / 1
*
* MONEY_TYPE_FIRST_ORDER
* 社区服务点新用户线上首单奖励(线上订单完成) / 2
*
* MONEY_TYPE_OL_ORDER
* 社区服务点用户线上订单分账(线上订单完成) / 51
*/
const MONEY_TYPE_PLAT_NEW_USER = 1;
const MONEY_TYPE_FIRST_ORDER = 2;
const MONEY_TYPE_OL_ORDER = 51;
/**
* 状态
*/
const STATUS_NORMAL = 1;
const STATUS_ABNORMAL = 2;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_financial_record';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_id',
'user_type',
'money',
'money_type',
'source_id',
'source_type',
'desc',
'comment',
'status',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
}

12
app/Model/Model.php

@ -19,4 +19,16 @@ abstract class Model extends BaseModel implements CacheableInterface
{
use Cacheable;
protected $dateFormat = 'U';
/**
* 设置表后缀
* @param string $suffix
* @return $this
*/
public function suffix($suffix = ''): Model
{
$tableName = $this->getTable();
$this->setTable($tableName.'_'.$suffix);
return $this;
}
}

122
app/Service/FinancialRecordService.php

@ -0,0 +1,122 @@
<?php
namespace App\Service;
use App\Model\FinancialRecord;
class FinancialRecordService implements FinancialRecordServiceInterface
{
/**
* @inheritDoc
*/
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->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='')
{
$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->ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment);
}
/**
* @inheritDoc
*/
public function communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $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->ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment);
}
public function ledgerAccounts($source_id, $money, $source_type, $money_type, $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
);
}
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();
}
}

62
app/Service/FinancialRecordServiceInterface.php

@ -0,0 +1,62 @@
<?php
namespace App\Service;
interface FinancialRecordServiceInterface
{
/**
* 社区服务点新用户奖励
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $comment
* @param string $desc
* @return mixed
*/
public function communityAwardByPlatNewUser($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $desc='新用户奖励', $comment='');
/**
* 社区服务点新用户线上首单奖励
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $comment
* @param string $desc
* @return mixed
*/
public function communityAwardByPlatNewUserFirstOLOrder($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $desc='新用户首单奖励', $comment='');
/**
* 社区服务点用户订单完成分账
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $comment
* @param string $desc
* @return mixed
*/
public function communitySeparateAccountsByOrderComp($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=2, $desc='用户订单分成', $comment='');
/**
* 收支总账
* @param $source_id
* @param $money
* @param $source_type
* @param $money_type
* @param $desc
* @param string $comment
* @return mixed
*/
public function ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment='');
}

104
app/Service/SeparateAccountsService.php

@ -0,0 +1,104 @@
<?php
namespace App\Service;
use App\Commons\Log;
use App\Constants\LogLabel;
use App\Model\OrderMain;
use App\Model\UserRelationBind;
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;
/**
* @inheritDoc
*/
public function orderOnlinePaid($global_order_id)
{
// TODO: Implement orderOnlinePaid() method.
}
/**
* @inheritDoc
*/
public function orderOnlineCompleted($global_order_id)
{
// 线上订单完成(用户点击确认收货完成/管理后台点击完成/配送员点击完成/自动收货等),进行相关分账
// 订单
$orderMain = OrderMain::query()
->where(['global_order_id' => $global_order_id])
->whereIn('state', [OrderMain::ORDER_STATE_COMPLETE,OrderMain::ORDER_STATE_EVALUATED,OrderMain::ORDER_STATE_UNREFUND])
->first();
if (empty($orderMain)) {
return;
}
Db::beginTransaction();
try {
// =======社区服务点分账 / Start=======
// 前提:用户线上下单并且订单完成
// 奖励规则A:用户是平台新用户,奖励社区服务点平台新用户奖励x元+平台新用户首单奖励y元+订单商品金额z%的分成
// 奖励规则B:用户是非新用户,奖励社区服务点订单实际支付金额z%的分成
// =======社区服务点分账 / Start=======
// 奖励/分账金额 TODO 届时查询出来一个配置
$award = ['new_user' => 1, 'first_order' => 2, 'separate_rate' => 2];
// 当前用户的社区服务点绑定关系
$communityBind = UserRelationBind::query()
->where(['bind_type' => UserRelationBind::BIND_TYPE_COMMUNITY, 'user_id' => $orderMain->user_id])
->first();
// 平台新用户
if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
$this->financialRecordService->communityAwardByPlatNewUser($communityBind->source_id, $orderMain->global_order_id, $award['new_user']);
$this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder($communityBind->source_id, $orderMain->global_order_id, $award['first_order']);
}
// 账单分成
$money = bcmul($orderMain->money, bcdiv($award['separate_rate'], 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($global_order_id)
{
// TODO: Implement orderOfflinePaid() method.
}
}

28
app/Service/SeparateAccountsServiceInterface.php

@ -0,0 +1,28 @@
<?php
namespace App\Service;
interface SeparateAccountsServiceInterface
{
/**
* (线上)订单支付完成分账
* @param $global_order_id
* @return mixed
*/
public function orderOnlinePaid($global_order_id);
/**
* (线上)订单确认完成分账
* 用户确认或服务商(服务站确认)
* @param $global_order_id
* @return mixed
*/
public function orderOnlineCompleted($global_order_id);
/**
* (线下)订单支付完成分账
* @param $global_order_id
* @return mixed
*/
public function orderOfflinePaid($global_order_id);
}

2
app/Service/UserService.php

@ -18,7 +18,7 @@ class UserService implements UserServiceInterface
* @param $order_main_id
* @return mixed|void
*/
public function isStageNewUser($user_id, $order_main_id): bool
public function isPlatformNewUser($user_id, $order_main_id): bool
{
$exist = OrderMain::query()
->where(['user_id' => $user_id])

2
app/Service/UserServiceInterface.php

@ -12,7 +12,7 @@ interface UserServiceInterface
* @param $order_main_id
* @return mixed
*/
public function isStageNewUser($user_id, $order_main_id): bool;
public function isPlatformNewUser($user_id, $order_main_id): bool;
public function saveUserUnionid($openid,$unionid);

6
composer.json

@ -36,7 +36,11 @@
"alibabacloud/iot": "^1.8",
"hyperf/snowflake": "^2.0",
"ext-bcmath": "*",
"overtrue/wechat": "~4.0"
"overtrue/wechat": "~4.0",
"hyperf/json-rpc": "^2.0",
"hyperf/rpc-server": "^2.0",
"hyperf/rpc-client": "^2.0",
"hyperf/consul": "^2.0"
},
"require-dev": {
"swoole/ide-helper": "^4.5",

4
config/autoload/dependencies.php

@ -27,4 +27,8 @@ return [
\App\Service\MiniprogramServiceInterface::class => \App\Service\MiniprogramService::class,
\App\Service\UserServiceInterface::class => \App\Service\UserService::class,
\App\Service\UserRelationBindServiceInterface::class => \App\Service\UserCommunityBindService::class,
\Hyperf\JsonRpc\JsonRpcTransporter::class => \Hyperf\JsonRpc\JsonRpcPoolTransporter::class,
\App\JsonRpc\OrderServiceInterface::class => \App\JsonRpc\OrderService::class,
\App\Service\FinancialRecordServiceInterface::class => \App\Service\FinancialRecordService::class,
\App\Service\SeparateAccountsServiceInterface::class => \App\Service\SeparateAccountsService::class,
];

10
config/autoload/server.php

@ -25,6 +25,16 @@ return [
SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9505,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
],
'settings' => [
'enable_coroutine' => true,

Loading…
Cancel
Save