Browse Source
Merge branch 'comunity_bind' into purchase_limit
Merge branch 'comunity_bind' into purchase_limit
# Conflicts: # app/Constants/ErrorCode.php # config/autoload/dependencies.php # config/routes.phpmaster
39 changed files with 1905 additions and 224 deletions
-
3app/Amqp/Consumer/couponRebateConsumer.php
-
5app/Constants/ErrorCode.php
-
21app/Constants/LogLabel.php
-
28app/Controller/CommunityController.php
-
349app/Controller/NotifyController.php
-
71app/Controller/OrderController.php
-
3app/Controller/PaymentController.php
-
92app/JsonRpc/OrderService.php
-
8app/JsonRpc/OrderServiceInterface.php
-
81app/Listener/ValidatorFactoryResolvedListener.php
-
8app/Model/CouponUserRec.php
-
7app/Model/CouponUserUse.php
-
91app/Model/FinancialRecord.php
-
12app/Model/Model.php
-
2app/Model/OrderMain.php
-
33app/Model/ServiceReward.php
-
36app/Model/UserBalance.php
-
40app/Model/UserRelationBind.php
-
45app/Request/CommunityBindRequest.php
-
1app/Request/OrderOnlineRequest.php
-
53app/Service/CouponService.php
-
2app/Service/CouponServiceInterface.php
-
3app/Service/FeiePrintService.php
-
182app/Service/FinancialRecordService.php
-
146app/Service/FinancialRecordServiceInterface.php
-
283app/Service/OrderService.php
-
39app/Service/OrderServiceInterface.php
-
47app/Service/PayRefundService.php
-
8app/Service/PayRefundServiceInterface.php
-
291app/Service/SeparateAccountsService.php
-
28app/Service/SeparateAccountsServiceInterface.php
-
35app/Service/UserCommunityBindService.php
-
48app/Service/UserRelationBindServiceInterface.php
-
2app/Service/UserService.php
-
2app/Service/UserServiceInterface.php
-
6composer.json
-
5config/autoload/dependencies.php
-
10config/autoload/server.php
-
3config/routes.php
@ -0,0 +1,28 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Controller; |
|||
|
|||
use App\Model\UserRelationBind; |
|||
use App\Request\CommunityBindRequest; |
|||
use App\Service\UserRelationBindServiceInterface; |
|||
use Hyperf\Di\Annotation\Inject; |
|||
|
|||
class CommunityController extends BaseController |
|||
{ |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var UserRelationBindServiceInterface |
|||
*/ |
|||
protected $userCommunityService; |
|||
|
|||
public function bind(CommunityBindRequest $request) |
|||
{ |
|||
$data = $request->validated(); |
|||
$res = $this->userCommunityService->bindLimitByUser(UserRelationBind::BIND_TYPE_COMMUNITY, $data['source_id'], $data['user_id'], $data['json_data']); |
|||
return $this->success(['id' => $res->id]); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
<?php |
|||
|
|||
namespace App\JsonRpc; |
|||
|
|||
use App\Commons\Log; |
|||
use App\Constants\ErrorCode; |
|||
use App\Service\SeparateAccountsServiceInterface; |
|||
use Hyperf\DbConnection\Db; |
|||
use Hyperf\RpcServer\Annotation\RpcService; |
|||
use Hyperf\Di\Annotation\Inject; |
|||
use App\Constants\LogLabel; |
|||
|
|||
/** |
|||
* @RpcService(name="OrderService", protocol="jsonrpc-http", server="jsonrpc-http", publishTo="") |
|||
*/ |
|||
class OrderService implements OrderServiceInterface |
|||
{ |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var Log |
|||
*/ |
|||
protected $log; |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var \App\Service\OrderServiceInterface |
|||
*/ |
|||
protected $orderService; |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var SeparateAccountsServiceInterface |
|||
*/ |
|||
protected $separateAccountsService; |
|||
|
|||
public function onlineComplete($global_order_id) |
|||
{ |
|||
Db::beginTransaction(); |
|||
try { |
|||
|
|||
$this->orderService->onlineCompleted($global_order_id); |
|||
$this->separateAccountsService->orderOnlineCompleted($global_order_id); |
|||
|
|||
Db::commit(); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => 0, |
|||
"result" => [], |
|||
"message" => '调用成功' |
|||
]; |
|||
} catch (\Exception $e) { |
|||
|
|||
Db::rollBack(); |
|||
$this->log->event(LogLabel::ONLINE_COMPLETE_LOG, ['exception' => $e->getMessage()]); |
|||
return [ |
|||
"status" => 200, |
|||
"code" =>ErrorCode::SEPARATE_ACCOUNTS_ERROR, |
|||
"result" => [], |
|||
"message" => ErrorCode::getMessage(ErrorCode::SEPARATE_ACCOUNTS_ERROR) |
|||
]; |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 线上订单退款 |
|||
* 申请退款 state = 8 |
|||
* 退款成功 state = 9 |
|||
*/ |
|||
public function onlineRefund($global_order_id){ |
|||
Db::beginTransaction(); |
|||
try{ |
|||
|
|||
return [ |
|||
"status" => 200, |
|||
"code" => 0, |
|||
"result" => $this->orderService->onlineRefund($global_order_id), |
|||
// 'result' => $global_order_id,
|
|||
"message" => '退款成功' |
|||
]; |
|||
} catch (\Exception $e){ |
|||
Db::rollBack(); |
|||
return [ |
|||
"status" => 200, |
|||
"code" => ErrorCode::ORDER_FAILURE, |
|||
"result" => [], |
|||
"message" => $e->getMessage() |
|||
]; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<?php |
|||
|
|||
namespace App\JsonRpc; |
|||
|
|||
interface OrderServiceInterface |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,91 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
namespace App\Model; |
|||
|
|||
/** |
|||
*/ |
|||
class FinancialRecord extends Model |
|||
{ |
|||
/** |
|||
* 当面付商户首单奖励限制的订单金额 |
|||
*/ |
|||
const OFL_FIRST_AWARD_LIMIT_AMOUNT = 3; |
|||
|
|||
/** |
|||
* 虚拟账户 |
|||
*/ |
|||
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; |
|||
|
|||
/** |
|||
* 流水类型,大的分类,<100是奖励分账等收入项 >=100是提现消费等支出项 |
|||
*/ |
|||
const MONEY_TYPE_PLAT_NEW_USER = 1; // 社区服务点新用户奖励(线上订单完成)
|
|||
const MONEY_TYPE_FIRST_ORDER = 2; // 社区服务点新用户线上首单奖励(线上订单完成)
|
|||
const MONEY_TYPE_OL_ORDER = 3; // 社区服务点用户线上订单分账(线上订单完成)
|
|||
const MONEY_TYPE_STORE_PLAT_NEW_USER = 4; // 商户平台新用户奖励
|
|||
const MONEY_TYPE_STORE_FIRST_ORDER = 5; // 商户当日首单奖励
|
|||
const MONEY_TYPE_STORE_OL_ORDER_COMP = 6; // 商户线上订单完成收入
|
|||
const MONEY_TYPE_STORE_OFL_ORDER_COMP = 7; // 商户线下订单完成收入
|
|||
const MONEY_TYPE_USER_OFL_ORDER = 100; // 用户线下支付订单
|
|||
const MONEY_TYPE_USER_OL_ORDER = 101; // 用户线上支付订单
|
|||
|
|||
/** |
|||
* 状态 |
|||
*/ |
|||
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 = []; |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
namespace App\Model; |
|||
|
|||
class ServiceReward extends Model |
|||
{ |
|||
/** |
|||
* 社区服务点 |
|||
*/ |
|||
const TYPE_COMMUNITY = 1; |
|||
|
|||
/** |
|||
* The table associated with the model. |
|||
* |
|||
* @var string |
|||
*/ |
|||
protected $table = 'lanzu_service_reward'; |
|||
/** |
|||
* The attributes that are mass assignable. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $fillable = []; |
|||
/** |
|||
* The attributes that should be cast to native types. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $casts = [ |
|||
'set_reward' => 'array' |
|||
]; |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
namespace App\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 = [ |
|||
'source_id', |
|||
'user_type', |
|||
'balance' |
|||
]; |
|||
/** |
|||
* The attributes that should be cast to native types. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $casts = []; |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
namespace App\Model; |
|||
|
|||
/** |
|||
*/ |
|||
class UserRelationBind extends Model |
|||
{ |
|||
|
|||
/** |
|||
* 社区服务点类型 |
|||
*/ |
|||
const BIND_TYPE_COMMUNITY = 1; |
|||
|
|||
/** |
|||
* The table associated with the model. |
|||
* |
|||
* @var string |
|||
*/ |
|||
protected $table = 'lanzu_user_relation_bind'; |
|||
/** |
|||
* The attributes that are mass assignable. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $fillable = ['bind_type', 'source_id', 'user_id', 'json_data']; |
|||
/** |
|||
* The attributes that should be cast to native types. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $casts = []; |
|||
|
|||
public function setJsonDataAttribute($value) |
|||
{ |
|||
$this->attributes['json_data'] = $value ? json_encode(json_decode($value, true)) : ''; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Request; |
|||
|
|||
use Hyperf\Validation\Request\FormRequest; |
|||
|
|||
class CommunityBindRequest extends FormRequest |
|||
{ |
|||
/** |
|||
* Determine if the user is authorized to make this request. |
|||
*/ |
|||
public function authorize(): bool |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* Get the validation rules that apply to the request. |
|||
*/ |
|||
public function rules(): array |
|||
{ |
|||
return [ |
|||
'source_id' => 'required|nonempty', |
|||
'user_id' => 'required|nonempty|exists_enable:ims_cjdc_user,id', |
|||
'json_data' => 'json', |
|||
]; |
|||
} |
|||
|
|||
public function messages(): array |
|||
{ |
|||
return [ |
|||
'*.nonempty' => ':attribute参数异常', |
|||
'user_id.exists_enable' => '用户不存在', |
|||
]; |
|||
} |
|||
|
|||
public function attributes(): array |
|||
{ |
|||
return [ |
|||
|
|||
]; |
|||
} |
|||
} |
|||
@ -0,0 +1,182 @@ |
|||
<?php |
|||
|
|||
namespace App\Service; |
|||
|
|||
use App\Model\FinancialRecord; |
|||
use App\Model\Store; |
|||
use App\Model\UserBalance; |
|||
use App\Model\Users; |
|||
|
|||
class FinancialRecordService implements FinancialRecordServiceInterface |
|||
{ |
|||
|
|||
|
|||
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(); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function communityAwardByPlatNewUser($user_id, $source_id, $money, $user_type=2, $source_type=1, $money_type=1, $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' => $user_id |
|||
]); |
|||
$balance->balance = bcadd($balance->balance, $money); |
|||
$balance->save(); |
|||
} |
|||
|
|||
/** |
|||
* @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' => $user_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' => $user_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 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, |
|||
[ |
|||
'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 userByOFLOrderPaid($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=100, $desc='用户下单(线下)', $comment='用户下单') |
|||
{ |
|||
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); |
|||
} |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function userByOLOrderPaid($user_id, $source_id, $money, $user_type=1, $source_type=1, $money_type=101, $desc='用户下单(线上)', $comment='用户下单') |
|||
{ |
|||
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment); |
|||
} |
|||
|
|||
/** |
|||
* @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); |
|||
} |
|||
} |
|||
@ -0,0 +1,146 @@ |
|||
<?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=2, $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=3, $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=''); |
|||
|
|||
/** |
|||
* 商户线下用户支付新用户奖励 |
|||
* @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=''); |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
|
|||
namespace App\Service; |
|||
|
|||
use App\Model\OrderMain; |
|||
use EasyWeChat\Factory; |
|||
use Hyperf\DbConnection\Db; |
|||
use App\Constants\ErrorCode; |
|||
|
|||
class PayRefundService implements PayRefundServiceInterface |
|||
{ |
|||
/** |
|||
* 微信支付退款 |
|||
*/ |
|||
public function wxPayRefund($global_order_id) |
|||
{ |
|||
$config = config('wxpay'); |
|||
$app = Factory::payment($config); |
|||
$app['guzzle_handler'] = CoroutineHandler::class; |
|||
|
|||
$result = [ |
|||
'status' => 0, |
|||
'msg' => '退款成功' |
|||
]; |
|||
|
|||
// 查询订单
|
|||
$orderMain = OrderMain::query() |
|||
->select('id','code','order_num','money','state') |
|||
->where('global_order_id',$global_order_id) |
|||
->where('pay_type',OrderMain::ORDER_PAY_WX) |
|||
->where(Db::raw('refund_time is null')) |
|||
->first(); |
|||
if(empty($orderMain)){ |
|||
return ['status'=>1, 'msg'=>'订单不存在或已退款']; |
|||
} |
|||
$optional = []; |
|||
$result = $app->refund->byOutTradeNumber( |
|||
$orderMain->code, |
|||
$orderMain->code, |
|||
$orderMain->money * 100, |
|||
$orderMain->money * 100, |
|||
$optional |
|||
); |
|||
return $result; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<?php |
|||
|
|||
namespace App\Service; |
|||
|
|||
interface PayRefundServiceInterface |
|||
{ |
|||
public function wxPayRefund($global_order_id); |
|||
} |
|||
@ -0,0 +1,291 @@ |
|||
<?php |
|||
|
|||
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 App\Model\Users; |
|||
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; |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function orderOnlinePaid($global_order_id) |
|||
{ |
|||
// 线上订单支付完成
|
|||
// 订单
|
|||
$orderMain = OrderMain::query() |
|||
->where(['global_order_id' => $global_order_id]) |
|||
->first(); |
|||
|
|||
if (empty($orderMain)) { |
|||
return false; |
|||
} |
|||
|
|||
// =======用户支付流水 / Start=======
|
|||
$this->financialRecordService->userByOLOrderPaid($orderMain->user_id, $global_order_id, $orderMain->money); |
|||
// =======用户支付流水 / End=======
|
|||
} |
|||
|
|||
/** |
|||
* @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 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, $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, $global_order_id, $award['new_user_reward']); |
|||
$this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder($communityBind->source_id, $global_order_id, $award['first_reward']); |
|||
} |
|||
|
|||
// 账单分成
|
|||
$money = bcmul($orderMain->money, bcdiv($award['flow_reward'], 100, 6), 2); |
|||
$this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $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) |
|||
{ |
|||
// 线下订单支付完成
|
|||
// 订单
|
|||
$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, $global_order_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, $global_order_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, $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 |
|||
) |
|||
) { |
|||
|
|||
$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, $global_order_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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
<?php |
|||
|
|||
namespace App\Service; |
|||
|
|||
use App\Model\UserRelationBind; |
|||
|
|||
class UserCommunityBindService implements UserRelationBindServiceInterface |
|||
{ |
|||
|
|||
/** |
|||
* @inheritDoc |
|||
*/ |
|||
public function bindLimitByUser($bind_type, $source_id, $user_id, $extra_data) |
|||
{ |
|||
return UserRelationBind::query()->updateOrCreate( |
|||
['bind_type' => $bind_type, 'user_id' => $user_id], |
|||
['source_id' => $source_id, 'json_data' => $extra_data] |
|||
); |
|||
} |
|||
|
|||
public function bindLimitBySource($bind_type, $source_id, $user_id, $extra_data) |
|||
{ |
|||
// TODO: Implement bindLimitBySource() method.
|
|||
} |
|||
|
|||
public function bind($bind_type, $source_id, $user_id, $extra_data) |
|||
{ |
|||
// TODO: Implement bind() method.
|
|||
} |
|||
|
|||
public function isBinded($bind_type, $source_id, $user_id) |
|||
{ |
|||
// TODO: Implement isBinded() method.
|
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
<?php |
|||
|
|||
namespace App\Service; |
|||
|
|||
interface UserRelationBindServiceInterface |
|||
{ |
|||
/** |
|||
* 绑定 |
|||
* 依据用户绑定一个关系,即每次都是新的绑定关系,原来的绑定关系解除(user_id不变,更新其他) |
|||
* @param $bind_type |
|||
* @param $source_id |
|||
* @param $user_id |
|||
* @param $extra_data |
|||
* @return mixed |
|||
*/ |
|||
public function bindLimitByUser($bind_type, $source_id, $user_id, $extra_data); |
|||
|
|||
/** |
|||
* 绑定 |
|||
* 依据绑定人(根据bind_type确定)绑定一个关系,即每次都是新的绑定关系,原来的绑定关系解除(source_id不变,更新其他) |
|||
* @param $bind_type |
|||
* @param $source_id |
|||
* @param $user_id |
|||
* @param $extra_data |
|||
* @return mixed |
|||
*/ |
|||
public function bindLimitBySource($bind_type, $source_id, $user_id, $extra_data); |
|||
|
|||
/** |
|||
* 绑定 |
|||
* 始终绑定一个新的关系,如果这个关系(source_id=》user_id)存在则更新其他数据 |
|||
* @param $bind_type |
|||
* @param $source_id |
|||
* @param $user_id |
|||
* @param $extra_data |
|||
* @return mixed |
|||
*/ |
|||
public function bind($bind_type, $source_id, $user_id, $extra_data); |
|||
|
|||
/** |
|||
* 是否已经存在绑定关系 |
|||
* @param $bind_type |
|||
* @param $source_id |
|||
* @param $user_id |
|||
* @return mixed |
|||
*/ |
|||
public function isBinded($bind_type, $source_id, $user_id); |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue