<?php
declare(strict_types=1);

namespace app\services\user;

use app\services\BaseServices;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

/**
 * 会员与分销奖励服务
 * Class UserRewardService
 */
class UserRewardService extends BaseServices
{
    // 报单产品ID
    const PRODUCT_REPORT_ID = 1;

    // 奖励类型常量
    const REWARD_TYPE_DIRECT_CASH = 'direct_cash';           // 直接分享现金奖励
    const REWARD_TYPE_DIRECT_COUPON = 'direct_coupon';      // 直接分享消费券奖励
    const REWARD_TYPE_SERVICE_CENTER_FEE = 'service_center_fee'; // 服务中心服务费
    const REWARD_TYPE_SERVICE_POINT_FEE = 'service_point_fee';   // 服务点服务费(新增)
    const REWARD_TYPE_SERVICE_POINT_PEER = 'service_point_peer'; // 服务点平级奖励
    const REWARD_TYPE_REPURCHASE_DIRECT = 'repurchase_direct';     // 复购直接推荐人
    const REWARD_TYPE_REPURCHASE_CENTER = 'repurchase_center';     // 复购服务中心
    const REWARD_TYPE_REPURCHASE_POINT = 'repurchase_point';       // 复购服务点

    /**
     * 处理订单奖励(收货后调用)
     * @param array $order 订单信息
     * @param int $uid 收货用户UID
     * @return bool
     */
    public function handleOrderReward(array $order, int $uid): bool
    {
        // 检查是否已发放奖励
        if ($order['reward_status'] == 1) {
            return true;
        }

        // 获取订单商品信息
        $cartInfo = $this->getOrderCartInfo($order['id']);
        if (!$cartInfo) {
            return true;
        }

        // 判断是否为报单产品(商品ID=1)
        $isReportProduct = $this->checkIsReportProduct($cartInfo);

        try {
            $this->transaction(function () use ($order, $uid, $isReportProduct, $cartInfo) {
                if ($isReportProduct) {
                    // 报单产品:发放直接分享奖励
                    $this->handleReportProductReward($order, $uid);
                    // 发放服务中心服务费(每笔订单100元)
                    $this->handleServiceCenterFee($order, $uid);
                    // ===== 新增:发放服务点服务费(每笔订单100元) =====
                    $this->handleServicePointFee($order, $uid);
                    // 发放服务点平级奖励(3%)
                    $this->handleServicePointPeerReward($order, $uid, $cartInfo);
                } else {
                    // 复购产品:发放复购奖励
                    $this->handleRepurchaseReward($order, $uid, $cartInfo);
                    // 复购也发放服务中心服务费
                    $this->handleServiceCenterFee($order, $uid);
                    // 复购也发放服务点平级奖励
                    $this->handleServicePointPeerReward($order, $uid, $cartInfo);
                }

                // 标记订单奖励已发放
                app()->make(StoreOrderServices::class)->update($order['id'], ['reward_status' => 1]);
            });
            return true;
        } catch (\Exception $e) {
            Log::error('订单奖励发放失败:订单ID-' . $order['id'] . ',错误:' . $e->getMessage());
            return false;
        }
    }

    /**
     * 处理报单产品奖励
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleReportProductReward(array $order, int $uid): void
    {
        // 获取上级推荐人
        $spreadUid = $this->getSpreadUid($uid);
        if (!$spreadUid) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $spreadUser = $userService->getUserInfo($spreadUid);
        if (!$spreadUser) {
            return;
        }

        // 奖励金额配置
        $cashReward = 650;      // 现金奖励650元
        $couponReward = 650;    // 消费券650积分

        // 1. 发放现金奖励到推荐人的佣金账户
        $currentBrokerage = $spreadUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$cashReward, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'direct_cash',
            $spreadUid,
            [
                'nickname' => $userService->value($uid, 'nickname'),
                'pay_price' => $order['pay_price'],
                'number' => $cashReward,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        // 更新用户佣金余额
        $userService->update($spreadUid, ['brokerage_price' => $newBrokerage], 'uid');

        // 2. 发放消费券(积分)到推荐人
        $currentIntegral = $spreadUser['integral'];
        $newIntegral = $currentIntegral + $couponReward;

        /** @var UserBillServices $billService */
        $billService = app()->make(UserBillServices::class);
        $billService->income(
            'direct_reward_coupon',
            $spreadUid,
            [
                'nickname' => $userService->value($uid, 'nickname'),
                'pay_price' => $order['pay_price'],
                'number' => $couponReward,
            ],
            $newIntegral,
            $order['id']
        );

        // 更新用户积分
        $userService->update($spreadUid, ['integral' => $newIntegral], 'uid');

        $userInfo = $userService->getUserInfo($uid);
        $userService->update($userInfo['uid'], ['first_order' => 1]);

