wesmiler 2 лет назад
Родитель
Сommit
67a0e9def0

+ 103 - 5
app/Console/Commands/SwooleTask.php

@@ -5,6 +5,7 @@ namespace App\Console\Commands;
 use App\Services\Api\FinanceService;
 use App\Services\Api\GoodsCategoryService;
 use App\Services\Api\GoodsService;
+use App\Services\Api\OrderService;
 use App\Services\RedisService;
 use App\Services\WalletService;
 use Illuminate\Console\Command;
@@ -359,7 +360,7 @@ class SwooleTask extends Command
         });
 
         // TODO 发放积分
-        \swoole_timer_tick(300000, function ($timer) use ($serv, &$time) { // 启用定时器,每1200秒执行一次
+        \swoole_timer_tick(180000, function ($timer) use ($serv, &$time) { // 启用定时器,每180秒执行一次
             $date = date('Y-m-d H:i:s');
             if($time>3600 && file_exists($this->options['log_file'])){
                 $time = 0;
@@ -382,27 +383,73 @@ class SwooleTask extends Command
         });
 
         // TODO 待返积分返还
-        \swoole_timer_tick(300000, function ($timer) use ($serv, &$time) { // 启用定时器,每1200秒执行一次
+        \swoole_timer_tick(120000, function ($timer) use ($serv, &$time) { // 启用定时器,每120秒执行一次
             $date = date('Y-m-d H:i:s');
             if($time>3600 && file_exists($this->options['log_file'])){
                 $time = 0;
                 file_put_contents($this->options['log_file'],"Task {$date}:清空日志\n");
             }
             $time++;
-            if(!RedisService::get('caches:task:lock:waitt_score_loaded')){
+            if(!RedisService::get('caches:task:lock:wait_score_loaded')){
                 $taskData = [
                     'taskName' => 'ReturnWaitScore',
                     'name' => "待返积分每日返还",
                     'date' => date('Y-m-d'),
                 ];
                 $res = $serv->task($taskData);
-                RedisService::set('caches:task:lock:waitt_score_loaded', true, rand(3,5));
+                RedisService::set('caches:task:lock:wait_score_loaded', true, rand(3,5));
                 echo "[Task ReturnWaitScore {$date}] 待返积分每日返还:{$res}\n";
             }else{
                 echo "[Task ReturnWaitScore {$date}] 间隔时间调用\n";
             }
 
         });
+
+        // TODO 全球分红结算
+        \swoole_timer_tick(120000, function ($timer) use ($serv, &$time) { // 启用定时器,每120秒执行一次
+            $date = date('Y-m-d H:i:s');
+            if($time>3600 && file_exists($this->options['log_file'])){
+                $time = 0;
+                file_put_contents($this->options['log_file'],"Task {$date}:清空日志\n");
+            }
+            $time++;
+            if(!RedisService::get('caches:task:lock:global_loaded')){
+                $taskData = [
+                    'taskName' => 'GlobalBonus',
+                    'name' => "待返积分每日返还",
+                    'date' => date('Y-m-d'),
+                ];
+                $res = $serv->task($taskData);
+                RedisService::set('caches:task:lock:global_loaded', true, rand(3,5));
+                echo "[Task GlobalBonus {$date}] 全球分红结算:{$res}\n";
+            }else{
+                echo "[Task GlobalBonus {$date}] 间隔时间调用\n";
+            }
+
+        });
+
+        // TODO 更新订单状态
+        \swoole_timer_tick(300000, function ($timer) use ($serv, &$time) { // 启用定时器,每300秒执行一次
+            $date = date('Y-m-d H:i:s');
+            if($time>3600 && file_exists($this->options['log_file'])){
+                $time = 0;
+                file_put_contents($this->options['log_file'],"Task {$date}:清空日志\n");
+            }
+            $time++;
+            if(!RedisService::get('caches:task:lock:order_loaded')){
+                $taskData = [
+                    'taskName' => 'UpdateOrderStatus',
+                    'name' => "更新订单状态",
+                    'date' => date('Y-m-d'),
+                ];
+                $res = $serv->task($taskData);
+                RedisService::set('caches:task:lock:order_loaded', true, rand(3,5));
+                echo "[Task UpdateOrderStatus {$date}] 更新订单状态:{$res}\n";
+            }else{
+                echo "[Task UpdateOrderStatus {$date}] 间隔时间调用\n";
+            }
+
+        });
     }
 
     //监听连接进入事件
@@ -433,6 +480,40 @@ class SwooleTask extends Command
         $date = date('Y-m-d H:i:s');
         $taskName = isset($data['taskName']) ? $data['taskName'] : '';
         switch ($taskName) {
+            case 'UpdateOrderStatus': // 更新订单状态
+                // 时间限制
+                if(date('H:i') >= '00:00' && date('H:i') <= '05:00'){
+                    echo "[Task {$taskName} {$date}] 不在运行时间段内\n";
+                    return false;
+                }
+
+                // 调用处理
+                if($res = OrderService::make()->updateOrderStatus()){
+                    $res = is_array($res) && $res? json_encode($res, 256) : 'success';
+                    echo "[Task {$taskName} {$date}] 更新订单状态结果:{$res}\n";
+                }else{
+                    $error = OrderService::make()->getError();
+                    $error = $error? lang($error) : 'failed';
+                    echo "[Task {$taskName} {$date}] 更新订单状态结果:{$error}\n";
+                }
+                break;
+            case 'UpdateOrderRefundStatus': // 更新售后订单状态
+                // 时间限制
+                if(date('H:i') >= '00:00' && date('H:i') <= '05:00'){
+                    echo "[Task {$taskName} {$date}] 不在运行时间段内\n";
+                    return false;
+                }
+
+                // 调用处理
+                if($res = OrderService::make()->updateOrderRefundStatus()){
+                    $res = is_array($res) && $res? json_encode($res, 256) : 'success';
+                    echo "[Task {$taskName} {$date}] 更新售后订单状态结果:{$res}\n";
+                }else{
+                    $error = OrderService::make()->getError();
+                    $error = $error? lang($error) : 'failed';
+                    echo "[Task {$taskName} {$date}] 更新售后订单状态结果:{$error}\n";
+                }
+                break;
             case 'UpdateGoods': // 更新商品
                 // 时间限制
                 if(date('H:i') >= '00:00' && date('H:i') <= '03:00'){
@@ -538,7 +619,7 @@ class SwooleTask extends Command
                 break;
             case 'ReturnWaitScore':
                 // 时间限制
-                if(date('H:i') >= '10:00'){
+                if(date('H:i') >= '06:00'){
                     echo "[Task {$taskName} {$date}] 不在运行时间段内\n";
                     return false;
                 }
@@ -553,6 +634,23 @@ class SwooleTask extends Command
                     echo "[Task {$taskName} {$date}] 待返积分每日返还结果:{$error}\n";
                 }
                 break;
+            case 'GlobalBonus': // 全球分红
+                // 时间限制
+                if(date('H:i') >= '05:00'){
+                    echo "[Task {$taskName} {$date}] 不在运行时间段内\n";
+                    return false;
+                }
+
+                // 调用处理
+                if($res = FinanceService::make()->globalBonus()){
+                    $res = is_array($res) && $res? json_encode($res, 256) : 'success';
+                    echo "[Task {$taskName} {$date}] 全球分红结算结果:{$res}\n";
+                }else{
+                    $error = FinanceService::make()->getError();
+                    $error = $error? lang($error) : 'failed';
+                    echo "[Task {$taskName} {$date}] 全球分红结算结果:{$error}\n";
+                }
+                break;
         }
 
         return '暂无任务处理';

+ 25 - 0
app/Models/AccountCountModel.php

@@ -0,0 +1,25 @@
+<?php
+// +----------------------------------------------------------------------
+// | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
+// +----------------------------------------------------------------------
+// | 版权所有 2017~2021 LARAVEL研发中心
+// +----------------------------------------------------------------------
+// | 官方网站: http://www.laravel.cn
+// +----------------------------------------------------------------------
+// | Author: laravel开发员 <laravel.qq.com>
+// +----------------------------------------------------------------------
+
+namespace App\Models;
+
+/**
+ * 账户统计-模型
+ * @author laravel开发员
+ * @since 2020/11/11
+ * @package App\Models
+ */
+class AccountCountModel extends BaseModel
+{
+    // 设置数据表
+    protected $table = 'account_counts';
+
+}

+ 73 - 0
app/Services/Api/AccountLogService.php

@@ -11,6 +11,7 @@
 
 namespace App\Services\Api;
 
+use App\Models\AccountCountModel;
 use App\Models\AccountLogModel;
 use App\Models\MemberModel;
 use App\Services\BaseService;
@@ -328,6 +329,58 @@ class AccountLogService extends BaseService
     }
 
     /**
+     * 个人每日业绩
+     * @param $userId
+     * @param $date
+     * @param int $type
+     * @return array|mixed
+     */
+    public function getTotal($userId, $date, $type = 2)
+    {
+        $cacheKey = "caches:members:account:total_{$userId}_{$date}_{$type}";
+        $data = RedisService::get($cacheKey);
+        if($data){
+            return $data;
+        }
+
+        $data = AccountCountModel::where(['user_id'=> $userId,'date'=>$date,'type'=> $type])
+            ->sum('money');
+        if($data){
+            RedisService::set($cacheKey, 5, 10);
+        }
+
+        return $data;
+    }
+
+    /**
+     * 团队每日业绩
+     * @param $userId
+     * @param $date
+     * @param int $type
+     * @return array|mixed
+     */
+    public function getTeamTotal($userId, $date, $type = 2)
+    {
+        $cacheKey = "caches:members:account:tram_total_{$userId}_{$date}_{$type}";
+        $data = RedisService::get($cacheKey);
+        if($data){
+            return $data;
+        }
+        $data = AccountCountModel::from('account_counts as a')
+            ->leftJoin('member as b','b.id','=','a.user_id')
+            ->where(function($query) use($userId){
+                $query->where('b.id',$userId)->orWhereRaw('FIND_IN_SET(?,b.parents)', $userId);
+            })
+            ->where(['a.date'=>$date,'a.type'=> $type])
+            ->sum('a.money');
+        if($data){
+            RedisService::set($cacheKey, $data, rand(5,10));
+        }
+
+        return $data;
+    }
+
+    /**
      * @param $params
      * @param int $pageSize
      * @return array
@@ -415,4 +468,24 @@ class AccountLogService extends BaseService
             'list' => $list,
         ];
     }
+
+    /**
+     * 更新账户统计
+     * @param $userId 用户ID
+     * @param $money 金额
+     * @param int $type 类型
+     * @return mixed
+     */
+    public function saveCount($userId, $money, $type=1)
+    {
+        $date = date('Y-m-d');
+        $id = AccountCountModel::where(['user_id'=> $userId,'date'=> $date,'type'=> $type])->value('id');
+        if(!$id){
+            $data = ['user_id'=>$userId,'date'=> $date,'type'=>$type,'money'=>$money,'create_time'=>time(),'update_time'=> time()];
+            return $this->model->insertGetId($data);
+        }else{
+            $data = ['money'=>DB::raw("money + {$money}"),'update_time'=>time()];
+            return AccountCountModel::where(['id'=> $id])->update($data);
+        }
+    }
 }

+ 647 - 5
app/Services/Api/FinanceService.php

@@ -11,6 +11,7 @@
 
 namespace App\Services\Api;
 
+use App\Models\AccountCountModel;
 use App\Models\AccountLogModel;
 use App\Models\FinanceModel;
 use App\Models\MemberModel;
@@ -165,7 +166,11 @@ class FinanceService extends BaseService
             $bonusUsdt1 = moneyFormat($usdt * $rate1/100, 4);
             if($parentInfo && $bonusUsdt1>0){
                 // 账户进账
-                $updateData = ['usdt'=> DB::raw("usdt + {$bonusUsdt1}"),'update_time'=>time()];
+                $updateData = [
+                    'usdt'=> DB::raw("usdt + {$bonusUsdt1}"),
+                    'upgrade_profit_total'=>DB::raw("upgrade_profit_total + {$bonusUsdt1}"), // 升级累计收益
+                    'update_time'=>time()
+                ];
                 if(!MemberModel::where(['id'=> $parentId,'mark'=>1])->update($updateData)){
                     DB::rollBack();
                     $this->error = 2601;
@@ -218,7 +223,11 @@ class FinanceService extends BaseService
             if($pointInfo && $bonusUsdt2>0){
                 if($pointLevel>= $userLevel){
                     // 账户进账
-                    $updateData = ['usdt'=> DB::raw("usdt + {$bonusUsdt2}"),'update_time'=>time()];
+                    $updateData = [
+                        'usdt'=> DB::raw("usdt + {$bonusUsdt2}"),
+                        'upgrade_profit_total'=>DB::raw("upgrade_profit_total + {$bonusUsdt2}"), // 升级累计收益
+                        'update_time'=>time()
+                    ];
                     if(!MemberModel::where(['id'=> $pointId,'mark'=>1])->update($updateData)){
                         DB::rollBack();
                         $this->error = 2603;
@@ -299,7 +308,11 @@ class FinanceService extends BaseService
                     $awardIndex = $k;
                     if($bonusUsdt3>0){
                         // 账户进账
-                        $updateData = ['usdt'=> DB::raw("usdt + {$bonusUsdt3}"),'update_time'=>time()];
+                        $updateData = [
+                            'usdt'=> DB::raw("usdt + {$bonusUsdt3}"),
+                            'upgrade_profit_total'=>DB::raw("upgrade_profit_total + {$bonusUsdt3}"), // 升级累计收益
+                            'update_time'=>time()
+                        ];
                         if(!MemberModel::where(['id'=> $pid,'mark'=>1])->update($updateData)){
                             DB::rollBack();
                             $this->error = 2605;
@@ -442,12 +455,266 @@ class FinanceService extends BaseService
 
         DB::commit();
 
+        // 算力统计
+        AccountLogService::make()->saveCount($userId, $power, 1);
+
         // 站内消息
         $dateTime = date('Y-m-d H:i:s');
         MessageService::make()->pushMessage($userId,   $log['remark'] , "您在{$dateTime}(UTC+8){$log['remark']}{$power}算力已到账,请及时查看账户!!!",3);
 
     }
 
+    /**
+     * 订单结算
+     * @param $orderInfo 订单信息
+     * @param $orderXdTotal 星豆数量
+     * @param int $userId
+     * @return bool
+     */
+    public function settleOrder($orderInfo, $orderXdTotal, $userId=0)
+    {
+        //$orderXdTotal = isset($orderInfo['xd_total'])?$orderInfo['xd_total'] : 0;
+        $orderId = isset($orderInfo['id'])?$orderInfo['id'] : 0;
+        $orderNo = isset($orderInfo['order_no'])?$orderInfo['order_no'] : '';
+        $orderUserId = isset($orderInfo['user_id'])?$orderInfo['user_id'] : 0;
+        $orderMerchUid = isset($orderInfo['merch_uid'])?$orderInfo['merch_uid'] : 0;
+        if(empty($orderId) || empty($orderUserId)){
+            $this->error = 2912;
+            return true;
+        }
+
+        if($orderXdTotal <= 0){
+            $this->error = 3005;
+            return true;
+        }
+
+        $cacheKey = "caches:settle:{$userId}_{$orderNo}";
+        if(RedisService::get($cacheKey)){
+            $this->error = 3002;
+            return true;
+        }
+
+        // 奖励待返积分、算力
+        $awardWaitScore = isset($orderInfo['award_wait_score'])?$orderInfo['award_wait_score'] : 0;
+        $awardPowerNum = isset($orderInfo['award_power_num'])?$orderInfo['award_power_num'] : 0;
+
+        // 订单用户信息
+        $userInfo = MemberModel::with(['parent'])
+            ->where(['id'=> $orderUserId,'mark'=> 1,'status'=> 1])
+            ->select(['id','nickname','pay_password','balance','usdt','power_num','wait_score','parent_id','parents'])
+            ->first();
+        $userInfo = $userInfo? $userInfo->toArray() : [];
+        $parentInfo = isset($userInfo['parent'])? $userInfo['parent'] : [];
+        $parentId = isset($userInfo['parent_id'])? $userInfo['parent_id'] : 0;
+        $userXd = isset($userInfo['balance'])? floatval($userInfo['balance']) : 0.00;
+        $userWaitScore = isset($userInfo['wait_score'])? floatval($userInfo['wait_score']) : 0.00;
+        $userPowerNum = isset($userInfo['power_num'])? floatval($userInfo['power_num']) : 0.00;
+        if(empty($userInfo)){
+            $this->error = 3003;
+            RedisService::clear($cacheKey);
+            return true;
+        }
+
+        // 推荐用户奖励(从用户奖励中扣除)
+        $inviteAwardWaitScore = 0;
+        $userAwardWaitScore = $awardWaitScore;
+        $parentStatus = isset($parentInfo['status'])? $parentInfo['status'] : 0;
+        if($parentInfo && $parentStatus==1 && $awardWaitScore>0){
+            // 奖励上级待返积分
+            $inviteWaitScoreRate = ConfigService::make()->getConfigByCode('cost_award_invite_wait_score',0);
+            $inviteWaitScoreRate = $inviteWaitScoreRate>0 && $inviteWaitScoreRate<100? $inviteWaitScoreRate : 0;
+            $inviteAwardWaitScore = moneyFormat($awardWaitScore * $inviteWaitScoreRate/100, 2);
+            $userAwardWaitScore = moneyFormat($awardWaitScore - $inviteAwardWaitScore, 2);
+        }
+
+        // 没有佣金
+        if($userAwardWaitScore<=0 && $userPowerNum<=0){
+            $this->error = 3004;
+            RedisService::clear($cacheKey);
+            return true;
+        }
+
+
+        // TODO 结算处理
+        DB::beginTransaction();
+
+        // TODO 订单商户佣金结算
+        if ($orderMerchUid > 0){
+            $merchantUserInfo = MemberModel::where(['id'=> $orderMerchUid,'mark'=>1])
+                ->select(['id','balance','wait_score','usdt','status'])
+                ->first();
+
+            // 商户佣金计算入账
+            $settleRate = ConfigService::make()->getConfigByCode('merchant_settle_usdt_rate');
+            $settleRate = $settleRate>0? min(100, $settleRate) : 100;
+            $settleXd = moneyFormat($orderXdTotal * $settleRate/100, 2);
+
+            $xdPrice = ConfigService::make()->getConfigByCode('xd_price',100);
+            $xdPrice = $xdPrice>0 && $xdPrice<10000? $xdPrice : 100;
+            $settleUsdt = moneyFormat($settleXd/$xdPrice, 2);
+
+            if($settleUsdt>0 && $merchantUserInfo){
+                $updateData = ['usdt'=> DB::raw("usdt + {$settleUsdt}"),'update_time'=>time()];
+                if(!MemberModel::where(['id'=> $orderMerchUid])->update($updateData)){
+                    DB::rollBack();
+                    $this->error = 1042;
+                    return false;
+                }
+
+                // 明细
+                $merchantUsdt = isset($merchantUserInfo['usdt'])? $merchantUserInfo['usdt'] : 0;
+                $log = [
+                    'user_id' => $orderMerchUid,
+                    'source_id' => $orderUserId,
+                    'source_order_no' => $orderNo,
+                    'type' => 10,
+                    'coin_type' => 1,
+                    'user_type'=> 1,
+                    'money' => $settleUsdt,
+                    'actual_money' => $settleUsdt,
+                    'balance' => $merchantUsdt,
+                    'create_time' => time(),
+                    'update_time' => time(),
+                    'remark' => "推荐商品佣金奖励",
+                    'status' => 1,
+                    'mark' => 1,
+                ];
+                if(!AccountLogModel::insertGetId($log)){
+                    DB::rollBack();
+                    $this->error = 2029;
+                    RedisService::clear($cacheKey);
+                    return false;
+                }
+            }
+
+        }
+
+        // TODO 购买用户奖励结算
+        $updateData = [
+            'wait_score'=>DB::raw("wait_score + {$userAwardWaitScore}"),  // 用户待返积分奖励
+            'power_num'=>DB::raw("power_num + {$awardPowerNum}"),  // 算力奖励
+            'update_time'=>time()
+        ];
+        if(!MemberModel::where(['id'=> $userId])->update($updateData)){
+            DB::rollBack();
+            $this->error = 1042;
+            RedisService::clear($cacheKey);
+            return false;
+        }
+
+        // 待返积分奖励明细
+        if($userAwardWaitScore>0){
+            $log = [
+                'user_id' => $orderUserId,
+                'source_id' => $orderId,
+                'source_order_no' => $orderNo,
+                'type' => 9,
+                'coin_type' => 5,
+                'user_type'=> 1,
+                'money' => $userAwardWaitScore,
+                'actual_money' => $userAwardWaitScore,
+                'balance' => $userWaitScore,
+                'create_time' => time(),
+                'update_time' => time(),
+                'remark' => "商城消费奖励",
+                'status' => 1,
+                'mark' => 1,
+            ];
+            if(!AccountLogModel::insertGetId($log)){
+                DB::rollBack();
+                $this->error = 2029;
+                RedisService::clear($cacheKey);
+                return false;
+            }
+
+            // 用户消息
+            $dateTime = date('Y-m-d H:i:s');
+            $message = "您在{$dateTime}(UTC+8)完成商城消费,获得待返积分奖励已到账:\n消费星豆:{$orderXdTotal}\n奖励积分:{$userAwardWaitScore}\n奖励前:{$userWaitScore}";
+            MessageService::make()->pushMessage($userId, '商城消费待返积分奖励', $message,3);
+        }
+
+        // 算力奖励明细
+        if($awardPowerNum>0){
+            $log = [
+                'user_id' => $orderUserId,
+                'source_id' => $orderId,
+                'source_order_no' => $orderNo,
+                'type' => 9,
+                'coin_type' => 3,
+                'user_type'=> 1,
+                'money' => $awardPowerNum,
+                'actual_money' => $awardPowerNum,
+                'balance' => $userPowerNum,
+                'create_time' => time(),
+                'update_time' => time(),
+                'remark' => "商城消费奖励",
+                'status' => 1,
+                'mark' => 1,
+            ];
+            if(!AccountLogModel::insertGetId($log)){
+                DB::rollBack();
+                $this->error = 2029;
+                RedisService::clear($cacheKey);
+                return false;
+            }
+
+            // 用户消息
+            $dateTime = date('Y-m-d H:i:s');
+            $message = "您在{$dateTime}(UTC+8)完成商城消费,获得算力奖励已到账:\n消费星豆:{$orderXdTotal}\n奖励算力:{$awardPowerNum}\n奖励前:{$userPowerNum}";
+            MessageService::make()->pushMessage($userId, '商城消费算力奖励', $message,3);
+
+            // 算力统计
+            AccountLogService::make()->saveCount($userId, $userPowerNum, 1);
+        }
+
+        // TODO 推荐用户待返积分奖励明细
+        if($inviteAwardWaitScore>0 && $parentId>0 && $parentId != $orderUserId){
+            $updateData = [
+                'wait_score'=>DB::raw("wait_score + {$inviteAwardWaitScore}"),  // 推荐用户待返积分奖励
+                'update_time'=>time()
+            ];
+            if(!MemberModel::where(['id'=> $parentId])->update($updateData)){
+                DB::rollBack();
+                $this->error = 2028;
+                RedisService::clear($cacheKey);
+                return false;
+            }
+
+            // 明细
+            $parentWaitScore = isset($parentInfo['wait_score'])? $parentInfo['wait_score'] : 0;
+            $log = [
+                'user_id' => $parentId,
+                'source_id' => $orderUserId,
+                'source_order_no' => $orderNo,
+                'type' => 9,
+                'coin_type' => 5,
+                'user_type'=> 1,
+                'money' => $inviteAwardWaitScore,
+                'actual_money' => $inviteAwardWaitScore,
+                'balance' => $parentWaitScore,
+                'create_time' => time(),
+                'update_time' => time(),
+                'remark' => "推荐用户商城消费奖励",
+                'status' => 1,
+                'mark' => 1,
+            ];
+            if(!AccountLogModel::insertGetId($log)){
+                DB::rollBack();
+                $this->error = 2029;
+                RedisService::clear($cacheKey);
+                return false;
+            }
+
+            // 用户消息
+            $dateTime = date('Y-m-d H:i:s');
+            $message = "您在{$dateTime}(UTC+8)获得推荐用户【{$userId}】商城消费,待返积分奖励已到账:\n消费星豆:{$orderXdTotal}\n奖励积分:{$inviteAwardWaitScore}\n奖励前:{$parentWaitScore}";
+            MessageService::make()->pushMessage($userId, '推荐用户商城消费奖励', $message,3);
+        }
+
+        DB::commit();
+        RedisService::clear($cacheKey);
+        return true;
+    }
 
     /**
      * 每日平台发放积分
@@ -455,7 +722,140 @@ class FinanceService extends BaseService
      */
     public function grantScore()
     {
-        return true;
+        $cacheKey = "caches:platform:grant_score";
+        if(RedisService::get($cacheKey.'_lock')){
+            $this->error = 3006;
+            return false;
+        }
+
+        $dayScore = ConfigService::make()->getConfigByCode('xb_day_num',0); // 每日发放
+        $dayScore = $dayScore>0 && $dayScore<=10000000? $dayScore : 0;
+        $xlTotal = ConfigService::make()->getConfigByCode('xl_total',0); // 总发放
+        $xlTotal = $xlTotal? $xlTotal : 0;
+        if($xlTotal<=0 || $dayScore <= 0 || $dayScore > $xlTotal){
+            $this->error = 3007;
+            return false;
+        }
+
+        // 发放用户
+        RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), rand(30,60));
+        $date = date('Y-m-d',strtotime('-1 day'));
+        $model = AccountCountModel::from('account_counts as a')
+            ->leftJoin('member as b','b.id','=','a.user_id')
+            ->leftJoin('member_level as c','c.id','=','b.member_level')
+            ->where(['a.date'=>$date,'a.type'=>1]);
+
+
+        $countModel = clone  $model;
+        $powerDayTotal = $countModel->sum('a.money');
+
+        $settleUsers = $model->where('b.score_grant_at','<',date('Y-m-d'))
+            ->select(['a.user_id','a.type','a.money','b.member_level','b.supper_point','b.score','c.power_multiple'])
+            ->orderBy('a.create_time','asc')
+            ->groupBy('a.user_id')
+            ->limit(rand(200,500))
+            ->get();
+        $settleUsers = $settleUsers? $settleUsers->toArray() : [];
+        if($settleUsers){
+            RedisService::set($cacheKey.'_'.date('YmdHis'), ['power'=> $powerDayTotal,'users'=>$settleUsers], 7200);
+            foreach($settleUsers as $item){
+                $dayPower = isset($item['money'])? $item['money'] : 0;
+                $userId = isset($item['user_id'])? $item['user_id'] : 0;
+                $powerRate = isset($item['power_multiple']) && $item['power_multiple']? $item['power_multiple'] : 1;
+                $userSettleScore = moneyFormat(($dayPower * $powerRate)/$powerDayTotal * $dayScore, 2);
+                if($userSettleScore>0 && $userId>0){
+                    // 节点分红积分奖励
+                    $nodeScore = 0;
+                    $nodeName = '节点会员';
+                    $nodeId = isset($item['supper_point'])? $item['supper_point'] : 0;
+                    if($nodeId>0){
+                        $nodeInfo = MemberNodeService::make()->getNodeInfo($nodeId);
+                        $scoreRate = isset($nodeInfo['score_rate'])? $nodeInfo['score_rate'] : 0;
+                        if($scoreRate>0 && $scoreRate<100){
+                            $nodeName = isset($nodeInfo['name']) && $nodeInfo['name']? $nodeInfo['name'] : '节点会员';
+                            $nodeScore = moneyFormat($userSettleScore * $scoreRate/100, 2);
+                        }
+                    }
+
+
+                    // 结算发放积分
+                    $totalScore = moneyFormat($userSettleScore + $nodeScore,2);
+                    DB::beginTransaction();
+                    $updateData = [
+                        'score'=> DB::raw("score + {$totalScore}"),
+                        'score_grant_at'=> date('Y-m-d H:i:s'),
+                        'update_time'=> time(),
+                    ];
+                    if(!MemberModel::where(['id'=> $userId])->update($updateData)){
+                        DB::rollBack();
+                        $this->error = 3007;
+                        continue;
+                    }
+
+                    // 明细
+                    $userScore = isset($item['score'])? $item['score'] : 0;
+                    $log = [
+                        'user_id' => $userId,
+                        'source_id' => 0,
+                        'source_order_no' => get_order_num('SC'),
+                        'type' => 9,
+                        'coin_type' => 4,
+                        'user_type'=> 1,
+                        'money' => $userSettleScore,
+                        'actual_money' => $userSettleScore,
+                        'balance' => $userScore,
+                        'create_time' => time(),
+                        'update_time' => time(),
+                        'remark' => "每日发放积分",
+                        'status' => 1,
+                        'mark' => 1,
+                    ];
+                    if(!AccountLogModel::insertGetId($log)){
+                        DB::rollBack();
+                        $this->error = 2029;
+                        continue;
+                    }
+
+                    if($nodeScore>0){
+                        $userScore += $userSettleScore;
+                        $log = [
+                            'user_id' => $userId,
+                            'source_id' => 0,
+                            'source_order_no' => get_order_num('SC'),
+                            'type' => 9,
+                            'coin_type' => 4,
+                            'user_type'=> 1,
+                            'money' => $nodeScore,
+                            'actual_money' => $nodeScore,
+                            'balance' => moneyFormat($userScore + $userSettleScore,4),
+                            'create_time' => time(),
+                            'update_time' => time(),
+                            'remark' => "{$nodeName}会员每日积分分红",
+                            'status' => 1,
+                            'mark' => 1,
+                        ];
+                        if(!AccountLogModel::insertGetId($log)){
+                            DB::rollBack();
+                            $this->error = 2029;
+                            continue;
+                        }
+                    }
+
+                    DB::commit();
+                    // 用户消息
+                    $dateTime = date('Y-m-d H:i:s');
+                    $message = "您在{$dateTime}(UTC+8)获得平台每日积分发放已到账:\n发放积分:{$dayScore}\n到账积分:{$userSettleScore}\n发放前:{$userScore}\n节点会员:{$nodeName}\n节点分红:{$nodeScore}";
+                    MessageService::make()->pushMessage($userId, '每日积分发放', $message,3);
+                }
+            }
+
+            RedisService::clear($cacheKey.'_lock');
+        }else{
+            // 结算完
+            RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), 86400);
+        }
+
+        return ['count'=> count($settleUsers),'power'=>$powerDayTotal,'day_score'=>$dayScore,'xl_total'=> $xlTotal];
     }
 
     /**
@@ -464,6 +864,248 @@ class FinanceService extends BaseService
      */
     public function returnWaitScore()
     {
-        return true;
+        $cacheKey = "caches:platform:wait_score";
+        if(RedisService::get($cacheKey.'_lock')){
+            $this->error = 3006;
+            return false;
+        }
+
+        // 每日日返还待返积分数量
+        $scoreToXdRate = ConfigService::make()->getConfigByCode('wait_score_to_xd_rate',10000);
+        $scoreToXdRate = $scoreToXdRate>0 && $scoreToXdRate<1000000? $scoreToXdRate : 10000;
+        $returnScore = ConfigService::make()->getConfigByCode('day_wait_score_num',0);
+        $returnScore = $returnScore>0 && $returnScore<500000? $returnScore : 0;
+        if($returnScore <= 0 || $scoreToXdRate<=0){
+            $this->error = 3009;
+            return false;
+        }
+
+        RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'),rand(30,60));
+        $users = MemberModel::where(['mark'=>1])
+            ->where('wait_score','>',0)
+            ->where('wait_score_return_at','<',date('Y-m-d'))
+            ->select(['id','usdt','score','balance','wait_score'])
+            ->orderBy('create_time','asc')
+            ->limit(rand(200,500))
+            ->get();
+        $users = $users? $users->toArray() : [];
+        if($users){
+            RedisService::set($cacheKey, $users, 86400);
+            foreach($users as $item){
+                $userXd = isset($item['balance'])? $item['balance'] : 0;
+                $waitScore = isset($item['wait_score'])? $item['wait_score'] : 0;
+                $userId = isset($item['id'])? $item['id'] : 0;
+                $settleScore = $waitScore >= $returnScore? $returnScore : $waitScore; // 不足每日返还则还完
+                $settleXd = moneyFormat($settleScore/$scoreToXdRate, 2); // 不足每日返还则还完
+                if($settleScore>0){
+                    DB::beginTransaction();
+                    $updateData = [
+                        'wait_score'=> DB::raw("wait_score - {$settleScore}"),  // 扣除待返积分
+                        'balance'=> DB::raw("balance + {$settleXd}"),  // 返还星豆数量
+                        'wait_score_return_at'=> date('Y-m-d H:i:s'),
+                        'update_time'=> time(),
+                    ];
+                    if(!MemberModel::where(['id'=> $userId])->update($updateData)){
+                        DB::rollBack();
+                        $this->error = 3007;
+                        continue;
+                    }
+
+                    // 待返积分明细
+                    $orderNo = get_order_num('FS');
+                    if($settleScore){
+                        $log = [
+                            'user_id' => $userId,
+                            'source_id' => 0,
+                            'source_order_no' => $orderNo,
+                            'type' => 24,
+                            'coin_type' => 5,
+                            'user_type'=> 1,
+                            'money' => -$settleScore,
+                            'actual_money' => -$settleScore,
+                            'balance' => $waitScore,
+                            'create_time' => time(),
+                            'update_time' => time(),
+                            'remark' => "每日待返积分返还星豆",
+                            'status' => 1,
+                            'mark' => 1,
+                        ];
+                        if(!AccountLogModel::insertGetId($log)){
+                            DB::rollBack();
+                            $this->error = 2029;
+                            continue;
+                        }
+                    }
+
+                    // 星豆明细
+                    if($settleXd){
+                        $log = [
+                            'user_id' => $userId,
+                            'source_id' => 0,
+                            'source_order_no' => $orderNo,
+                            'type' => 24,
+                            'coin_type' => 2,
+                            'user_type'=> 1,
+                            'money' => $settleXd,
+                            'actual_money' => $settleXd,
+                            'balance' => $userXd,
+                            'create_time' => time(),
+                            'update_time' => time(),
+                            'remark' => "每日待返积分返还星豆",
+                            'status' => 1,
+                            'mark' => 1,
+                        ];
+                        if(!AccountLogModel::insertGetId($log)){
+                            DB::rollBack();
+                            $this->error = 2029;
+                            continue;
+                        }
+                    }
+
+                    DB::commit();
+
+                    // 用户消息
+                    $dateTime = date('Y-m-d H:i:s');
+                    $message = "您在{$dateTime}(UTC+8)获得每日积分返还已到账:\n返还积分:{$settleScore}\n返还前:{$waitScore}\n返还星豆:{$settleXd}\n返还前前:{$userXd}\n";
+                    MessageService::make()->pushMessage($userId, '每日积分返还星豆奖励', $message,3);
+                }
+            }
+
+
+            RedisService::clear($cacheKey.'_lock');
+        }else{
+            RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), 86400);
+        }
+
+        return ['count'=> count($users),'return'=> $returnScore];
+    }
+
+    /**
+     * 全球分红
+     * @return bool
+     */
+    public function globalBonus()
+    {
+        $cacheKey = "caches:platform:global_bonus";
+        if(RedisService::get($cacheKey.'_lock')){
+            $this->error = 3006;
+            return false;
+        }
+
+        // 昨日业绩
+        $date = date('Y-m-d', strtotime('-1 day'));
+        $model = AccountCountModel::from('account_counts as a')
+            ->leftJoin('member as b','b.id','=','a.user_id')
+            ->where(['a.date'=>$date,'a.type'=>2]);
+
+
+        $countModel1 = clone  $model;  // 普通节点
+        $countModel2 = clone  $model;  // 超级节点
+        $node1Total = $countModel1->where(['b.supper_point'=>1])->sum('a.money');
+        $node2Total = $countModel2->where(['b.supper_point'=>2])->sum('a.money');
+
+        // 无任何节点业绩
+        if($node1Total <= 0 && $node2Total <= 0){
+            $this->error = 3010;
+            return false;
+        }
+
+        // 结算用户
+        $users = MemberModel::from('member as a')
+            ->leftJoin('member_nodes as b','b.id','=','a.supper_point')
+            ->leftJoin('member_level as c','c.id','=','a.member_level')
+            ->where('a.supper_point','>',0)
+            ->where('a.global_bonus_at','<',date('Y-m-d'))
+            ->where(['a.mark'=>1])
+            ->select(['a.id','a.balance','a.usdt','a.supper_point','a.parent_id','a.member_level','c.global_bonus_rate','b.name'])
+            ->orderBy('a.supper_point','asc')
+            ->orderBy('a.id','asc')
+            ->limit(rand(200,500))
+            ->get();
+
+        $users = $users? $users->toArray() : [];
+        $success = 0;
+        if($users) {
+            RedisService::set($cacheKey, $users, 86400);
+            foreach ($users as $item){
+                $userUsdt = isset($item['usdt'])? $item['usdt'] : 0;
+                $userId = isset($item['id'])? $item['id'] : 0;
+                $userSupperPoint = isset($item['supper_point'])? $item['supper_point'] : 0;
+                $bonusRate = isset($item['global_bonus_rate'])? $item['global_bonus_rate'] : 0;
+                if($bonusRate<=0 || $bonusRate>=100 || $userSupperPoint<=0){
+                    continue;
+                }
+
+                // 个人昨日业绩
+                $userPerformance = AccountLogService::make()->getTotal($userId, $date,2);
+                // 团队昨日业绩
+                $teamPerformance = AccountLogService::make()->getTeamTotal($userId, $date,2);
+
+                // 普通节点
+                $nodeTotal = 0;
+                if($userSupperPoint==1){
+                    $nodeTotal = $node1Total;
+                }
+                // 超级节点
+                else if($userSupperPoint == 2){
+                    $nodeTotal = $node2Total;
+                }
+
+                $bonusUsdt = moneyFormat(($teamPerformance/$nodeTotal) * $bonusRate/100,4);
+                if($bonusUsdt>0){
+                    DB::beginTransaction();
+                    $updateData = [
+                        'usdt'=> DB::raw("usdt + {$bonusUsdt}"),  // 奖励USDT
+                        'global_bonus_at'=> date('Y-m-d H:i:s'),
+                        'update_time'=> time(),
+                    ];
+                    if(!MemberModel::where(['id'=> $userId])->update($updateData)){
+                        DB::rollBack();
+                        $this->error = 3007;
+                        continue;
+                    }
+
+                    // 待返积分明细
+                    $orderNo = get_order_num('GU');
+                    $log = [
+                        'user_id' => $userId,
+                        'source_id' => 0,
+                        'source_order_no' => $orderNo,
+                        'type' => 15,
+                        'coin_type' => 5,
+                        'user_type'=> 1,
+                        'money' => $bonusUsdt,
+                        'actual_money' => $bonusUsdt,
+                        'balance' => $userUsdt,
+                        'create_time' => time(),
+                        'update_time' => time(),
+                        'remark' => "全球分红奖励",
+                        'status' => 1,
+                        'mark' => 1,
+                    ];
+                    if(!AccountLogModel::insertGetId($log)){
+                        DB::rollBack();
+                        $this->error = 2029;
+                        continue;
+                    }
+
+                    // 平台财务
+                    FinanceService::make()->saveLog(0,$bonusUsdt,2);
+
+                    // 用户消息
+                    $dateTime = date('Y-m-d H:i:s');
+                    $nodeName = isset($item['name'])? $item['name'] :'';
+                    $message = "您在{$dateTime}(UTC+8)获得全球分红奖励已到账:\n奖励金额:{$bonusUsdt}\n奖励前:{$userUsdt}\n节点类型:{$nodeName}\n个人算力:{$userPerformance}\n团队算力:{$teamPerformance}\n节点算力:{$nodeTotal}";
+                    MessageService::make()->pushMessage($userId, '全球分红奖励', $message,3);
+
+                }
+
+            }
+
+            RedisService::clear($cacheKey.'_lock');
+        }else{
+            RedisService::set($cacheKey.'_lock', date('Y-m-d H:i:s'), 86400);
+        }
+        return ['count'=>count($users),'success'=> $success];
     }
 }

+ 30 - 0
app/Services/Api/MemberNodeService.php

@@ -274,6 +274,12 @@ class MemberNodeService extends BaseService
 
         DB::commit();
 
+        // 算力统计
+        AccountLogService::make()->saveCount($userId, $powerNum, 1);
+
+        // 业绩统计
+        AccountLogService::make()->saveCount($userId, $price, 2);
+
         // 结算收益奖励
         FinanceService::make()->settleBonus($userId, $userInfo, $price, $orderNo, "购买{$nodeName}");
 
@@ -282,4 +288,28 @@ class MemberNodeService extends BaseService
         return true;
     }
 
+
+    /**
+     * 节点详情信息
+     * @param $nodeId 节点ID
+     * @return array|mixed
+     */
+    public function getNodeInfo($nodeId)
+    {
+        $cacheKey = "caches:nodes:info:{$nodeId}";
+        $data = RedisService::get($cacheKey);
+        if($data){
+            return $data;
+        }
+
+        $data = $this->model->where(['id'=>$nodeId,'mark'=>1,'status'=>1])
+            ->select(['id','name','price','score_rate','box_num'])
+            ->first();
+        $data = $data?$data->toArray() : [];
+        if($data){
+            RedisService::set($cacheKey, $data, rand(3600,7200));
+        }
+
+        return $data;
+    }
 }

+ 6 - 0
app/Services/Api/MemberService.php

@@ -1748,6 +1748,12 @@ class MemberService extends BaseService
 
         DB::commit();
 
+        // 算力统计
+        AccountLogService::make()->saveCount($userId, $powerNum, 1);
+
+        // 业绩统计
+        AccountLogService::make()->saveCount($userId, $upgradeUsdt, 2);
+
         // 结算收益奖励
         FinanceService::make()->settleBonus($userId, $userInfo, $upgradeUsdt, $orderNo, "购买{$levelName}");
 

+ 105 - 216
app/Services/Api/OrderService.php

@@ -432,7 +432,7 @@ class OrderService extends BaseService
             case 10: // 星豆余额支付
                 // 扣除余额
                 $updateData = [
-                    'usdt'=> DB::raw("usdt - {$payTotal}"), // 扣除USDT
+                    'balance'=> DB::raw("balance - {$payTotal}"), // 扣除星豆
                     'update_time'=>time()
                 ];
                 if(!MemberModel::where(['id'=> $userId])->update($updateData)){
@@ -1241,41 +1241,42 @@ class OrderService extends BaseService
     public function complete($userId, $params)
     {
         $id = isset($params['id']) ? $params['id'] : 0;
-        $merchId = isset($params['merch_id']) ? $params['merch_id'] : 0;
         $info = $this->model->with(['goods'])
             ->where(['id' => $id, 'mark' => 1])
-            ->select(['id','user_id','order_no','merch_id','source_id','city','pay_money','type','postage','reception_at','coupon_id','status','is_service','refund_status','pay_time'])
+            ->select(['id','user_id','order_no','out_order_no','merch_uid','xd_total','pay_money','type','postage','reception_at','coupon_id','status','refund_status','pay_time'])
             ->first();
         $status = isset($info['status']) ? $info['status'] : 0;
         $orderUserId = isset($info['user_id']) ? $info['user_id'] : 0;
-        $orderMerchId = isset($info['merch_id']) ? $info['merch_id'] : 0;
-        $orderMechId = isset($info['source_id']) ? $info['source_id'] : 0;
-        $orderType = isset($info['type']) ? $info['type'] : 0;
-        $payMoney = isset($info['pay_money']) ? $info['pay_money'] : 0;
+        $orderNo = isset($info['order_no']) ? $info['order_no'] : '';
         $goods = isset($info['goods'])? $info['goods'] : [];
         if (!$id || empty($info)) {
-            $this->error = 2636;
+            $this->error = 2912;
             return false;
         }
 
-        var_dump($info);
-        return  false;
-
         // 非法操作
-        if($userId && $merchId != $orderMerchId && $orderUserId != $userId){
-            $this->error = 2667;
+        if($userId && $orderUserId != $userId){
+            $this->error = 2913;
             return false;
         }
 
         // 订单状态
-        if (($userId && $status != 3)||(!$userId && !in_array($status,[2,3]))) {
-            $this->error = 2668;
+        if (!in_array($status, [2,3,5])) {
+            $this->error = 2914;
             return false;
         }
 
-        // 限制操作订单类型
-        if(!in_array($orderType, [1,2,6])){
-            $this->error = 2681;
+        $realXdTotal = 0;
+        $hasGoods = false;
+        foreach($goods as $item){
+            if(!in_array($item['refund_status'],[3])){
+                $hasGoods = true;
+                $realXdTotal += $item['xd_total'];
+            }
+        }
+
+        if(!$hasGoods || $realXdTotal <=0){
+            $this->error = 2931;
             return false;
         }
 
@@ -1285,7 +1286,7 @@ class OrderService extends BaseService
         // 更新订单状态
         if (!$this->model->where(['id' => $id])->update(['status' => 4, 'update_time' => time()])) {
             DB::rollBack();
-            $this->error = 2678;
+            $this->error = 2932;
             return false;
         }
 
@@ -1294,211 +1295,22 @@ class OrderService extends BaseService
             foreach($goods as $item){
                 $num = isset($item['num'])? $item['num'] : 0;
                 if($num>0){
-                    GoodsModel::where(['id'=> $item['goods_id'],'mark'=>1])->update([
+                    GoodsModel::where(['goods_id'=> $item['goods_id'],'mark'=>1])->update([
                         'sales'=> DB::raw("sales + {$num}"),'update_time'=> time()
                     ]);
                 }
-
             }
         }
 
-        // 服务订单统计处理
-        if($orderType == 2){
-            // 更新技师服务订单,接单统计数据
-            $serviceCount = $this->model->where(['user_id'=> $orderUserId,'source_id'=> $orderMechId,'type'=>2,'status'=>4,'mark'=>1])->count('id');
-            $updateData = ['order_total'=> DB::raw("order_total + 1"),'update_time'=>time()];
-            if($serviceCount<=1){
-                $updateData['service_num'] =  DB::raw("service_num + 1");
-            }
-            if($orderMechId && !MechanicModel::where(['id'=>$orderMechId,'mark'=> 1])->update($updateData)){
-                DB::rollBack();
-                $this->error = 2682;
-                return false;
-            }
-
-            // 更新商家服务订单,统计数据
-            $updateData = ['service_order_num'=> DB::raw("service_order_num + 1"),'service_order_total'=> DB::raw("service_order_total + {$payMoney}"),'update_time'=>time()];
-            if($orderMechId && !MerchantModel::where(['id'=>$orderMerchId,'mark'=> 1])->update($updateData)){
-                DB::rollBack();
-                $this->error = 2682;
-                return false;
-            }
-        }
-
-        // 店内订单结算
-        $balance = MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->value('balance');
-        if ($orderType == 6){
-            // 商家入账
-            $settleRate = ConfigService::make()->getConfigByCode('merch_settle_rate');
-            $settleRate = $settleRate>0? min(100, $settleRate) : 100;
-            $settleMoney = moneyFormat($payMoney * $settleRate/100, 2);
-            $updateData = ['balance'=> DB::raw("balance + {$settleMoney}"),'update_time'=>time()];
-            if($settleMoney>0 && !MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->update($updateData)){
-                DB::rollBack();
-                $this->error = 2683;
-                return false;
-            }
-
-            // 流水记录
-            $log = [
-                'user_id'=> 0,
-                'merch_id'=> $orderMerchId,
-                'source_uid'=> $orderUserId,
-                'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'',
-                'type'=> 3,
-                'coin_type'=> 2,
-                'user_type'=> 2,
-                'money'=> $settleMoney,
-                'balance'=>$balance? $balance : 0.00,
-                'create_time'=> time(),
-                'update_time'=> time(),
-                'remark'=> '商家店内订单收入',
-                'status'=>1,
-                'mark'=>1
-            ];
-            if(!AccountLogModel::insertGetId($log)){
-                DB::rollBack();
-                $this->error = 2641;
-                return false;
-            }
-
-            // 平台抽成入账,财务统计
-            $financeMoney = floatval($payMoney - $settleMoney);
-            if($financeMoney>0){
-                $log = [
-                    'user_id'=> 0,
-                    'merch_id'=> 0,
-                    'source_uid'=> $orderUserId,
-                    'source_order_no'=> $info['order_no'],
-                    'type'=> 13,
-                    'coin_type'=> 2,
-                    'user_type'=> 5,
-                    'money'=> $financeMoney,
-                    'balance'=> 0,
-                    'create_time'=> time(),
-                    'update_time'=> time(),
-                    'remark'=> '平台店内订单收入',
-                    'status'=>1,
-                    'mark'=>1
-                ];
-                if(!AccountLogModel::insertGetId($log)){
-                    DB::rollBack();
-                    $this->error = 2641;
-                    return false;
-                }
-                FinanceService::make()->saveLog(0,$financeMoney, 1, 1);
-            }
-        }
-
-        // 服务订单结算
-        else if(in_array($orderType, [1,2])){
-
-            // 计算服务订单分销佣金和代理佣金
-            if(!$result = FinanceService::make()->settleOrder($info, $userId)){
-                DB::rollBack();
-                $this->error = FinanceService::make()->getError();
-                return false;
-            }
-
-            // 商家入账
-            $settleMoney = isset($result['merch_money'])? $result['merch_money'] : 0;
-            $updateData = [
-                'balance'=> DB::raw("balance + {$settleMoney}"),
-                'service_order_num'=>DB::raw("service_order_num + 1"),
-                'service_order_total'=>DB::raw("service_order_total + {$payMoney}"),
-                'update_time'=>time()
-            ];
-            if($settleMoney>0 && !MerchantModel::where(['id'=> $orderMerchId,'mark'=>1])->update($updateData)){
-                DB::rollBack();
-                $this->error = 2683;
-                return false;
-            }
-
-            $log = [
-                'user_id'=> 0,
-                'merch_id'=> $orderMerchId,
-                'source_uid'=> $orderUserId,
-                'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'',
-                'type'=> 3,
-                'coin_type'=> 2,
-                'user_type'=> 2,
-                'money'=> $settleMoney,
-                'balance'=>$balance? $balance : 0.00,
-                'create_time'=> time(),
-                'update_time'=> time(),
-                'remark'=> '商家订单收入',
-                'status'=>1,
-                'mark'=>1
-            ];
-            if(!AccountLogModel::insertGetId($log)){
-                DB::rollBack();
-                $this->error = 2641;
-                return false;
-            }
-
-            // 平台入账,财务统计
-            $financeMoney = isset($result['platform_money'])? $result['platform_money'] : 0;
-            if($financeMoney>0){
-                FinanceService::make()->saveLog(0,$financeMoney, 1, 1);
-            }
-
-            $log = [
-                'user_id'=> 0,
-                'merch_id'=> 0,
-                'source_uid'=> $orderUserId,
-                'source_order_no'=> isset($info['order_no'])? $info['order_no'] :'',
-                'type'=> 13,
-                'coin_type'=> 2,
-                'user_type'=> 5,
-                'money'=> $financeMoney,
-                'balance'=> 0,
-                'create_time'=> time(),
-                'update_time'=> time(),
-                'remark'=> '平台订单收入',
-                'status'=>1,
-                'mark'=>1
-            ];
-            if(!AccountLogModel::insertGetId($log)){
-                DB::rollBack();
-                $this->error = 2641;
-                return false;
-            }
-
-            // 技师累计
-            if($orderMechId){
-                $updateData = [
-                    'order_total'=> DB::raw("order_total + 1"),
-                    'service_num'=>DB::raw("service_num + 1"),
-                    'update_time'=>time()
-                ];
-                MechanicModel::where(['id'=> $orderMechId,'mark'=>1])->update($updateData);
-            }
-        }
+        // 完成订单消息
+        $dateTime = date('Y-m-d H:i:s');
+        $message = "您在{$dateTime}(UTC+8)成功完成购物订单【{$orderNo}】交易。";
+        MessageService::make()->pushMessage($orderUserId,"订单交易完成",$message, 2);
 
-        // 消息推送
-        $params = [
-            'title' => "订单完成通知",
-            'body' => "您的订单已完成,请即时查看进度并给予评论",
-            'type' => 2, // 1-公告通知,2-订单通知,3-交易通知,4-其他
-            'content' => [
-                'order_no' => ['name' => '订单号', 'text' => $info['order_no']],
-                'time' => ['name' => '下单时间', 'text' => $info['pay_time']],
-                'picker_time' => ['name' => '确认时间', 'text' => date('Y-m-d H:i:s')],
-                'mechanic' => [],
-                'money' => ['name' => '订单金额', 'text' => $info['pay_money']],
-                'status' => ['name' => '状态', 'text' => '已完成'],
-            ],
-            'click_type' => 'payload',
-            'url' => '/pages/order/detail?id=' . $id,
-        ];
-        $mechanic = isset($info['mechanic'])? $info['mechanic'] : [];
-        $code = isset($mechanic['code'])? $mechanic['code'] : '';
-        if($code){
-            $params['content']['mechanic'] = ['name' => '服务技师', 'text' => "{$code}号技师"];
-        }
-        if(!PushService::make()->pushMessageByUser($info['user_id'], $params, 0)){
+        // 订单结算奖励和佣金
+        if(!$result = FinanceService::make()->settleOrder($info, $realXdTotal)){
             DB::rollBack();
-            $this->error = PushService::make()->getError();
+            $this->error = FinanceService::make()->getError();
             return false;
         }
 
@@ -1607,4 +1419,81 @@ class OrderService extends BaseService
             return false;
         }
     }
+
+    /**
+     * 更新订单状态
+     * @return array|false
+     */
+    public function updateOrderStatus()
+    {
+        set_time_limit(0);
+        $cacheKey = "cache:orders:update_lock";
+        if(RedisService::get($cacheKey)){
+            $this->error = 3001;
+            return false;
+        }
+
+        $page = RedisService::get('caches:orders:update_page');
+        $page = $page? $page+1 : 1;
+        $catchNum = ConfigService::make()->getConfigByCode('update_order_num',100);
+        $pageSize = $catchNum>10 && $catchNum<=200? $catchNum : 100;
+        $orders = $this->model->whereIn('status',[2,3])
+            ->where(['mark'=>1])
+            ->select(['id','user_id',''])
+            ->orderBy('pay_time','asc')
+            ->offset(($page-1)*$pageSize)
+            ->limit($pageSize)
+            ->get();
+        $orders = $orders? $orders->toArray() : [];
+        RedisService::set($cacheKey, $orders, rand(30,60));
+        $success = 0;
+        $deliverCount = 0;
+        if($orders){
+            foreach ($orders as $item){
+                $orderId = isset($item['id'])? $item['id'] : 0;
+                $orderNo = isset($item['order_no'])? $item['order_no'] : '';
+                $outOrderNo = isset($item['out_order_no'])? $item['out_order_no'] : '';
+
+                if(empty($orderNo) || empty($outOrderNo)){
+                    continue;
+                }
+                $lockCacheKey = "caches:orders:update:{$orderNo}_{$outOrderNo}";
+                if(RedisService::get($lockCacheKey.'_lock')){
+                    continue;
+                }
+
+                $data = [
+                    'out_order_no'=> $outOrderNo,
+                    'third_order_no'=> $orderNo,
+                ];
+                $result = SupplyService::make()->getApiData('getOrderDetail', $data);
+                if(empty($result)){
+                    RedisService::clear($lockCacheKey.'_lock');
+                    continue;
+                }
+
+                $orderStatus = isset($result['status'])? $result['status'] : 0;
+                $deliveryTime = isset($result['delivery_time']) && $result['delivery_time']? strtotime($result['delivery_time']) : time();
+                $supplyOrderNo = isset($result['supply_order_no']) && $result['supply_order_no']? $result['supply_order_no'] : '';
+                // 已发货,待收货
+                if($orderStatus == 3){
+                    if($this->model->where(['order_no'=> $orderNo])->update(['supply_order_no'=>$supplyOrderNo,'express_time'=> $deliveryTime,'status'=>3,'update_time'=>time()])){
+                        $deliverCount++;
+                    }
+                }
+                // 已完成
+                else if(in_array($orderStatus,[4,7]))
+                {
+                    if($this->complete(0,['order_id'=> $orderId,'supply_order_no'=>$supplyOrderNo])){
+                        $success++;
+                    }
+                }
+
+                RedisService::clear($lockCacheKey.'_lock');
+            }
+        }
+
+        RedisService::clear($cacheKey);
+        return ['count'=> count($orders),'success'=> $success, 'delivery'=>$deliverCount];
+    }
 }

+ 5 - 6
app/Services/LiveService.php

@@ -19,6 +19,7 @@ use App\Models\LiveModel;
 use App\Models\MemberModel;
 use App\Models\RewardOrderModel;
 use App\Models\VideoCollectModel;
+use App\Services\Api\AccountLogService;
 use App\Services\Api\MemberCollectService;
 use App\Services\Api\MessageService;
 use App\Services\Api\TaskService;
@@ -905,7 +906,7 @@ class LiveService extends BaseService
             'user_type'=> 1,
             'type'=>1,
             'coin_type'=> 2,
-            'money'=> -$usdt,
+            'money'=> -$money,
             'date'=> date('Y-m-d'),
             'actual_money'=> -$money,
             'balance'=> $balance,
@@ -1046,14 +1047,12 @@ class LiveService extends BaseService
             return false;
         }
 
-
-
-
         DB::commit();
 
         // TODO 推送站内消息
-        MessageService::make()->pushMessage($userId, lang('打赏消费通知'), lang('打赏消费通知内容',['time'=> $dateTime,'money'=>$money,'live_name'=>$liveName]),3);
-        MessageService::make()->pushMessage($liveUserId, lang('打赏通知'), lang('打赏通知内容',['time'=> $dateTime,'money'=>$money,'nickname'=>$userNickname]),3);
+        MessageService::make()->pushMessage($userId, web_lang('打赏消费通知'), web_lang('打赏消费通知内容',['time'=> $dateTime,'money'=>$money,'live_name'=>$liveName]),3);
+        MessageService::make()->pushMessage($liveUserId, web_lang('打赏通知'), web_lang('打赏通知内容',['time'=> $dateTime,'money'=>$money,'nickname'=>$userNickname]),3);
+
 
         // TODO 打赏直播任务
         if($userId != $liveUserId){

+ 14 - 0
resources/lang/zh-cn/api.php

@@ -206,6 +206,20 @@ return [
     '2928'=> '无可取消售后的商品',
     '2929'=> '取消售后失败,请返回重试或联系客服',
     '2930'=> '取消售后成功',
+    '2931'=> '订单不可操作完成,请检查是否已售后处理完成',
+    '2932'=> '订单更新失败',
+
+
+    '3001'=> '订单更新处理中',
+    '3002'=> '订单结算中',
+    '3003'=> '订单结算用户不存在',
+    '3004'=> '订单结算金额错误',
+    '3005'=> '没有奖励可结算',
+    '3006'=> '没到时间发放',
+    '3007'=> '每日积分发放参数设置错误',
+    '3008'=> '积分账户结算失败',
+    '3009'=> '待返积分返还参数错误',
+    '3010'=> '没有可结算的金额',
 
 
     '112009'=> '供应商账户余额不足,请联系客服',