225 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			225 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| 
								 | 
							
								<?php
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace addons\xilufitness\controller;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								use addons\xilufitness\model\TimesCardShare;
							 | 
						|||
| 
								 | 
							
								use addons\xilufitness\model\UserCard;
							 | 
						|||
| 
								 | 
							
								use addons\xilufitness\services\pay\PayService;
							 | 
						|||
| 
								 | 
							
								use think\Config;
							 | 
						|||
| 
								 | 
							
								use think\Db;
							 | 
						|||
| 
								 | 
							
								use think\Log;
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @ApiSector(定时任务)
							 | 
						|||
| 
								 | 
							
								 * @ApiWeigh(1)
							 | 
						|||
| 
								 | 
							
								 * @package addons\xilufitness\controller
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								class Autotask extends \think\addons\Controller
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    protected $noNeedLogin = ["*"];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    protected $layout = '';
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public function _initialize()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        parent::_initialize();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!$this->request->isCli()) {
							 | 
						|||
| 
								 | 
							
								            $this->error('只允许在终端进行操作!');
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /**
							 | 
						|||
| 
								 | 
							
								     * 获取 配置信息
							 | 
						|||
| 
								 | 
							
								     * @param int $brand_id 品牌商id
							 | 
						|||
| 
								 | 
							
								     * @return array
							 | 
						|||
| 
								 | 
							
								     */
							 | 
						|||
| 
								 | 
							
								    private function getConfig(int $brand_id = 0){
							 | 
						|||
| 
								 | 
							
								        $brandConfig = Config::get('xilubrand')[$brand_id] ?? '';
							 | 
						|||
| 
								 | 
							
								        return [
							 | 
						|||
| 
								 | 
							
								            'appid'          => $brandConfig['mini_appid'] ?? '',
							 | 
						|||
| 
								 | 
							
								            'appsecret'      => $brandConfig['mini_appsecret'] ?? '',
							 | 
						|||
| 
								 | 
							
								            'encodingaeskey' => '',
							 | 
						|||
| 
								 | 
							
								            // 配置商户支付参数
							 | 
						|||
| 
								 | 
							
								            'mch_id'         => $brandConfig['mini_mch_id'] ?? '',
							 | 
						|||
| 
								 | 
							
								            'mch_key'        => $brandConfig['mini_mch_key'] ?? '',
							 | 
						|||
| 
								 | 
							
								            // 配置商户支付双向证书目录 (p12 | key,cert 二选一,两者都配置时p12优先)
							 | 
						|||
| 
								 | 
							
								            'ssl_p12'        => ROOT_PATH.'public'.$brandConfig['mini_mch_p12'] ?? '',
							 | 
						|||
| 
								 | 
							
								            'ssl_key'       => ROOT_PATH.'public'.$brandConfig['mini_mch_pem_key'] ?? '',
							 | 
						|||
| 
								 | 
							
								            'ssl_cer'       => ROOT_PATH.'public'.$brandConfig['mini_mch_pem_cert'] ?? '',
							 | 
						|||
| 
								 | 
							
								            // 配置缓存目录,需要拥有写权限
							 | 
						|||
| 
								 | 
							
								            'cache_path'     => RUNTIME_PATH.'wechat',
							 | 
						|||
| 
								 | 
							
								        ];
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /**
							 | 
						|||
| 
								 | 
							
								     * 计划任务入口
							 | 
						|||
| 
								 | 
							
								     */
							 | 
						|||
| 
								 | 
							
								    public function cron(){
							 | 
						|||
| 
								 | 
							
								        Log::log("[".date('Y-m-d H:i:s'."]"." - 开始执行定时任务"));
							 | 
						|||
| 
								 | 
							
								        $this->change_work_course();
							 | 
						|||
| 
								 | 
							
								        $this->change_work_camp();
							 | 
						|||
| 
								 | 
							
								        $this->cancel_wait();
							 | 
						|||
| 
								 | 
							
								        $msg = $this->change_invalid_share();
							 | 
						|||
| 
								 | 
							
								        Log::log("[".date('Y-m-d H:i:s'."]"." - 执行定时任务结束"));
							 | 
						|||
| 
								 | 
							
								        return $msg;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /**
							 | 
						|||
| 
								 | 
							
								     * 清理失效的次卡分享
							 | 
						|||
| 
								 | 
							
								     */
							 | 
						|||
| 
								 | 
							
								    public function change_invalid_share()
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        Log::log("[".date('Y-m-d H:i:s'."]"." - 开始清理失效的次卡分享"));
							 | 
						|||
| 
								 | 
							
								        $share_card = new TimesCardShare();
							 | 
						|||
| 
								 | 
							
								        $user_card = new UserCard();
							 | 
						|||
| 
								 | 
							
								        //查询失效的次卡分享
							 | 
						|||
| 
								 | 
							
								        $share_list = $share_card
							 | 
						|||
| 
								 | 
							
								            ->where('status',0)
							 | 
						|||
| 
								 | 
							
								            ->where('share_expire_time', '<', date('Y-m-d H:i:s'))
							 | 
						|||
| 
								 | 
							
								            ->select();
							 | 
						|||
| 
								 | 
							
								        foreach ($share_list as $k => $v) {
							 | 
						|||
| 
								 | 
							
								            try {
							 | 
						|||
| 
								 | 
							
								                Db::startTrans();
							 | 
						|||
| 
								 | 
							
								                $share_id = xilufitness_get_id_value($v->id);
							 | 
						|||
| 
								 | 
							
								                Log::log($share_id);
							 | 
						|||
| 
								 | 
							
								                $data['status'] = 2;
							 | 
						|||
| 
								 | 
							
								                $result = Db::name('xilufitness_times_card_share')->where('id', $share_id)->update($data);
							 | 
						|||
| 
								 | 
							
								                Log::log($result);
							 | 
						|||
| 
								 | 
							
								                // 判断更新是否成功
							 | 
						|||
| 
								 | 
							
								                if ($result) {
							 | 
						|||
| 
								 | 
							
								                    $user_card_id = $v->user_card_id;
							 | 
						|||
| 
								 | 
							
								                    $card_info = $user_card::get($user_card_id);
							 | 
						|||
| 
								 | 
							
								                    $card_info['left_times_count']  = $card_info['left_times_count'] + 1;
							 | 
						|||
| 
								 | 
							
								                    $card_info['already_share_times']  = $card_info['already_share_times'] - 1;
							 | 
						|||
| 
								 | 
							
								                    $card_info['left_share_times']  = $card_info['left_share_times'] + 1;
							 | 
						|||
| 
								 | 
							
								                    $card_info->save();
							 | 
						|||
| 
								 | 
							
								                    Log::log("清理失效的次卡分享成功");
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                Db::commit();
							 | 
						|||
| 
								 | 
							
								            } catch (\Exception $e) {
							 | 
						|||
| 
								 | 
							
								                Log::log("清理失效的次卡分享失败");
							 | 
						|||
| 
								 | 
							
								                Log::log($e);
							 | 
						|||
| 
								 | 
							
								                Db::rollback();
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        Log::log( "清理失效的次卡分享" . count($share_list) . "条");
							 | 
						|||
| 
								 | 
							
								        Log::log("[".date('Y-m-d H:i:s'."]"." - 清理失效的次卡分享结束"));
							 | 
						|||
| 
								 | 
							
								        return "清理失效的次卡分享" . count($share_list) . "条";
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /**
							 | 
						|||
| 
								 | 
							
								     * 开课前五分钟 排队取消 排队失效
							 | 
						|||
| 
								 | 
							
								     */
							 | 
						|||
| 
								 | 
							
								    public function cancel_wait(){
							 | 
						|||
| 
								 | 
							
								        $model = new \addons\xilufitness\model\Order;
							 | 
						|||
| 
								 | 
							
								        $time = time() - 300;
							 | 
						|||
| 
								 | 
							
								        $i = 1;
							 | 
						|||
| 
								 | 
							
								        do {
							 | 
						|||
| 
								 | 
							
								            try {
							 | 
						|||
| 
								 | 
							
								                $total_count = $model->where(['order_status' => 10, 'starttime' => ['egt',$time]])->count('*');
							 | 
						|||
| 
								 | 
							
								                $list = $model
							 | 
						|||
| 
								 | 
							
								                    ->where(['order_status' => 10, 'starttime' => ['egt',$time]])
							 | 
						|||
| 
								 | 
							
								                    ->order("pay_time asc")
							 | 
						|||
| 
								 | 
							
								                    ->page($i,100)
							 | 
						|||
| 
								 | 
							
								                    ->select();
							 | 
						|||
| 
								 | 
							
								                $current_count = ($i-1)*100 + count($list);
							 | 
						|||
| 
								 | 
							
								                foreach ($list as $key => $val){
							 | 
						|||
| 
								 | 
							
								                    Db::startTrans();
							 | 
						|||
| 
								 | 
							
								                    $cancelResult = $val->save(['order_status' => 4]);
							 | 
						|||
| 
								 | 
							
								                    if(false !== $cancelResult){
							 | 
						|||
| 
								 | 
							
								                        PayService::getInstance(['mini_config' => $this->getConfig($val['brand_id'])])->refundOrder(xilufitness_get_id_value($val['id']),($val['brand_id'] ?? 0));
							 | 
						|||
| 
								 | 
							
								                    }
							 | 
						|||
| 
								 | 
							
								                    Db::commit();
							 | 
						|||
| 
								 | 
							
								                    unset($cancelResult);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            } catch (\Exception $e){
							 | 
						|||
| 
								 | 
							
								                Db::rollback();
							 | 
						|||
| 
								 | 
							
								                Log::record("取消排队失败:".$e->getMessage());
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        } while($total_count > $current_count && ++$i);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /**
							 | 
						|||
| 
								 | 
							
								     * 检测课程排课到了开课时间,状态还在待预约 只要有人报名改为 开课成功
							 | 
						|||
| 
								 | 
							
								     */
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public function change_work_course(){
							 | 
						|||
| 
								 | 
							
								        $model = new \addons\xilufitness\model\WorkCourse;
							 | 
						|||
| 
								 | 
							
								        $orderModel = new \addons\xilufitness\model\Order;
							 | 
						|||
| 
								 | 
							
								        $i = 1;
							 | 
						|||
| 
								 | 
							
								        $page_size = 100;
							 | 
						|||
| 
								 | 
							
								        do {
							 | 
						|||
| 
								 | 
							
								            $total_count = $model->where(['status' => 'normal', 'start_at' => ['elt',time()]])->count('*');
							 | 
						|||
| 
								 | 
							
								            $list = $model
							 | 
						|||
| 
								 | 
							
								                ->where(['status' => 'normal', 'start_at' => ['elt',time()]])
							 | 
						|||
| 
								 | 
							
								                ->order("start_at asc")
							 | 
						|||
| 
								 | 
							
								                ->page($i,$page_size)
							 | 
						|||
| 
								 | 
							
								                ->select();
							 | 
						|||
| 
								 | 
							
								            array_walk($list,function (&$item,$key) use($orderModel){
							 | 
						|||
| 
								 | 
							
								                $order_count = $orderModel->where(['brand_id' => $item->brand_id ?? 0, 'data_id' => xilufitness_get_id_value($item->id ?? 0), 'order_type' => $item->course_type ?? -1,
							 | 
						|||
| 
								 | 
							
								                    'order_status' => ['notin',[0,4,10]]])->count('*');
							 | 
						|||
| 
								 | 
							
								                if($order_count > 0){
							 | 
						|||
| 
								 | 
							
								                    $item->allowField(true)->save(['status' => 'complete']);
							 | 
						|||
| 
								 | 
							
								                } else {
							 | 
						|||
| 
								 | 
							
								                    $item->allowField(true)->save(['status' => 'failed']);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            });
							 | 
						|||
| 
								 | 
							
								            $current_count = ($i - 1)*$page_size + count($list);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        } while($total_count > $current_count && ++$i);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /**
							 | 
						|||
| 
								 | 
							
								     * 检测活动排课到期情况
							 | 
						|||
| 
								 | 
							
								     */
							 | 
						|||
| 
								 | 
							
								    public function change_work_camp(){
							 | 
						|||
| 
								 | 
							
								        $model = new \addons\xilufitness\model\WorkCamp;
							 | 
						|||
| 
								 | 
							
								        $orderModel = new \addons\xilufitness\model\Order;
							 | 
						|||
| 
								 | 
							
								        $i = 1;
							 | 
						|||
| 
								 | 
							
								        $page_size = 100;
							 | 
						|||
| 
								 | 
							
								        do {
							 | 
						|||
| 
								 | 
							
								            $total_count = $model->where(['status' => 'normal', 'start_at' => ['elt',time()]])->count('*');
							 | 
						|||
| 
								 | 
							
								            $list = $model
							 | 
						|||
| 
								 | 
							
								                ->where(['status' => 'normal', 'start_at' => ['elt',time()]])
							 | 
						|||
| 
								 | 
							
								                ->order("start_at asc")
							 | 
						|||
| 
								 | 
							
								                ->page($i,$page_size)
							 | 
						|||
| 
								 | 
							
								                ->select();
							 | 
						|||
| 
								 | 
							
								            array_walk($list,function (&$item,$key) use($orderModel){
							 | 
						|||
| 
								 | 
							
								                $order_count = $orderModel->where(['brand_id' => $item->brand_id ?? 0, 'data_id' => xilufitness_get_id_value($item->id ?? 0), 'order_type' => 3,
							 | 
						|||
| 
								 | 
							
								                    'order_status' => ['notin',[0,4]]])->count('*');
							 | 
						|||
| 
								 | 
							
								                if($order_count >= $item['camp_count']){
							 | 
						|||
| 
								 | 
							
								                    $item->allowField(true)->save(['status' => 'complete']);
							 | 
						|||
| 
								 | 
							
								                } else {
							 | 
						|||
| 
								 | 
							
								                    //开营失败 自动退款
							 | 
						|||
| 
								 | 
							
								                    try {
							 | 
						|||
| 
								 | 
							
								                        Db::startTrans();
							 | 
						|||
| 
								 | 
							
								                        $result =  $item->allowField(true)->save(['status' => 'failed']);
							 | 
						|||
| 
								 | 
							
								                        if(false !== $result){
							 | 
						|||
| 
								 | 
							
								                            $orderList = $orderModel->where(['brand_id' => $item->brand_id ?? 0, 'data_id' => xilufitness_get_id_value($item->id ?? 0), 'order_type' => 3,
							 | 
						|||
| 
								 | 
							
								                                'pay_status' => 1, 'order_status' => 1])->select();
							 | 
						|||
| 
								 | 
							
								                            foreach ($orderList as $key => $val){
							 | 
						|||
| 
								 | 
							
								                                    $orderResult = $val->save(['order_status' => 4]);
							 | 
						|||
| 
								 | 
							
								                                    if(false !== $orderResult){
							 | 
						|||
| 
								 | 
							
								                                        PayService::getInstance(['mini_config' => $this->getConfig($val['brand_id'])])->refundOrder(xilufitness_get_id_value($val['id']),($val['brand_id'] ?? 0));
							 | 
						|||
| 
								 | 
							
								                                    }
							 | 
						|||
| 
								 | 
							
								                                    unset($orderResult);
							 | 
						|||
| 
								 | 
							
								                            }
							 | 
						|||
| 
								 | 
							
								                        }
							 | 
						|||
| 
								 | 
							
								                        Db::commit();
							 | 
						|||
| 
								 | 
							
								                    } catch (\Exception $e){
							 | 
						|||
| 
								 | 
							
								                        Db::rollback();
							 | 
						|||
| 
								 | 
							
								                        Log::record("活动开营失败:".$e->getMessage());
							 | 
						|||
| 
								 | 
							
								                    }
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            });
							 | 
						|||
| 
								 | 
							
								            $current_count = ($i - 1)*$page_size + count($list);
							 | 
						|||
| 
								 | 
							
								        } while($total_count > $current_count && ++$i);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								}
							 |