        // 发送消息通知
        event('CustomNoticeListener', [$spreadUid, [
            'uid' => $spreadUid,
            'cash' => $cashReward,
            'coupon' => $couponReward,
            'time' => date('Y-m-d H:i:s')
        ], 'direct_reward']);
    }

    /**
     * 处理服务中心服务费(每笔订单100元)
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServiceCenterFee(array $order, int $uid): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务中心
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_center_uid'] == 0) {
            return;
        }

        $centerUid = $userInfo['service_center_uid'];
        $centerUser = $userService->getUserInfo($centerUid);
        if (!$centerUser || $centerUser['is_service_center'] != 1) {
            return;
        }

        $feeAmount = 100; // 每笔订单100元服务费

        $currentBrokerage = $centerUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$feeAmount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'get_center_brokerage',
            $centerUid,
            [
                'nickname' => $userInfo['nickname'],
                'order_id' => $order['order_id'],
                'number' => $feeAmount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        $userService->update($centerUid, ['brokerage_price' => $newBrokerage], 'uid');
    }

    // ===== 新增:处理服务点服务费(每笔订单100元) =====
    /**
     * 处理服务点服务费(每笔订单100元)
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServicePointFee(array $order, int $uid): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务点
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_point_uid'] == 0) {
            return;
        }

        $pointUid = $userInfo['service_point_uid'];
        $pointUser = $userService->getUserInfo($pointUid);
        if (!$pointUser || $pointUser['is_service_point'] != 1) {
            return;
        }

        $feeAmount = 100; // 每笔订单100元服务费

        $currentBrokerage = $pointUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$feeAmount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'get_point_brokerage', // 类型标识
            $pointUid,
            [
                'nickname' => $userInfo['nickname'],
                'order_id' => $order['order_id'],
                'number' => $feeAmount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        $userService->update($pointUid, ['brokerage_price' => $newBrokerage], 'uid');
    }
    // ===== 新增结束 =====

    /**
     * 处理服务点平级奖励(3%+3%)
     * @param array $order
     * @param int $uid
     * @param array $cartInfo
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServicePointPeerReward(array $order, int $uid, array $cartInfo): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务点
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_point_uid'] == 0) {
            return;
        }

        $pointUid = $userInfo['service_point_uid'];
        $pointUser = $userService->getUserInfo($pointUid);
        if (!$pointUser || $pointUser['is_service_point'] != 1) {
            return;
        }

        // 检查是否存在父级服务点(平级条件)
        $parentPointUid = $pointUser['parent_service_point_uid'];
        if ($parentPointUid == 0) {
            return; // 没有父级服务点,不发放平级奖励
        }

        $parentPointUser = $userService->getUserInfo($parentPointUid);
        if (!$parentPointUser || $parentPointUser['is_service_point'] != 1) {
            return;
        }

        // 计算奖励金额:订单金额的3%
        $orderAmount = $order['pay_price'];
        $rewardAmount = bcmul((string)$orderAmount, '0.03', 2);
        if ($rewardAmount <= 0) {
            return;
        }

        // 发放给所属服务点3%
        $this->addBrokerageToUser($pointUid, (float)$rewardAmount, $order['id'], 'point_peer_self', [
            'nickname' => $userInfo['nickname'],
            'order_id' => $order['order_id'],
            'number' => $rewardAmount,
            'level' => 'self'
        ]);

        // 发放给父级服务点3%
        $this->addBrokerageToUser($parentPointUid, (float)$rewardAmount, $order['id'], 'point_peer_parent', [
            'nickname' => $userInfo['nickname'],
            'order_id' => $order['order_id'],
            'number' => $rewardAmount,
            'level' => 'parent'
        ]);
    }

    /**
     * 处理复购奖励
     * @param array $order
     * @param int $uid
     * @param array $cartInfo
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleRepurchaseReward(array $order, int $uid, array $cartInfo): void
    {
        $orderAmount = $order['pay_price'];

        // 1. 直接推荐人获得30%
        $directReward = bcmul((string)$orderAmount, '0.30', 2);
        $spreadUid = $this->getSpreadUid($uid);
        if ($spreadUid && $directReward > 0) {
            $this->addBrokerageToUser($spreadUid, (float)$directReward, $order['id'], 'repurchase_direct', [
                'nickname' => app()->make(UserServices::class)->value($uid, 'nickname'),
                'order_id' => $order['order_id'],
                'number' => $directReward
            ]);
        }

        // 2. 服务中心获得5%
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);
        if ($userInfo && $userInfo['service_center_uid'] > 0) {
            $centerReward = bcmul((string)$orderAmount, '0.05', 2);
            if ($centerReward > 0) {
                $this->addBrokerageToUser($userInfo['service_center_uid'], (float)$centerReward, $order['id'], 'repurchase_center', [
                    'nickname' => $userInfo['nickname'],
                    'order_id' => $order['order_id'],
                    'number' => $centerReward
                ]);
            }
        }

        // 3. 服务点获得5%
        if ($userInfo && $userInfo['service_point_uid'] > 0) {
            $pointReward = bcmul((string)$orderAmount, '0.05', 2);
            if ($pointReward > 0) {
                $this->addBrokerageToUser($userInfo['service_point_uid'], (float)$pointReward, $order['id'], 'repurchase_point', [
                    'nickname' => $userInfo['nickname'],
                    'order_id' => $order['order_id'],
                    'number' => $pointReward
                ]);
            }
        }
    }

    /**
     * 添加佣金到用户
     * @param int $targetUid
     * @param float $amount
     * @param int $orderId
     * @param string $type
     * @param array $extra
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function addBrokerageToUser(int $targetUid, float $amount, int $orderId, string $type, array $extra = []): void
    {
        if ($amount <= 0 || $targetUid <= 0) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $targetUser = $userService->getUserInfo($targetUid);
        if (!$targetUser) {
            return;
        }

        $currentBrokerage = $targetUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$amount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);

        $titleMap = [
            'point_peer_self' => '服务点平级奖励(本级)',
            'point_peer_parent' => '服务点平级奖励(上级)',
            'repurchase_direct' => '复购直接推荐奖励',
            'repurchase_center' => '复购服务中心奖励',
            'repurchase_point' => '复购服务点奖励',
            'center_fee' => '服务中心服务费',
            'point_fee' => '服务点服务费' // 新增
        ];

        $brokerageService->income(
            $type,
            $targetUid,
            [
                'number' => $amount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400,
                'title' => $titleMap[$type] ?? '佣金奖励',
                'order_id' => $extra['order_id'] ?? '',
                'nickname' => $extra['nickname'] ?? ''
            ],
            $newBrokerage,
            $orderId
        );

        $userService->update($targetUid, ['brokerage_price' => $newBrokerage], 'uid');
    }

    /**
     * 检查订单是否为报单产品
     * @param array $cartInfo
     * @return bool
     */
    protected function checkIsReportProduct(array $cartInfo): bool
    {
        foreach ($cartInfo as $cart) {
            $cartData = is_string($cart['cart_info']) ? json_decode($cart['cart_info'], true) : $cart['cart_info'];
            if (isset($cartData['product_id']) && $cartData['product_id'] == self::PRODUCT_REPORT_ID) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取订单商品信息
     * @param int $orderId
     * @return array
     */
    protected function getOrderCartInfo(int $orderId): array
    {
        /** @var StoreOrderCartInfoServices $cartService */
        $cartService = app()->make(StoreOrderCartInfoServices::class);
        return $cartService->getCartColunm(['oid' => $orderId], 'cart_info,unique', 'id');
    }

    /**
     * 获取上级推荐人UID
     * @param int $uid
     * @return int
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function getSpreadUid(int $uid): int
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);
        return $userInfo['spread_uid'] ?? 0;
    }

    /**
     * 检查并升级服务点
     * @param int $uid 用户UID
     * @param array $order 订单信息
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function checkAndUpgradeToServicePoint(int $uid, array $order): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);

        // 已经是服务点则跳过
        if ($userInfo['is_service_point'] == 1) {
            return;
        }

        $isUpgrade = false;
        $triggerType = '';
        $recommendCount = 0;
        $purchaseCount = 0;
        $upgradeReason = '';
        $servicePointUid = 0;
        $parentPointUid = 0;

        if($userInfo['spread_uid'] != 0){
            // 条件1:直接推荐10名会员(推荐的下级中完成报单的人数)
            $spreadInfo = $userService->getUserInfo($userInfo['spread_uid']);
            $recommendCount = $this->getDirectRecommendReportCount($spreadInfo['uid']);
            if ($recommendCount >= 10) {
                // 获取父级服务点(当前用户的所属服务点)
                $parentPointUid = $spreadInfo['service_point_uid'] ?? 0;
                $isUpgrade = true;
                $servicePointUid = $spreadInfo['uid'];
                $triggerType = 'auto_recommend';
                $upgradeReason = '直接推荐10名会员';
            }
        }


        // 条件2:一次性购买10单会酒(商品ID=1的订单累计收货数量>=10)
        if (!$isUpgrade) {
            $purchaseCount = $this->getUserReportOrderCount($uid);
            if ($purchaseCount >= 10) {
                // 获取父级服务点(当前用户的所属服务点)
                $parentPointUid = $userInfo['service_point_uid'] ?? 0;
                $isUpgrade = true;
                $servicePointUid = $uid;
                $triggerType = 'auto_purchase';
                $upgradeReason = '购买10单会酒';
            }
        }

        if ($isUpgrade) {
            // 升级为服务点
            $updateData = [
                'is_service_point' => 1,
                'service_point_uid' => $servicePointUid,
                'service_point_time' => time(),
                'parent_service_point_uid' => $parentPointUid
            ];
            $userService->update($uid, $updateData, 'uid');

            // ========== 新增:添加升级记录 ==========
            try {
                /** @var UserUpgradeLogServices $upgradeLogService */
                $upgradeLogService = app()->make(UserUpgradeLogServices::class);
                $upgradeLogService->addUpgradeLog($uid, 'service_point', $triggerType, [
                    'recommend_count' => $recommendCount,
                    'purchase_count' => $purchaseCount,
                    'parent_service_point_uid' => $parentPointUid,
                    'remark' => $upgradeReason
                ]);
            } catch (\Exception $e) {
                Log::error('添加服务点升级记录失败:' . $e->getMessage());
            }
            // ========== 新增结束 ==========

            // 记录升级日志
            Log::info("用户{$uid}升级为服务点,原因:{$upgradeReason},父级服务点:{$parentPointUid}");

            // 发送升级通知
            event('CustomNoticeListener', [$uid, [
                'uid' => $uid,
                'reason' => $upgradeReason,
                'time' => date('Y-m-d H:i:s')
            ], 'upgrade_service_point']);
        }
    }

    /**
     * 获取用户直接推荐的完成报单人数
     * @param int $uid
     * @return int
     */
    protected function getDirectRecommendReportCount(int $uid): int
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取所有下级
        $subUsers = $userService->getColumn(['spread_uid' => $uid], 'uid');
        if (empty($subUsers)) {
            return 0;
        }

        // 统计下级中完成报单订单的人数
        /** @var StoreOrderServices $orderService */
        $orderService = app()->make(StoreOrderServices::class);
        $count = 0;
        foreach ($subUsers as $subUid) {
            // 查询该下级是否有已完成收货的报单订单
            $hasReportOrder = $orderService->count([
                'uid' => $subUid,
                'paid' => 1,
                'status' => 2,
                'reward_status' => 1
            ]);
            if ($hasReportOrder > 0) {
                $count++;
            }
        }

        return $count;
    }

    /**
     * 获取用户报单产品累计收货数量
     * @param int $uid
     * @return int
     */
    protected function getUserReportOrderCount(int $uid): int
    {
        /** @var StoreOrderServices $orderService */
        $orderService = app()->make(StoreOrderServices::class);

        // 获取用户所有已完成收货的订单
        $orders = $orderService->getList([
            'uid' => $uid,
            'paid' => 1,
            'status' => 2,
            'reward_status' => 1
        ], ['id']);

        if (empty($orders)) {
            return 0;
        }

        $totalCount = 0;
        $orderIds = array_column($orders, 'id');

        /** @var StoreOrderCartInfoServices $cartService */
        $cartService = app()->make(StoreOrderCartInfoServices::class);
        foreach ($orderIds as $orderId) {
            $cartList = $cartService->getCartColunm(['oid' => $orderId], 'cart_info', 'id');
            foreach ($cartList as $cart) {
                $cartData = is_string($cart) ? json_decode($cart, true) : $cart;
                if (isset($cartData['product_id']) && $cartData['product_id'] == self::PRODUCT_REPORT_ID) {
                    $totalCount += $cartData['cart_num'] ?? 1;
                }
            }
        }

        return $totalCount;
    }

    /**
     * 设置用户的所属服务点和服务中心(收货时调用)
     * @param int $uid 消费者UID
     * @param int $spreadUid 推荐人UID
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function setUserServiceRelation(int $uid, int $spreadUid): void
    {
        if ($spreadUid <= 0) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $spreadUser = $userService->getUserInfo($spreadUid);
        if (!$spreadUser) {
            return;
        }

        $updateData = [];

        // 设置所属服务点
        if ($spreadUser['is_service_point'] == 1 && $spreadUser['service_point_uid'] == 0) {
            $updateData['service_point_uid'] = $spreadUid;
        } elseif ($spreadUser['service_point_uid'] > 0) {
            $updateData['service_point_uid'] = $spreadUser['service_point_uid'];
        }

        // 设置所属服务中心
        if ($spreadUser['is_service_center'] == 1 && $spreadUser['service_center_uid'] == 0) {
            $updateData['service_center_uid'] = $spreadUid;
        } elseif ($spreadUser['service_center_uid'] > 0) {
            $updateData['service_center_uid'] = $spreadUser['service_center_uid'];
        }

        if (!empty($updateData)) {
            $userService->update($uid, $updateData, 'uid');
        }
    }
}<?php
declare(strict_types=1);

namespace app\services\user;

use app\services\BaseServices;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

/**
 * 会员与分销奖励服务
 * Class UserRewardService
 */
