524 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			524 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						||
 | 
						||
namespace app\common\model\school\activity\order;
 | 
						||
 | 
						||
use app\common\model\BaseModel;
 | 
						||
use app\common\model\school\activity\Activity;
 | 
						||
use app\common\model\user\withdrawal\UserwithdrawalLog;
 | 
						||
use think\Model;
 | 
						||
use traits\model\SoftDelete;
 | 
						||
 | 
						||
class SettleLog extends BaseModel
 | 
						||
{
 | 
						||
 | 
						||
    use SoftDelete;
 | 
						||
 | 
						||
    
 | 
						||
 | 
						||
    // 表名
 | 
						||
    protected $name = 'school_activity_settle_log';
 | 
						||
    
 | 
						||
    // 自动写入时间戳字段
 | 
						||
    protected $autoWriteTimestamp = 'integer';
 | 
						||
 | 
						||
    // 定义时间戳字段名
 | 
						||
    protected $createTime = 'createtime';
 | 
						||
    protected $updateTime = false;
 | 
						||
    protected $deleteTime = 'deletetime';
 | 
						||
 | 
						||
    // 追加属性
 | 
						||
    protected $append = [
 | 
						||
        'status_text',
 | 
						||
        'settletime_text',
 | 
						||
        'canceltime_text',
 | 
						||
        'unfreezetime_text'
 | 
						||
    ];
 | 
						||
    
 | 
						||
 | 
						||
    
 | 
						||
    public function getStatusList()
 | 
						||
    {
 | 
						||
        return ['1' => __('Status 1'), '2' => __('Status 2'), '3' => __('Status 3'), '-1' => __('Status -1')];
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function getStatusTextAttr($value, $data)
 | 
						||
    {
 | 
						||
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
 | 
						||
        $list = $this->getStatusList();
 | 
						||
        return isset($list[$value]) ? $list[$value] : '';
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function getSettletimeTextAttr($value, $data)
 | 
						||
    {
 | 
						||
        $value = $value ? $value : (isset($data['settletime']) ? $data['settletime'] : '');
 | 
						||
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function getCanceltimeTextAttr($value, $data)
 | 
						||
    {
 | 
						||
        $value = $value ? $value : (isset($data['canceltime']) ? $data['canceltime'] : '');
 | 
						||
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function getUnfreezetimeTextAttr($value, $data)
 | 
						||
    {
 | 
						||
        $value = $value ? $value : (isset($data['unfreezetime']) ? $data['unfreezetime'] : '');
 | 
						||
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
 | 
						||
    }
 | 
						||
 | 
						||
    protected function setSettletimeAttr($value)
 | 
						||
    {
 | 
						||
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
 | 
						||
    }
 | 
						||
 | 
						||
    protected function setCanceltimeAttr($value)
 | 
						||
    {
 | 
						||
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
 | 
						||
    }
 | 
						||
 | 
						||
    protected function setUnfreezetimeAttr($value)
 | 
						||
    {
 | 
						||
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function order()
 | 
						||
    {
 | 
						||
        return $this->belongsTo(Order::class, 'activity_order_id', 'id', [], 'LEFT')->setEagerlyType(0);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function log()
 | 
						||
    {
 | 
						||
        return $this->belongsTo(UserwithdrawalLog::class, 'withdrawal_log_id', 'id', [], 'LEFT')->setEagerlyType(0);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function touser()
 | 
						||
    {
 | 
						||
        return $this->belongsTo('app\common\model\User', 'to_user_id', 'id', [], 'LEFT')->setEagerlyType(0);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public function payuser()
 | 
						||
    {
 | 
						||
        return $this->belongsTo('app\common\model\User', 'pay_user_id', 'id', [], 'LEFT')->setEagerlyType(0);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    public function activity()
 | 
						||
    {
 | 
						||
        return $this->belongsTo(Activity::class, 'activity_id', 'id', [], 'LEFT')->setEagerlyType(0);
 | 
						||
    }
 | 
						||
 | 
						||
    public function detail()
 | 
						||
    {
 | 
						||
        return $this->belongsTo(OrderDetail::class, 'activity_order_detail_id', 'id', [], 'LEFT')->setEagerlyType(0);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 检测订单结算
 | 
						||
     */
 | 
						||
    public static function timeoutSettleActivityCheck($activity_id,$trans = false){
 | 
						||
        $count = 0;
 | 
						||
        if ($trans) {
 | 
						||
            self::beginTrans();
 | 
						||
        }
 | 
						||
        try {
 | 
						||
 | 
						||
            $orders = Order::where("payprice",">",0) //支付单
 | 
						||
                ->where("pay_type",'wechat')  //微信支付
 | 
						||
                ->where("sub_refundprice",">",0)  //剩余未退大于0
 | 
						||
                ->where("activity_id",$activity_id) //当前活动
 | 
						||
                ->where("status","in",["-3","9","6"])
 | 
						||
                ->select();
 | 
						||
            foreach ($orders as $order){
 | 
						||
                //剩余金额大于手续费的订单,并且未插入此结算单的
 | 
						||
                $sub_refundprice = bcsub($order["sub_refundprice"],$order["fee_price"],2);
 | 
						||
                if($sub_refundprice >= 0.01){
 | 
						||
                   $log = self::where("activity_order_id",$order["id"])->where("status","not in",["-1"])->find();
 | 
						||
                   if(!$log){
 | 
						||
                       (new self)->generatorLog($order["id"]);
 | 
						||
                   }
 | 
						||
                }
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            if ($trans) {
 | 
						||
                self::commitTrans();
 | 
						||
            }
 | 
						||
        } catch (\Exception $e) {
 | 
						||
            if ($trans) {
 | 
						||
                self::rollbackTrans();
 | 
						||
            }
 | 
						||
            throw new \Exception($e->getMessage());
 | 
						||
        }
 | 
						||
        return $count;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 检测订单结算
 | 
						||
     */
 | 
						||
    public  function timeoutSettleCheck($trans = false){
 | 
						||
        $count = 0;
 | 
						||
 | 
						||
        if ($trans) {
 | 
						||
            self::beginTrans();
 | 
						||
        }
 | 
						||
        try {
 | 
						||
            //查询更新所有活动状态
 | 
						||
            Activity::timeoutCheck();
 | 
						||
 | 
						||
            //执行售后单挂起操作
 | 
						||
            (new order)->timeoutSuspension();
 | 
						||
 | 
						||
            //延后时间(秒)
 | 
						||
            $delay = config("site.activity_end_settle") ?: 0;
 | 
						||
            $time = time();
 | 
						||
            //查询处于可结算状态的订单(活动结束时间戳 , 延后时间  =超时可以结算的活动)
 | 
						||
            $time = $time - $delay;
 | 
						||
            $activityList = Activity::where("status",'5')->where("end_time",'<',$time)->select();
 | 
						||
            foreach ($activityList as $activity){
 | 
						||
                //对活动订单进行结算记录插入
 | 
						||
                $this->timeoutSettleActivityCheck($activity["id"]);
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            //检测更新所有结算订状态
 | 
						||
            SettleLog::timeoutCheck(null,null);
 | 
						||
            //检测活动状态
 | 
						||
            (new Activity)->updateSettleStatus();
 | 
						||
 | 
						||
            if ($trans) {
 | 
						||
                self::commitTrans();
 | 
						||
            }
 | 
						||
        } catch (\Exception $e) {
 | 
						||
            if ($trans) {
 | 
						||
                self::rollbackTrans();
 | 
						||
            }
 | 
						||
            throw new \Exception($e->getMessage());
 | 
						||
        }
 | 
						||
        return $count;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /** 生成结算记录
 | 
						||
     * @param $order_id
 | 
						||
     * @param $trans
 | 
						||
     * @return true
 | 
						||
     * @throws \Exception
 | 
						||
     */
 | 
						||
    public function generatorLog($order_id,$trans=false){
 | 
						||
        $order = Order::where("id" ,$order_id)->find();
 | 
						||
        if(!$order) return false;
 | 
						||
        //免费的忽略
 | 
						||
        if($order->payprice <= 0) return false;
 | 
						||
        $detail = $order->detail;
 | 
						||
        if(!$detail) return false;
 | 
						||
        $data = [
 | 
						||
            "activity_order_id" => $order_id,
 | 
						||
            "withdrawal_log_id" =>0,
 | 
						||
            "to_user_id" => $detail->user_id,
 | 
						||
            "pay_user_id" => $order->user_id,
 | 
						||
            "status" =>'1',
 | 
						||
            "unfreezetime" => $detail->settlement_time,
 | 
						||
            "order_price" => $order->payprice,
 | 
						||
            "sub_refundprice" =>$order->sub_refundprice,
 | 
						||
            "fee_scale" => $order->fee_scale,
 | 
						||
            "fee_price" => $order->fee_price,
 | 
						||
            "settle_price" => bcsub($order->sub_refundprice,$order->fee_price,2),
 | 
						||
            "activity_id" => $order->activity_id,
 | 
						||
            "activity_order_detail_id" => $detail->id,
 | 
						||
        ];
 | 
						||
        if($data["settle_price"] < 0.01) return false;
 | 
						||
//判断逻辑
 | 
						||
        if($trans){
 | 
						||
            self::beginTrans();
 | 
						||
        }
 | 
						||
        $res = true;
 | 
						||
        try{
 | 
						||
            $res =self::where([
 | 
						||
                "activity_order_id" => $order_id,
 | 
						||
                "status" =>'1',
 | 
						||
                "to_user_id" => $detail->user_id,
 | 
						||
            ])->find();
 | 
						||
            //保存
 | 
						||
            if(!$res)$res = self::create($data);
 | 
						||
            //记录状态检测
 | 
						||
            $this->settleCheck($res["id"]);
 | 
						||
 | 
						||
            if($trans){
 | 
						||
                self::commitTrans();
 | 
						||
            }
 | 
						||
        }catch (\Exception $e){
 | 
						||
            if($trans){
 | 
						||
                self::rollbackTrans();
 | 
						||
            }
 | 
						||
            throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
 | 
						||
        }
 | 
						||
        return $res;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /** 结算冻结状态更新
 | 
						||
     * @param $log_id
 | 
						||
     * @param $trans
 | 
						||
     * @return true
 | 
						||
     * @throws \Exception
 | 
						||
     */
 | 
						||
    public function settleCheck($log,$trans=false){
 | 
						||
        if(is_string($log)||is_numeric($log))$log = self::where("id" ,$log)->where("status",'1')->find();
 | 
						||
        if(!$log) return false;
 | 
						||
//判断逻辑
 | 
						||
        if($trans){
 | 
						||
            self::beginTrans();
 | 
						||
        }
 | 
						||
        $res = true;
 | 
						||
        try{
 | 
						||
            $time = time();
 | 
						||
            if($log->unfreezetime < $time){
 | 
						||
                //更新状态
 | 
						||
                $res = self::where("id" ,$log["id"])->update(["status" =>'2']);
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            if($trans){
 | 
						||
                self::commitTrans();
 | 
						||
            }
 | 
						||
        }catch (\Exception $e){
 | 
						||
            if($trans){
 | 
						||
                self::rollbackTrans();
 | 
						||
            }
 | 
						||
            throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
 | 
						||
        }
 | 
						||
        return $res;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 超时检测
 | 
						||
     */
 | 
						||
    public static function timeoutCheck($activity_order_id=null,$to_user_id=null,$trans = false){
 | 
						||
        $count = 0;
 | 
						||
        $model = self::where("status",'1');
 | 
						||
        if($activity_order_id)$model = $model->where("activity_order_id",$activity_order_id);
 | 
						||
        if($to_user_id)$model = $model->where("to_user_id",$to_user_id);
 | 
						||
        //得到所有过期的队列
 | 
						||
        $list = $model->select();
 | 
						||
 | 
						||
        if ($trans) {
 | 
						||
            self::beginTrans();
 | 
						||
        }
 | 
						||
        try {
 | 
						||
 | 
						||
            foreach ($list as $log)
 | 
						||
            {
 | 
						||
                //更新结算状态
 | 
						||
                (new self)->settleCheck($log,$trans=false);
 | 
						||
                $count++;
 | 
						||
            }
 | 
						||
            if ($trans) {
 | 
						||
                self::commitTrans();
 | 
						||
            }
 | 
						||
        } catch (\Exception $e) {
 | 
						||
            if ($trans) {
 | 
						||
                self::rollbackTrans();
 | 
						||
            }
 | 
						||
            throw new \Exception($e->getMessage());
 | 
						||
        }
 | 
						||
        return $count;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 批量关闭
 | 
						||
     */
 | 
						||
    public static function allClose($activity_order_id=null,$to_user_id=null,$trans = false){
 | 
						||
        $count = 0;
 | 
						||
        $model = self::where("status",'2');
 | 
						||
        if($activity_order_id)$model = $model->where("activity_order_id",$activity_order_id);
 | 
						||
        if($to_user_id)$model = $model->where("to_user_id",$to_user_id);
 | 
						||
        //得到所有过期的队列
 | 
						||
        $list = $model->select();
 | 
						||
 | 
						||
        if ($trans) {
 | 
						||
            self::beginTrans();
 | 
						||
        }
 | 
						||
        try {
 | 
						||
 | 
						||
            foreach ($list as $log)
 | 
						||
            {
 | 
						||
 | 
						||
                $log["status"] = "-1";
 | 
						||
                $log["canceltime"] = time();
 | 
						||
                $log->save();
 | 
						||
                $count++;
 | 
						||
            }
 | 
						||
            if ($trans) {
 | 
						||
                self::commitTrans();
 | 
						||
            }
 | 
						||
        } catch (\Exception $e) {
 | 
						||
            if ($trans) {
 | 
						||
                self::rollbackTrans();
 | 
						||
            }
 | 
						||
            throw new \Exception($e->getMessage());
 | 
						||
        }
 | 
						||
        return $count;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /** 获取用户结算信息
 | 
						||
     * @param $user_id
 | 
						||
     */
 | 
						||
    public static function getUserSettleInfo($user_id = 0)
 | 
						||
    {
 | 
						||
        //统计未入账未提现金额
 | 
						||
//        $expected_incoming_amount = 0.00;
 | 
						||
//
 | 
						||
//        $orders = Order::where("payprice",">",0) //支付单
 | 
						||
//        ->where("pay_type",'wechat')  //微信支付
 | 
						||
//        ->where("sub_refundprice",">",0)  //剩余未退大于0
 | 
						||
//        ->where("user_id",$user_id) //当前活动
 | 
						||
//        ->where("status","in",["-3","2","3","9","6"])
 | 
						||
//        ->field("sub_refundprice,fee_price")
 | 
						||
//            ->select();
 | 
						||
//        foreach ($orders as $order){
 | 
						||
//            //剩余金额大于手续费的订单,并且未插入此结算单的
 | 
						||
//            $sub_refundprice = bcsub($order["sub_refundprice"],$order["fee_price"],2);
 | 
						||
//            if($sub_refundprice > 0){
 | 
						||
//                $expected_incoming_amount += $sub_refundprice;
 | 
						||
//            }
 | 
						||
//
 | 
						||
//        }
 | 
						||
 | 
						||
        $expected_incoming_amount = self::where("to_user_id",$user_id)->where("status",'1')->sum("settle_price");
 | 
						||
 | 
						||
        //统计已入账待提现金额
 | 
						||
        $settled_amount = self::where("to_user_id",$user_id)->where("status",'2')->sum("settle_price");
 | 
						||
        //统计累计真实收益金额
 | 
						||
        $accumulated_incoming_amount = self::where("to_user_id",$user_id)->where("status","in",['2',"3"])->sum("settle_price");
 | 
						||
 | 
						||
        return [
 | 
						||
            "expected_incoming_amount" => $expected_incoming_amount,
 | 
						||
            "settled_amount" => $settled_amount,
 | 
						||
            "accumulated_incoming_amount" => $accumulated_incoming_amount,
 | 
						||
        ];
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /**得到基础条件
 | 
						||
     * @param $status
 | 
						||
     * @param null $model
 | 
						||
     * @param string $alisa
 | 
						||
     */
 | 
						||
    public static function getBaseWhere($whereData = [], $model = null, $alisa = '',$with = false)
 | 
						||
    {
 | 
						||
 | 
						||
        if (!$model) {
 | 
						||
            $model = new static;
 | 
						||
            if ($alisa&&!$with) $model = $model->alias($alisa);
 | 
						||
        }
 | 
						||
        if ($alisa) $alisa = $alisa . '.';
 | 
						||
        $tableFields = (new static)->getTableFields();
 | 
						||
        foreach ($tableFields as $fields)
 | 
						||
        {
 | 
						||
            if(in_array($fields, ['status','activity_id','user_id','activity_order_detail_id']))continue;
 | 
						||
//            if (isset($whereData[$fields]) && $whereData[$fields]) $model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
 | 
						||
 | 
						||
            if (isset($whereData[$fields]) && $whereData[$fields]){
 | 
						||
                if(is_array($whereData[$fields])){
 | 
						||
                    $model = $model->where("{$alisa}{$fields}", $whereData[$fields][0], $whereData[$fields][1]);
 | 
						||
                }else{
 | 
						||
                    $model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
 | 
						||
                }
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
        if (isset($whereData['status']) && $whereData['status'] !=="" && $whereData['status'] !==null  ) $model = $model->where("{$alisa}status", 'in', $whereData['status']);
 | 
						||
        if (isset($whereData['not_status']) && $whereData['not_status'] !=="" && $whereData['not_status'] !==null ) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']);
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        if (isset($whereData['keywords'])&&$whereData['keywords']){
 | 
						||
            $model = $model->where("{$alisa}order_no|{$alisa}pay_no|user.nickname|user.realname|user.mobile|detail.title|detail.address|detail.address_detail", 'LIKE', "%{$whereData['keywords']}%" );
 | 
						||
        }
 | 
						||
        if (isset($whereData['time'])&&$whereData['time']){
 | 
						||
 | 
						||
            $model = $model->time(["{$alisa}createtime",$whereData['time']]);
 | 
						||
        }
 | 
						||
        if (isset($whereData['user_id']) && $whereData['user_id']) $model = $model->where("{$alisa}to_user_id", '=', $whereData['user_id']);
 | 
						||
 | 
						||
        if (isset($whereData['activity_ids']) && $whereData['activity_ids']) $model = $model->where("{$alisa}activity_id", 'in', $whereData['activity_ids']);
 | 
						||
        if (isset($whereData['activity_id']) && $whereData['activity_id']) $model = $model->where("{$alisa}activity_id", 'in', $whereData['activity_id']);
 | 
						||
 | 
						||
 | 
						||
        if (isset($whereData['activity_order_detail_id']) && $whereData['activity_order_detail_id']) $model = $model->where("{$alisa}activity_order_detail_id", 'in', $whereData['activity_order_detail_id']);
 | 
						||
 | 
						||
//        if (isset($whereData['has_evaluate'])&&$whereData['has_evaluate']){
 | 
						||
//            //1查已评价 2查未评价
 | 
						||
//            if($whereData['has_evaluate'] == 1){
 | 
						||
//                //1查已评价
 | 
						||
//                $model = $model->where("{$alisa}classes_evaluate_id", '<>', 0);
 | 
						||
//            }else{
 | 
						||
//                //2查未评价
 | 
						||
//                $model = $model->whereExists(function ($query) use ($alisa) {
 | 
						||
//                    $order_table_name = (new \app\common\model\school\classes\hourorder\Order())->getQuery()->getTable();
 | 
						||
//                    $query->table($order_table_name)->where($order_table_name . '.classes_order_id=' . $alisa . 'id')->where('status', '=', '3');
 | 
						||
//                })->where("{$alisa}classes_evaluate_id", '=', 0);
 | 
						||
//
 | 
						||
//            }
 | 
						||
//        }
 | 
						||
 | 
						||
        return $model;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    public static function allList($user_id,$page, $limit,$keywords,$status,$activity_id=[],$params=[]){
 | 
						||
        $with_field = [
 | 
						||
            'touser'=>['nickname','mobile','avatar','realname'],
 | 
						||
            'payuser'=>['nickname','mobile','avatar','realname'],
 | 
						||
            'base'=>['*'],
 | 
						||
            'detail'=>['*'],
 | 
						||
        ];
 | 
						||
        $alisa = (new self)->getWithAlisaName();
 | 
						||
        $sort = "{$alisa}.id desc";
 | 
						||
        $serch_where = ['status'=>$status,'user_id'=>$user_id,'keywords'=>$keywords,"activity_id"=>$activity_id];
 | 
						||
//        if($type)$serch_where['type'] = $type;
 | 
						||
        return (new self)->getBaseList(array_merge($serch_where,$params), $page, $limit,$sort,$with_field);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
}
 |