shop-php/app/common/dao/store/consumption/CommissionDao.php
2024-02-07 16:19:16 +08:00

257 lines
11 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\dao\store\consumption;
use app\common\dao\system\financial\FinancialDao;
use app\common\model\store\consumption\StoreConsumption;
use app\common\model\store\consumption\StoreConsumptionUser;
use app\common\model\store\order\StoreOrder;
use app\common\model\system\merchant\FinancialRecord;
use app\common\model\system\merchant\Merchant;
use app\common\model\user\User;
use app\common\model\user\UserBill;
use app\common\repositories\system\merchant\MerchantRepository;
use crmeb\utils\Curl;
use think\facade\Log;
class CommissionDao
{
/**
* 活动首单商户佣金 (支付成功后调用)
* @param $order
* @param $financeDao
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function firstOrderCommission($order, $financeDao)
{
$commission = bcmul($order['pay_price'], 0.01, 2);
if ($commission > 0 && $order['order_type'] == 1) {
// 订单为自提且佣金大于0
$financeDao->user = $order->user;
$financeDao->order = $order;
$financeDao->platformOut($commission, 'commission_to_store', $order['mer_id']);
app()->make(MerchantRepository::class)->addLockMoney($order['mer_id'], 'order', $order['order_id'], $commission);
}
$consumption = StoreConsumption::where('status', 1)->where('type', StoreConsumption::TYPE_FIRST_ORDER_COMMISSION)->find();
if (empty($consumption)) {
return $financeDao;
}
$storeConsumptionDao = new StoreConsumptionUserDao();
$isFirstOrder = $storeConsumptionDao->isFirstOrder($order['uid'], $consumption['start_time'], $consumption['end_time']);
if (!$isFirstOrder) {
return $financeDao;
}
// 给镇合伙人、村合伙人、小组服务团队、店铺分佣,仅直推
$promotionCode = User::where('uid', $order['uid'])->value('promotion_code');
if (!empty($promotionCode)) {
$merchantId = substr($promotionCode, strpos($promotionCode, 'mer_') + 4);
if (strpos($promotionCode, 'mer_') !== false && $merchantId) {
$userId = Merchant::where('mer_id', $merchantId)->value('uid');
$user = User::where('uid', $userId)->find();
$commission = bcmul($order['pay_price'], 0.03, 2);
$financeDao->user = $user;
$financeDao->order = $order;
$financeDao->platformOut($commission, 'commission_to_promoter', $merchantId);
app()->make(MerchantRepository::class)->addLockMoney($merchantId, 'order', $order['order_id'], $commission);
$redPack = bcmul($order['pay_price'], $consumption['config']['red_pack_rate'], 2);
if ($redPack > 0) {
try {
(new StoreConsumptionUserDao())->send($consumption, $consumption['config']['red_pack_rate'], $user['uid'], $order['order_id'], $order['pay_price'], StoreConsumptionUser::STATUS_UNUSED, StoreConsumptionUser::TYPE_TWO);
} catch (\Exception $e) {
Log::error($e->getMessage());
}
}
} else {
$this->sendCommission($order, $promotionCode);
}
}
return $financeDao;
}
/**
* 活动首单推广人佣金(供应商平台异步回调)
* @param $data
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function firstOrderCommissionCallback($data)
{
$consumption = StoreConsumption::where('status', 1)->where('type', StoreConsumption::TYPE_FIRST_ORDER_COMMISSION)->find();
if (empty($consumption)) {
return [];
}
$users = $this->getUsers($data['user']);
$order = StoreOrder::where('order_id', $data['order_id'])->find();
if (empty($order)) {
return [];
}
$result = [];
$financeDao = new FinancialDao();
foreach ($users as $user) {
$commission = bcdiv($user['user_profit'], 100, 2);
if ($commission > 0) {
$financeDao->user = $user;
$financeDao->order = $order;
$financialType = $user['type'] == 4 ? 'commission_to_courier' : 'commission_to_promoter';
$financeDao->platformOut($commission, $financialType);
$result[] = $user;
}
$redPack = bcmul($order['pay_price'], $consumption['config']['red_pack_rate'], 2);
if ($redPack > 0) {
try {
(new StoreConsumptionUserDao())->send($consumption, $consumption['config']['red_pack_rate'], $user['uid'], $order['order_id'], $order['pay_price'], StoreConsumptionUser::STATUS_UNUSED, StoreConsumptionUser::TYPE_TWO);
} catch (\Exception $e) {
Log::error($e->getMessage());
}
}
}
$financeDao->save();
return $result;
}
/**
* 给镇合伙人或推广人发放佣金(支付完成后调用,推广人仅首单奖励)
* 请求发送给供应商平台后异步回调
* 暂时取消镇合伙人佣金
* @param $order
* @param $promotionCode
* @param int $type 类型1=>小组2=>村合伙人3=>镇合伙人4=>配送员
* @return void
*/
public function sendCommission($order, $promotionCode, $type = 1)
{
$curl = new Curl();
$timestamp = time();
$json = ['timestamp' => $timestamp, 'data' => ['order_id' => $order['order_id'], 'order_sn' => $order['order_sn'], 'order_money' => bcmul($order['pay_price'], 100), 'promotion_code' => $promotionCode]];
if ($type == 3) {
$json['data']['street_code'] = $promotionCode;
} elseif ($type == 4) {
$json['data']['courier_phone'] = $promotionCode;
} else {
$json['data']['promotion_code'] = $promotionCode;
}
$aes = new \AES();
$iv = $aes->buildIv($timestamp);
$encrypt = $aes->encrypt($json, $iv);
$api = in_array($type, [1, 2]) ? 'user_first_order_share_profit' : 'user_order_share_profit';
$url = env('task.new_worker_host_url') . '/api/shop_call/' . $api;
$result = $curl->post($url, ['timestamp' => $timestamp, 'data' => $encrypt]);
$result = json_decode($result, true);
Log::info('供销佣金:' . var_export($result, true));
}
/**
* 订单退款,店铺退佣金
* @param $refundOrder
* @return void
*/
public function refundByOrder($refundOrder)
{
// 是否已经退过佣金
$refunded = FinancialRecord::where('order_id', $refundOrder->order['order_id'])
->whereIn('financial_type', ['commission_to_store_refund', 'commission_to_courier_refund', 'commission_to_promoter_refund'])
->count();
if ($refunded > 0) {
return;
}
// 退佣金和红包、保证金
$financeRecord = FinancialRecord::where('order_id', $refundOrder->order['order_id'])
->whereIn('financial_type', ['commission_to_store', 'commission_to_courier', 'commission_to_promoter'])
->field('user_id uid,user_info nickname,number,mer_id,financial_type')->select()->toArray();
if (empty($financeRecord)) {
return;
}
$userIds = [];
$financeDao = new FinancialDao();
foreach ($financeRecord as $item) {
$userIds[] = $item['uid'];
$financeDao->user = $item;
$financeDao->order = $refundOrder->order;
$financeDao->platformIn($item['number'], $item['financial_type'] . '_refund', $item['mer_id']);
if ($item['mer_id'] > 0) {
app()->make(MerchantRepository::class)->subLockMoney($item['mer_id'], 'order', $refundOrder->order['order_id'], $item['number']);
}
}
$financeDao->save();
// 服务团队退红包
$redPacks = UserBill::whereIn('uid', $userIds)->where('extra->order_id',$refundOrder->order['order_id'])->select()->toArray();
foreach ($redPacks as $redPack) {
(new StoreConsumptionUserDao())->refundByCommission($redPack['uid'], $refundOrder->order['order_id'], $redPack['number']);
}
$promotionCode = User::where('uid', $refundOrder['uid'])->value('promotion_code');
if ($promotionCode && strpos($promotionCode, 'mer_') === false){
$curl = new Curl();
$aes = new \AES();
$timestamp = time();
$json = ['timestamp' => $timestamp, 'data' => ['order_sn' => $refundOrder->order['order_sn']]];
$iv = $aes->buildIv($timestamp);
$encrypt = $aes->encrypt($json, $iv);
$url = env('task.new_worker_host_url') . '/api/shop_call/handleRefund';
$result = $curl->post($url, ['timestamp' => $timestamp, 'data' => $encrypt]);
$result = json_decode($result, true);
Log::error('发起佣金退款:' . var_export($result, true));
}
}
/**
* @deprecated 暂时弃用,后续可能会用
* 供销平台退佣金回调
* @param $data
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function refundByCallback($data)
{
$result = [];
$users = $this->getUsers($data['user']);
$order = StoreOrder::where('order_id', $data['order_id'])->find();
if (empty($order) || empty($users)) {
return [];
}
$financeDao = new FinancialDao();
foreach ($users as $user) {
$commission = bcdiv($user['user_profit'], 100, 2);
if ($commission > 0) {
$financeDao->user = $user;
$financeDao->order = $order;
$financialType = ($user['type'] == 3 ? 'order_commission' : 'first_order_commission') . '_refund';
$financeDao->platformIn($commission, $financialType);
$result[] = $user;
}
$redPack = bcmul($order['pay_price'], 0.07, 2);
if ($redPack > 0) {
try {
(new StoreConsumptionUserDao())->refundByCommission($user['uid'], $order->order_id, $redPack);
} catch (\Exception $e) {
Log::error($e->getMessage());
}
}
}
$financeDao->save();
return $result;
}
public function getUsers($info)
{
$info = reset_index($info, 'account');
$users = User::whereIn('account', array_keys($info))->field('uid,account,nickname')->select()->toArray();
foreach ($users as &$user) {
if (isset($info[$user['account']])) {
$user = array_merge($info[$user['account']], $user);
}
}
return $users;
}
}