class UserRewardService extends BaseServices
{
    // 报单产品ID
    const PRODUCT_REPORT_ID = 1;

    // 奖励类型常量
    const REWARD_TYPE_DIRECT_CASH = 'direct_cash';           // 直接分享现金奖励
    const REWARD_TYPE_DIRECT_COUPON = 'direct_coupon';      // 直接分享消费券奖励
    const REWARD_TYPE_SERVICE_CENTER_FEE = 'service_center_fee'; // 服务中心服务费
    const REWARD_TYPE_SERVICE_POINT_FEE = 'service_point_fee';   // 服务点服务费(新增)
    const REWARD_TYPE_SERVICE_POINT_PEER = 'service_point_peer'; // 服务点平级奖励
    const REWARD_TYPE_REPURCHASE_DIRECT = 'repurchase_direct';     // 复购直接推荐人
    const REWARD_TYPE_REPURCHASE_CENTER = 'repurchase_center';     // 复购服务中心
    const REWARD_TYPE_REPURCHASE_POINT = 'repurchase_point';       // 复购服务点

    /**
     * 处理订单奖励(收货后调用)
     * @param array $order 订单信息
     * @param int $uid 收货用户UID
     * @return bool
     */
    public function handleOrderReward(array $order, int $uid): bool
    {
        // 检查是否已发放奖励
        if ($order['reward_status'] == 1) {
            return true;
        }

        // 获取订单商品信息
        $cartInfo = $this->getOrderCartInfo($order['id']);
        if (!$cartInfo) {
            return true;
        }

        // 判断是否为报单产品(商品ID=1)
        $isReportProduct = $this->checkIsReportProduct($cartInfo);

        try {
            $this->transaction(function () use ($order, $uid, $isReportProduct, $cartInfo) {
                if ($isReportProduct) {
                    // 报单产品:发放直接分享奖励
                    $this->handleReportProductReward($order, $uid);
                    // 发放服务中心服务费(每笔订单100元)
                    $this->handleServiceCenterFee($order, $uid);
                    // ===== 新增:发放服务点服务费(每笔订单100元) =====
                    $this->handleServicePointFee($order, $uid);
                    // 发放服务点平级奖励(3%)
                    $this->handleServicePointPeerReward($order, $uid, $cartInfo);
                } else {
                    // 复购产品:发放复购奖励
                    $this->handleRepurchaseReward($order, $uid, $cartInfo);
                    // 复购也发放服务中心服务费
                    $this->handleServiceCenterFee($order, $uid);
                    // 复购也发放服务点平级奖励
                    $this->handleServicePointPeerReward($order, $uid, $cartInfo);
                }

                // 标记订单奖励已发放
                app()->make(StoreOrderServices::class)->update($order['id'], ['reward_status' => 1]);
            });
            return true;
        } catch (\Exception $e) {
            Log::error('订单奖励发放失败:订单ID-' . $order['id'] . ',错误:' . $e->getMessage());
            return false;
        }
    }

    /**
     * 处理报单产品奖励
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleReportProductReward(array $order, int $uid): void
    {
        // 获取上级推荐人
        $spreadUid = $this->getSpreadUid($uid);
        if (!$spreadUid) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $spreadUser = $userService->getUserInfo($spreadUid);
        if (!$spreadUser) {
            return;
        }

        // 奖励金额配置
        $cashReward = 650;      // 现金奖励650元
        $couponReward = 650;    // 消费券650积分

        // 1. 发放现金奖励到推荐人的佣金账户
        $currentBrokerage = $spreadUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$cashReward, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'direct_cash',
            $spreadUid,
            [
                'nickname' => $userService->value($uid, 'nickname'),
                'pay_price' => $order['pay_price'],
                'number' => $cashReward,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        // 更新用户佣金余额
        $userService->update($spreadUid, ['brokerage_price' => $newBrokerage], 'uid');

        // 2. 发放消费券(积分)到推荐人
        $currentIntegral = $spreadUser['integral'];
        $newIntegral = $currentIntegral + $couponReward;

        /** @var UserBillServices $billService */
        $billService = app()->make(UserBillServices::class);
        $billService->income(
            'direct_reward_coupon',
            $spreadUid,
            [
                'nickname' => $userService->value($uid, 'nickname'),
                'pay_price' => $order['pay_price'],
                'number' => $couponReward,
            ],
            $newIntegral,
            $order['id']
        );

        // 更新用户积分
        $userService->update($spreadUid, ['integral' => $newIntegral], 'uid');

        $userInfo = $userService->getUserInfo($uid);
        $userService->update($userInfo['uid'], ['first_order' => 1]);

        // 发送消息通知
        event('CustomNoticeListener', [$spreadUid, [
            'uid' => $spreadUid,
            'cash' => $cashReward,
            'coupon' => $couponReward,
            'time' => date('Y-m-d H:i:s')
        ], 'direct_reward']);
    }

    /**
     * 处理服务中心服务费(每笔订单100元)
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServiceCenterFee(array $order, int $uid): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务中心
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_center_uid'] == 0) {
            return;
        }

        $centerUid = $userInfo['service_center_uid'];
        $centerUser = $userService->getUserInfo($centerUid);
        if (!$centerUser || $centerUser['is_service_center'] != 1) {
            return;
        }

        $feeAmount = 100; // 每笔订单100元服务费

        $currentBrokerage = $centerUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$feeAmount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'get_center_brokerage',
            $centerUid,
            [
                'nickname' => $userInfo['nickname'],
                'order_id' => $order['order_id'],
                'number' => $feeAmount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        $userService->update($centerUid, ['brokerage_price' => $newBrokerage], 'uid');
    }

    // ===== 新增:处理服务点服务费(每笔订单100元) =====
    /**
     * 处理服务点服务费(每笔订单100元)
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServicePointFee(array $order, int $uid): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务点
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_point_uid'] == 0) {
            return;
        }

        $pointUid = $userInfo['service_point_uid'];
        $pointUser = $userService->getUserInfo($pointUid);
        if (!$pointUser || $pointUser['is_service_point'] != 1) {
            return;
        }

        $feeAmount = 100; // 每笔订单100元服务费

        $currentBrokerage = $pointUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$feeAmount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'get_point_brokerage', // 类型标识
            $pointUid,
            [
                'nickname' => $userInfo['nickname'],
                'order_id' => $order['order_id'],
                'number' => $feeAmount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        $userService->update($pointUid, ['brokerage_price' => $newBrokerage], 'uid');
    }
    // ===== 新增结束 =====

    /**
     * 处理服务点平级奖励(3%+3%)
     * @param array $order
     * @param int $uid
     * @param array $cartInfo
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServicePointPeerReward(array $order, int $uid, array $cartInfo): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务点
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_point_uid'] == 0) {
            return;
        }

        $pointUid = $userInfo['service_point_uid'];
        $pointUser = $userService->getUserInfo($pointUid);
        if (!$pointUser || $pointUser['is_service_point'] != 1) {
            return;
        }

        // 检查是否存在父级服务点(平级条件)
        $parentPointUid = $pointUser['parent_service_point_uid'];
        if ($parentPointUid == 0) {
            return; // 没有父级服务点,不发放平级奖励
        }

        $parentPointUser = $userService->getUserInfo($parentPointUid);
        if (!$parentPointUser || $parentPointUser['is_service_point'] != 1) {
            return;
        }

        // 计算奖励金额:订单金额的3%
        $orderAmount = $order['pay_price'];
        $rewardAmount = bcmul((string)$orderAmount, '0.03', 2);
        if ($rewardAmount <= 0) {
            return;
        }

        // 发放给所属服务点3%
        $this->addBrokerageToUser($pointUid, (float)$rewardAmount, $order['id'], 'point_peer_self', [
            'nickname' => $userInfo['nickname'],
            'order_id' => $order['order_id'],
            'number' => $rewardAmount,
            'level' => 'self'
        ]);

        // 发放给父级服务点3%
        $this->addBrokerageToUser($parentPointUid, (float)$rewardAmount, $order['id'], 'point_peer_parent', [
            'nickname' => $userInfo['nickname'],
            'order_id' => $order['order_id'],
            'number' => $rewardAmount,
            'level' => 'parent'
        ]);
    }

    /**
     * 处理复购奖励
     * @param array $order
     * @param int $uid
     * @param array $cartInfo
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleRepurchaseReward(array $order, int $uid, array $cartInfo): void
    {
        $orderAmount = $order['pay_price'];

        // 1. 直接推荐人获得30%
        $directReward = bcmul((string)$orderAmount, '0.30', 2);
        $spreadUid = $this->getSpreadUid($uid);
        if ($spreadUid && $directReward > 0) {
            $this->addBrokerageToUser($spreadUid, (float)$directReward, $order['id'], 'repurchase_direct', [
                'nickname' => app()->make(UserServices::class)->value($uid, 'nickname'),
                'order_id' => $order['order_id'],
                'number' => $directReward
            ]);
        }

        // 2. 服务中心获得5%
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);
        if ($userInfo && $userInfo['service_center_uid'] > 0) {
            $centerReward = bcmul((string)$orderAmount, '0.05', 2);
            if ($centerReward > 0) {
                $this->addBrokerageToUser($userInfo['service_center_uid'], (float)$centerReward, $order['id'], 'repurchase_center', [
                    'nickname' => $userInfo['nickname'],
                    'order_id' => $order['order_id'],
                    'number' => $centerReward
                ]);
            }
        }

        // 3. 服务点获得5%
        if ($userInfo && $userInfo['service_point_uid'] > 0) {
            $pointReward = bcmul((string)$orderAmount, '0.05', 2);
            if ($pointReward > 0) {
                $this->addBrokerageToUser($userInfo['service_point_uid'], (float)$pointReward, $order['id'], 'repurchase_point', [
                    'nickname' => $userInfo['nickname'],
                    'order_id' => $order['order_id'],
                    'number' => $pointReward
                ]);
            }
        }
    }

    /**
     * 添加佣金到用户
     * @param int $targetUid
     * @param float $amount
     * @param int $orderId
     * @param string $type
     * @param array $extra
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function addBrokerageToUser(int $targetUid, float $amount, int $orderId, string $type, array $extra = []): void
    {
        if ($amount <= 0 || $targetUid <= 0) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $targetUser = $userService->getUserInfo($targetUid);
        if (!$targetUser) {
            return;
        }

        $currentBrokerage = $targetUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$amount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);

        $titleMap = [
            'point_peer_self' => '服务点平级奖励(本级)',
            'point_peer_parent' => '服务点平级奖励(上级)',
            'repurchase_direct' => '复购直接推荐奖励',
            'repurchase_center' => '复购服务中心奖励',
            'repurchase_point' => '复购服务点奖励',
            'center_fee' => '服务中心服务费',
            'point_fee' => '服务点服务费' // 新增
        ];

        $brokerageService->income(
            $type,
            $targetUid,
            [
                'number' => $amount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400,
                'title' => $titleMap[$type] ?? '佣金奖励',
                'order_id' => $extra['order_id'] ?? '',
                'nickname' => $extra['nickname'] ?? ''
            ],
            $newBrokerage,
            $orderId
        );

        $userService->update($targetUid, ['brokerage_price' => $newBrokerage], 'uid');
    }

    /**
     * 检查订单是否为报单产品
     * @param array $cartInfo
     * @return bool
     */
    protected function checkIsReportProduct(array $cartInfo): bool
    {
        foreach ($cartInfo as $cart) {
            $cartData = is_string($cart['cart_info']) ? json_decode($cart['cart_info'], true) : $cart['cart_info'];
            if (isset($cartData['product_id']) && $cartData['product_id'] == self::PRODUCT_REPORT_ID) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取订单商品信息
     * @param int $orderId
     * @return array
     */
    protected function getOrderCartInfo(int $orderId): array
    {
        /** @var StoreOrderCartInfoServices $cartService */
        $cartService = app()->make(StoreOrderCartInfoServices::class);
        return $cartService->getCartColunm(['oid' => $orderId], 'cart_info,unique', 'id');
    }

    /**
     * 获取上级推荐人UID
     * @param int $uid
     * @return int
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function getSpreadUid(int $uid): int
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);
        return $userInfo['spread_uid'] ?? 0;
    }

    /**
     * 检查并升级服务点
     * @param int $uid 用户UID
     * @param array $order 订单信息
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function checkAndUpgradeToServicePoint(int $uid, array $order): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);

        // 已经是服务点则跳过
        if ($userInfo['is_service_point'] == 1) {
            return;
        }

        $isUpgrade = false;
        $triggerType = '';
        $recommendCount = 0;
        $purchaseCount = 0;
        $upgradeReason = '';
        $servicePointUid = 0;
        $parentPointUid = 0;

        if($userInfo['spread_uid'] != 0){
            // 条件1:直接推荐10名会员(推荐的下级中完成报单的人数)
            $spreadInfo = $userService->getUserInfo($userInfo['spread_uid']);
            $recommendCount = $this->getDirectRecommendReportCount($spreadInfo['uid']);
            if ($recommendCount >= 10) {
                // 获取父级服务点(当前用户的所属服务点)
                $parentPointUid = $spreadInfo['service_point_uid'] ?? 0;
                $isUpgrade = true;
                $servicePointUid = $spreadInfo['uid'];
                $triggerType = 'auto_recommend';
                $upgradeReason = '直接推荐10名会员';
            }
        }


        // 条件2:一次性购买10单会酒(商品ID=1的订单累计收货数量>=10)
        if (!$isUpgrade) {
            $purchaseCount = $this->getUserReportOrderCount($uid);
            if ($purchaseCount >= 10) {
                // 获取父级服务点(当前用户的所属服务点)
                $parentPointUid = $userInfo['service_point_uid'] ?? 0;
                $isUpgrade = true;
                $servicePointUid = $uid;
                $triggerType = 'auto_purchase';
                $upgradeReason = '购买10单会酒';
            }
        }

        if ($isUpgrade) {
            // 升级为服务点
            $updateData = [
                'is_service_point' => 1,
                'service_point_uid' => $servicePointUid,
                'service_point_time' => time(),
                'parent_service_point_uid' => $parentPointUid
            ];
            $userService->update($uid, $updateData, 'uid');

            // ========== 新增:添加升级记录 ==========
            try {
                /** @var UserUpgradeLogServices $upgradeLogService */
                $upgradeLogService = app()->make(UserUpgradeLogServices::class);
                $upgradeLogService->addUpgradeLog($uid, 'service_point', $triggerType, [
                    'recommend_count' => $recommendCount,
                    'purchase_count' => $purchaseCount,
                    'parent_service_point_uid' => $parentPointUid,
                    'remark' => $upgradeReason
                ]);
            } catch (\Exception $e) {
                Log::error('添加服务点升级记录失败:' . $e->getMessage());
            }
            // ========== 新增结束 ==========

            // 记录升级日志
            Log::info("用户{$uid}升级为服务点,原因:{$upgradeReason},父级服务点:{$parentPointUid}");

            // 发送升级通知
            event('CustomNoticeListener', [$uid, [
                'uid' => $uid,
                'reason' => $upgradeReason,
                'time' => date('Y-m-d H:i:s')
            ], 'upgrade_service_point']);
        }
    }

    /**
     * 获取用户直接推荐的完成报单人数
     * @param int $uid
     * @return int
     */
    protected function getDirectRecommendReportCount(int $uid): int
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取所有下级
        $subUsers = $userService->getColumn(['spread_uid' => $uid], 'uid');
        if (empty($subUsers)) {
            return 0;
        }

        // 统计下级中完成报单订单的人数
        /** @var StoreOrderServices $orderService */
        $orderService = app()->make(StoreOrderServices::class);
        $count = 0;
        foreach ($subUsers as $subUid) {
            // 查询该下级是否有已完成收货的报单订单
            $hasReportOrder = $orderService->count([
                'uid' => $subUid,
                'paid' => 1,
                'status' => 2,
                'reward_status' => 1
            ]);
            if ($hasReportOrder > 0) {
                $count++;
            }
        }

        return $count;
    }

    /**
     * 获取用户报单产品累计收货数量
     * @param int $uid
     * @return int
     */
    protected function getUserReportOrderCount(int $uid): int
    {
        /** @var StoreOrderServices $orderService */
        $orderService = app()->make(StoreOrderServices::class);

        // 获取用户所有已完成收货的订单
        $orders = $orderService->getList([
            'uid' => $uid,
            'paid' => 1,
            'status' => 2,
            'reward_status' => 1
        ], ['id']);

        if (empty($orders)) {
            return 0;
        }

        $totalCount = 0;
        $orderIds = array_column($orders, 'id');

        /** @var StoreOrderCartInfoServices $cartService */
        $cartService = app()->make(StoreOrderCartInfoServices::class);
        foreach ($orderIds as $orderId) {
            $cartList = $cartService->getCartColunm(['oid' => $orderId], 'cart_info', 'id');
            foreach ($cartList as $cart) {
                $cartData = is_string($cart) ? json_decode($cart, true) : $cart;
                if (isset($cartData['product_id']) && $cartData['product_id'] == self::PRODUCT_REPORT_ID) {
                    $totalCount += $cartData['cart_num'] ?? 1;
                }
            }
        }

        return $totalCount;
    }

    /**
     * 设置用户的所属服务点和服务中心(收货时调用)
     * @param int $uid 消费者UID
     * @param int $spreadUid 推荐人UID
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function setUserServiceRelation(int $uid, int $spreadUid): void
    {
        if ($spreadUid <= 0) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $spreadUser = $userService->getUserInfo($spreadUid);
        if (!$spreadUser) {
            return;
        }

        $updateData = [];

        // 设置所属服务点
        if ($spreadUser['is_service_point'] == 1 && $spreadUser['service_point_uid'] == 0) {
            $updateData['service_point_uid'] = $spreadUid;
        } elseif ($spreadUser['service_point_uid'] > 0) {
            $updateData['service_point_uid'] = $spreadUser['service_point_uid'];
        }

        // 设置所属服务中心
        if ($spreadUser['is_service_center'] == 1 && $spreadUser['service_center_uid'] == 0) {
            $updateData['service_center_uid'] = $spreadUid;
        } elseif ($spreadUser['service_center_uid'] > 0) {
            $updateData['service_center_uid'] = $spreadUser['service_center_uid'];
        }

        if (!empty($updateData)) {
            $userService->update($uid, $updateData, 'uid');
        }
    }
}<?php
declare(strict_types=1);

namespace app\services\user;

use app\services\BaseServices;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

/**
 * 会员与分销奖励服务
 * Class UserRewardService
 */
class UserRewardService extends BaseServices
{
    // 报单产品ID
    const PRODUCT_REPORT_ID = 1;

    // 奖励类型常量
    const REWARD_TYPE_DIRECT_CASH = 'direct_cash';           // 直接分享现金奖励
    const REWARD_TYPE_DIRECT_COUPON = 'direct_coupon';      // 直接分享消费券奖励
    const REWARD_TYPE_SERVICE_CENTER_FEE = 'service_center_fee'; // 服务中心服务费
    const REWARD_TYPE_SERVICE_POINT_FEE = 'service_point_fee';   // 服务点服务费(新增)
    const REWARD_TYPE_SERVICE_POINT_PEER = 'service_point_peer'; // 服务点平级奖励
    const REWARD_TYPE_REPURCHASE_DIRECT = 'repurchase_direct';     // 复购直接推荐人
    const REWARD_TYPE_REPURCHASE_CENTER = 'repurchase_center';     // 复购服务中心
    const REWARD_TYPE_REPURCHASE_POINT = 'repurchase_point';       // 复购服务点

    /**
     * 处理订单奖励(收货后调用)
     * @param array $order 订单信息
     * @param int $uid 收货用户UID
     * @return bool
     */
    public function handleOrderReward(array $order, int $uid): bool
    {
        // 检查是否已发放奖励
        if ($order['reward_status'] == 1) {
            return true;
        }

        // 获取订单商品信息
        $cartInfo = $this->getOrderCartInfo($order['id']);
        if (!$cartInfo) {
            return true;
        }

        // 判断是否为报单产品(商品ID=1)
        $isReportProduct = $this->checkIsReportProduct($cartInfo);

        try {
            $this->transaction(function () use ($order, $uid, $isReportProduct, $cartInfo) {
                if ($isReportProduct) {
                    // 报单产品:发放直接分享奖励
                    $this->handleReportProductReward($order, $uid);
                    // 发放服务中心服务费(每笔订单100元)
                    $this->handleServiceCenterFee($order, $uid);
                    // ===== 新增:发放服务点服务费(每笔订单100元) =====
                    $this->handleServicePointFee($order, $uid);
                    // 发放服务点平级奖励(3%)
                    $this->handleServicePointPeerReward($order, $uid, $cartInfo);
                } else {
                    // 复购产品:发放复购奖励
                    $this->handleRepurchaseReward($order, $uid, $cartInfo);
                    // 复购也发放服务中心服务费
                    $this->handleServiceCenterFee($order, $uid);
                    // 复购也发放服务点平级奖励
                    $this->handleServicePointPeerReward($order, $uid, $cartInfo);
                }

                // 标记订单奖励已发放
                app()->make(StoreOrderServices::class)->update($order['id'], ['reward_status' => 1]);
            });
            return true;
        } catch (\Exception $e) {
            Log::error('订单奖励发放失败:订单ID-' . $order['id'] . ',错误:' . $e->getMessage());
            return false;
        }
    }

    /**
     * 处理报单产品奖励
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleReportProductReward(array $order, int $uid): void
    {
        // 获取上级推荐人
        $spreadUid = $this->getSpreadUid($uid);
        if (!$spreadUid) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $spreadUser = $userService->getUserInfo($spreadUid);
        if (!$spreadUser) {
            return;
        }

        // 奖励金额配置
        $cashReward = 650;      // 现金奖励650元
        $couponReward = 650;    // 消费券650积分

        // 1. 发放现金奖励到推荐人的佣金账户
        $currentBrokerage = $spreadUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$cashReward, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'direct_cash',
            $spreadUid,
            [
                'nickname' => $userService->value($uid, 'nickname'),
                'pay_price' => $order['pay_price'],
                'number' => $cashReward,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        // 更新用户佣金余额
        $userService->update($spreadUid, ['brokerage_price' => $newBrokerage], 'uid');

        // 2. 发放消费券(积分)到推荐人
        $currentIntegral = $spreadUser['integral'];
        $newIntegral = $currentIntegral + $couponReward;

        /** @var UserBillServices $billService */
        $billService = app()->make(UserBillServices::class);
        $billService->income(
            'direct_reward_coupon',
            $spreadUid,
            [
                'nickname' => $userService->value($uid, 'nickname'),
                'pay_price' => $order['pay_price'],
                'number' => $couponReward,
            ],
            $newIntegral,
            $order['id']
        );

        // 更新用户积分
        $userService->update($spreadUid, ['integral' => $newIntegral], 'uid');

        $userInfo = $userService->getUserInfo($uid);
        $userService->update($userInfo['uid'], ['first_order' => 1]);

        // 发送消息通知
        event('CustomNoticeListener', [$spreadUid, [
            'uid' => $spreadUid,
            'cash' => $cashReward,
            'coupon' => $couponReward,
            'time' => date('Y-m-d H:i:s')
        ], 'direct_reward']);
    }

    /**
     * 处理服务中心服务费(每笔订单100元)
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServiceCenterFee(array $order, int $uid): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务中心
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_center_uid'] == 0) {
            return;
        }

        $centerUid = $userInfo['service_center_uid'];
        $centerUser = $userService->getUserInfo($centerUid);
        if (!$centerUser || $centerUser['is_service_center'] != 1) {
            return;
        }

        $feeAmount = 100; // 每笔订单100元服务费

        $currentBrokerage = $centerUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$feeAmount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'get_center_brokerage',
            $centerUid,
            [
                'nickname' => $userInfo['nickname'],
                'order_id' => $order['order_id'],
                'number' => $feeAmount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        $userService->update($centerUid, ['brokerage_price' => $newBrokerage], 'uid');
    }

    // ===== 新增:处理服务点服务费(每笔订单100元) =====
    /**
     * 处理服务点服务费(每笔订单100元)
     * @param array $order
     * @param int $uid
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServicePointFee(array $order, int $uid): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务点
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_point_uid'] == 0) {
            return;
        }

        $pointUid = $userInfo['service_point_uid'];
        $pointUser = $userService->getUserInfo($pointUid);
        if (!$pointUser || $pointUser['is_service_point'] != 1) {
            return;
        }

        $feeAmount = 100; // 每笔订单100元服务费

        $currentBrokerage = $pointUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$feeAmount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);
        $brokerageService->income(
            'get_point_brokerage', // 类型标识
            $pointUid,
            [
                'nickname' => $userInfo['nickname'],
                'order_id' => $order['order_id'],
                'number' => $feeAmount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400
            ],
            $newBrokerage,
            $order['id']
        );

        $userService->update($pointUid, ['brokerage_price' => $newBrokerage], 'uid');
    }
    // ===== 新增结束 =====

    /**
     * 处理服务点平级奖励(3%+3%)
     * @param array $order
     * @param int $uid
     * @param array $cartInfo
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleServicePointPeerReward(array $order, int $uid, array $cartInfo): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取消费者的所属服务点
        $userInfo = $userService->getUserInfo($uid);
        if (!$userInfo || $userInfo['service_point_uid'] == 0) {
            return;
        }

        $pointUid = $userInfo['service_point_uid'];
        $pointUser = $userService->getUserInfo($pointUid);
        if (!$pointUser || $pointUser['is_service_point'] != 1) {
            return;
        }

        // 检查是否存在父级服务点(平级条件)
        $parentPointUid = $pointUser['parent_service_point_uid'];
        if ($parentPointUid == 0) {
            return; // 没有父级服务点,不发放平级奖励
        }

        $parentPointUser = $userService->getUserInfo($parentPointUid);
        if (!$parentPointUser || $parentPointUser['is_service_point'] != 1) {
            return;
        }

        // 计算奖励金额:订单金额的3%
        $orderAmount = $order['pay_price'];
        $rewardAmount = bcmul((string)$orderAmount, '0.03', 2);
        if ($rewardAmount <= 0) {
            return;
        }

        // 发放给所属服务点3%
        $this->addBrokerageToUser($pointUid, (float)$rewardAmount, $order['id'], 'point_peer_self', [
            'nickname' => $userInfo['nickname'],
            'order_id' => $order['order_id'],
            'number' => $rewardAmount,
            'level' => 'self'
        ]);

        // 发放给父级服务点3%
        $this->addBrokerageToUser($parentPointUid, (float)$rewardAmount, $order['id'], 'point_peer_parent', [
            'nickname' => $userInfo['nickname'],
            'order_id' => $order['order_id'],
            'number' => $rewardAmount,
            'level' => 'parent'
        ]);
    }

    /**
     * 处理复购奖励
     * @param array $order
     * @param int $uid
     * @param array $cartInfo
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function handleRepurchaseReward(array $order, int $uid, array $cartInfo): void
    {
        $orderAmount = $order['pay_price'];

        // 1. 直接推荐人获得30%
        $directReward = bcmul((string)$orderAmount, '0.30', 2);
        $spreadUid = $this->getSpreadUid($uid);
        if ($spreadUid && $directReward > 0) {
            $this->addBrokerageToUser($spreadUid, (float)$directReward, $order['id'], 'repurchase_direct', [
                'nickname' => app()->make(UserServices::class)->value($uid, 'nickname'),
                'order_id' => $order['order_id'],
                'number' => $directReward
            ]);
        }

        // 2. 服务中心获得5%
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);
        if ($userInfo && $userInfo['service_center_uid'] > 0) {
            $centerReward = bcmul((string)$orderAmount, '0.05', 2);
            if ($centerReward > 0) {
                $this->addBrokerageToUser($userInfo['service_center_uid'], (float)$centerReward, $order['id'], 'repurchase_center', [
                    'nickname' => $userInfo['nickname'],
                    'order_id' => $order['order_id'],
                    'number' => $centerReward
                ]);
            }
        }

        // 3. 服务点获得5%
        if ($userInfo && $userInfo['service_point_uid'] > 0) {
            $pointReward = bcmul((string)$orderAmount, '0.05', 2);
            if ($pointReward > 0) {
                $this->addBrokerageToUser($userInfo['service_point_uid'], (float)$pointReward, $order['id'], 'repurchase_point', [
                    'nickname' => $userInfo['nickname'],
                    'order_id' => $order['order_id'],
                    'number' => $pointReward
                ]);
            }
        }
    }

    /**
     * 添加佣金到用户
     * @param int $targetUid
     * @param float $amount
     * @param int $orderId
     * @param string $type
     * @param array $extra
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function addBrokerageToUser(int $targetUid, float $amount, int $orderId, string $type, array $extra = []): void
    {
        if ($amount <= 0 || $targetUid <= 0) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $targetUser = $userService->getUserInfo($targetUid);
        if (!$targetUser) {
            return;
        }

        $currentBrokerage = $targetUser['brokerage_price'];
        $newBrokerage = bcadd((string)$currentBrokerage, (string)$amount, 2);

        /** @var UserBrokerageServices $brokerageService */
        $brokerageService = app()->make(UserBrokerageServices::class);

        $titleMap = [
            'point_peer_self' => '服务点平级奖励(本级)',
            'point_peer_parent' => '服务点平级奖励(上级)',
            'repurchase_direct' => '复购直接推荐奖励',
            'repurchase_center' => '复购服务中心奖励',
            'repurchase_point' => '复购服务点奖励',
            'center_fee' => '服务中心服务费',
            'point_fee' => '服务点服务费' // 新增
        ];

        $brokerageService->income(
            $type,
            $targetUid,
            [
                'number' => $amount,
                'frozen_time' => time() + intval(sys_config('extract_time', 30)) * 86400,
                'title' => $titleMap[$type] ?? '佣金奖励',
                'order_id' => $extra['order_id'] ?? '',
                'nickname' => $extra['nickname'] ?? ''
            ],
            $newBrokerage,
            $orderId
        );

        $userService->update($targetUid, ['brokerage_price' => $newBrokerage], 'uid');
    }

    /**
     * 检查订单是否为报单产品
     * @param array $cartInfo
     * @return bool
     */
    protected function checkIsReportProduct(array $cartInfo): bool
    {
        foreach ($cartInfo as $cart) {
            $cartData = is_string($cart['cart_info']) ? json_decode($cart['cart_info'], true) : $cart['cart_info'];
            if (isset($cartData['product_id']) && $cartData['product_id'] == self::PRODUCT_REPORT_ID) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取订单商品信息
     * @param int $orderId
     * @return array
     */
    protected function getOrderCartInfo(int $orderId): array
    {
        /** @var StoreOrderCartInfoServices $cartService */
        $cartService = app()->make(StoreOrderCartInfoServices::class);
        return $cartService->getCartColunm(['oid' => $orderId], 'cart_info,unique', 'id');
    }

    /**
     * 获取上级推荐人UID
     * @param int $uid
     * @return int
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function getSpreadUid(int $uid): int
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);
        return $userInfo['spread_uid'] ?? 0;
    }

    /**
     * 检查并升级服务点
     * @param int $uid 用户UID
     * @param array $order 订单信息
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function checkAndUpgradeToServicePoint(int $uid, array $order): void
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $userInfo = $userService->getUserInfo($uid);

        // 已经是服务点则跳过
        if ($userInfo['is_service_point'] == 1) {
            return;
        }

        $isUpgrade = false;
        $triggerType = '';
        $recommendCount = 0;
        $purchaseCount = 0;
        $upgradeReason = '';
        $servicePointUid = 0;
        $parentPointUid = 0;

        if($userInfo['spread_uid'] != 0){
            // 条件1:直接推荐10名会员(推荐的下级中完成报单的人数)
            $spreadInfo = $userService->getUserInfo($userInfo['spread_uid']);
            $recommendCount = $this->getDirectRecommendReportCount($spreadInfo['uid']);
            if ($recommendCount >= 10) {
                // 获取父级服务点(当前用户的所属服务点)
                $parentPointUid = $spreadInfo['service_point_uid'] ?? 0;
                $isUpgrade = true;
                $servicePointUid = $spreadInfo['uid'];
                $triggerType = 'auto_recommend';
                $upgradeReason = '直接推荐10名会员';
            }
        }


        // 条件2:一次性购买10单会酒(商品ID=1的订单累计收货数量>=10)
        if (!$isUpgrade) {
            $purchaseCount = $this->getUserReportOrderCount($uid);
            if ($purchaseCount >= 10) {
                // 获取父级服务点(当前用户的所属服务点)
                $parentPointUid = $userInfo['service_point_uid'] ?? 0;
                $isUpgrade = true;
                $servicePointUid = $uid;
                $triggerType = 'auto_purchase';
                $upgradeReason = '购买10单会酒';
            }
        }

        if ($isUpgrade) {
            // 升级为服务点
            $updateData = [
                'is_service_point' => 1,
                'service_point_uid' => $servicePointUid,
                'service_point_time' => time(),
                'parent_service_point_uid' => $parentPointUid
            ];
            $userService->update($uid, $updateData, 'uid');

            // ========== 新增:添加升级记录 ==========
            try {
                /** @var UserUpgradeLogServices $upgradeLogService */
                $upgradeLogService = app()->make(UserUpgradeLogServices::class);
                $upgradeLogService->addUpgradeLog($uid, 'service_point', $triggerType, [
                    'recommend_count' => $recommendCount,
                    'purchase_count' => $purchaseCount,
                    'parent_service_point_uid' => $parentPointUid,
                    'remark' => $upgradeReason
                ]);
            } catch (\Exception $e) {
                Log::error('添加服务点升级记录失败:' . $e->getMessage());
            }
            // ========== 新增结束 ==========

            // 记录升级日志
            Log::info("用户{$uid}升级为服务点,原因:{$upgradeReason},父级服务点:{$parentPointUid}");

            // 发送升级通知
            event('CustomNoticeListener', [$uid, [
                'uid' => $uid,
                'reason' => $upgradeReason,
                'time' => date('Y-m-d H:i:s')
            ], 'upgrade_service_point']);
        }
    }

    /**
     * 获取用户直接推荐的完成报单人数
     * @param int $uid
     * @return int
     */
    protected function getDirectRecommendReportCount(int $uid): int
    {
        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);

        // 获取所有下级
        $subUsers = $userService->getColumn(['spread_uid' => $uid], 'uid');
        if (empty($subUsers)) {
            return 0;
        }

        // 统计下级中完成报单订单的人数
        /** @var StoreOrderServices $orderService */
        $orderService = app()->make(StoreOrderServices::class);
        $count = 0;
        foreach ($subUsers as $subUid) {
            // 查询该下级是否有已完成收货的报单订单
            $hasReportOrder = $orderService->count([
                'uid' => $subUid,
                'paid' => 1,
                'status' => 2,
                'reward_status' => 1
            ]);
            if ($hasReportOrder > 0) {
                $count++;
            }
        }

        return $count;
    }

    /**
     * 获取用户报单产品累计收货数量
     * @param int $uid
     * @return int
     */
    protected function getUserReportOrderCount(int $uid): int
    {
        /** @var StoreOrderServices $orderService */
        $orderService = app()->make(StoreOrderServices::class);

        // 获取用户所有已完成收货的订单
        $orders = $orderService->getList([
            'uid' => $uid,
            'paid' => 1,
            'status' => 2,
            'reward_status' => 1
        ], ['id']);

        if (empty($orders)) {
            return 0;
        }

        $totalCount = 0;
        $orderIds = array_column($orders, 'id');

        /** @var StoreOrderCartInfoServices $cartService */
        $cartService = app()->make(StoreOrderCartInfoServices::class);
        foreach ($orderIds as $orderId) {
            $cartList = $cartService->getCartColunm(['oid' => $orderId], 'cart_info', 'id');
            foreach ($cartList as $cart) {
                $cartData = is_string($cart) ? json_decode($cart, true) : $cart;
                if (isset($cartData['product_id']) && $cartData['product_id'] == self::PRODUCT_REPORT_ID) {
                    $totalCount += $cartData['cart_num'] ?? 1;
                }
            }
        }

        return $totalCount;
    }

    /**
     * 设置用户的所属服务点和服务中心(收货时调用)
     * @param int $uid 消费者UID
     * @param int $spreadUid 推荐人UID
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function setUserServiceRelation(int $uid, int $spreadUid): void
    {
        if ($spreadUid <= 0) {
            return;
        }

        /** @var UserServices $userService */
        $userService = app()->make(UserServices::class);
        $spreadUser = $userService->getUserInfo($spreadUid);
        if (!$spreadUser) {
            return;
        }

        $updateData = [];

        // 设置所属服务点
        if ($spreadUser['is_service_point'] == 1 && $spreadUser['service_point_uid'] == 0) {
            $updateData['service_point_uid'] = $spreadUid;
        } elseif ($spreadUser['service_point_uid'] > 0) {
            $updateData['service_point_uid'] = $spreadUser['service_point_uid'];
        }

        // 设置所属服务中心
        if ($spreadUser['is_service_center'] == 1 && $spreadUser['service_center_uid'] == 0) {
            $updateData['service_center_uid'] = $spreadUid;
        } elseif ($spreadUser['service_center_uid'] > 0) {
            $updateData['service_center_uid'] = $spreadUser['service_center_uid'];
        }

        if (!empty($updateData)) {
            $userService->update($uid, $updateData, 'uid');
        }
    }
}