商城定时任务控制器

84 阅读3分钟
<?php
/**
 * Created by PhpStorm.
 * User: lcz
 * Date: 2018/4/17
 * Time: 10:06
 * 定时任务控制器
 */
namespace app\api\controller;

use app\common\controller\Weixin;
use app\common\model\Agent;
use app\common\model\CommissionRebate;
use app\common\model\CouponCollectRecord;
use app\common\model\OperatorSaleDetail;
use app\common\model\OrderGroup;
use app\common\model\Orderjd;
use app\common\model\OrderPdd;
use app\common\model\OrderTbk;
use app\common\model\SettingTime;
use think\Controller;
use think\Db;
use think\Request;

class Task extends Controller{
	
	/**
	 * 检查超时付款订单
	 */
	public function checkTimeOutOrder(){
		$settingModel = new SettingTime();
		$setting = $settingModel
			->where(['type' => $settingModel::PAY_ORDER_TIME])
			->select();
		
		$log = '============='.date('Y-m-d H:i:s').'=========='."\r\n";
		if(!$setting){
			$log .= '没有超时时间设置'."\r\n";
			die($log);
		}
		
		
		
		
		foreach($setting as $v) {
			//转换成秒
			$time = $v['days']*24*3600+$v['hour']*3600+$v['minute']*60+$v['second'];
			if($time <= 0){
				$log .= '商家设置时间为0'."\r\n";
				continue;
			}
			$orderModel = new \app\common\model\Order();
			$map['create_time'] = ['lt', time()-$time];
			$map['order_status'] = $orderModel::STATUS_WAIT_PAYMENT;
			
			$res = $orderModel->save([
				'order_status' => $orderModel::STATUS_CLOSE,
				'close_type' => $orderModel::CLOSE_TYPE_TIMEOUT,
			],$map);
			if($res !== false) {
				$log .= '商家处理成功,处理数量【'.$res.'】条'."\r\n";
			} else {
				$log .= "商家处理出错\r\n";
			}
		}
		die($log);
	}
	
	/**
	 * 订单超时签收
	 */
	public function signOrder(){
		
		$settingModel = new SettingTime();
		$setting = $settingModel
			->where(['type' => $settingModel::SIGN_ORDER_TIME])
			->select();
		$log = '============='.date('Y-m-d H:i:s').'=========='."\r\n";
		if(!$setting){
			$log .= '没有超时时间设置'."\r\n";
			die($log);
		}
		
		foreach($setting as $v) {
			//转换成秒
			$time = $v['days']*24*3600+$v['hour']*3600+$v['minute']*60+$v['second'];
			if($time <= 0){
				$log .= '商家设置时间为0'."\r\n";
				continue;
			}
			
			$orderModel = new \app\common\model\Order();
			$map['shipping_time'] = ['lt', time()-$time];
			$map['order_status'] = $orderModel::STATUS_WAIT_SIGN;
			
			//更改订单状态及收货时间
			$res = $orderModel->save([
				'order_status' => $orderModel::STATUS_SIGN,
				'confirm_time' => time(),
			],$map);
			
			//如果签收签单后有其它操作,记得开户事务
			if($res !== false) {
				$log .= '商家处理成功,处理数量【'.$res.'】条'."\r\n";
			} else {
				$log .= '商家'."处理出错\r\n";
			}
		}
		
		die($log);
	}
	
	
	/**
	 * 统计用户,每天3点统计
	 */
	public function countUser(){
		$model = new \app\common\model\User();
		$endTime = strtotime(date('Y-m-d 00:00:00'));
		$beginTime = strtotime('-1 days', $endTime);
		$all = $model->where(['jointime' => ['lt', $endTime]])
			->field('id, count(id) as all_number')
			->select();
		
		if($all) {
			$where['jointime'] = [
				['egt', $beginTime],
				['lt', $endTime]
			];
			
			$new = $model->where($where)
				->field('id, count(id) as new_number')
				->select();
			
			foreach($all as $v) {
				$datas[] = [
					'time' => $beginTime,
					'all' => $v['all_number'],
					'new' => isset($new[$v['merid']])?$new[$v['merid']]:0,
				];
				
			}
			$res = Db::name('countUser')->insertAll($datas);
			
			if($res) {
				echo date('Y-m-d H:i:s', $beginTime).'统计用户完成'."\r\n";
			} else {
				echo date('Y-m-d H:i:s', $beginTime).'统计用户出错'."\r\n";
			}
		}
		
	}
	
	//统计订单,每天3点05分执行
	public function countOrder(){
		$model = new \app\common\model\Order();
		$merids = $model->group('merid')->column('merid','id');
		foreach($merids as $merid) {
			$all = $model->where(['merid' => $merid])->count();
			
			$endTime = strtotime(date('Y-m-d 00:00:00'));
			$beginTime = strtotime('-1 days', $endTime);
			$where['merid'] = $merid;
			$where['jointime'] = [
				['egt', $beginTime],
				['lt', $endTime]
			];
			
			$where = [['egt', $beginTime], ['lt', $endTime]];
			$new = $model
				->where(['create_time' => $where, 'merid' => $merid])
				->count();
			
			
			$pay = $model
				->where(['pay_time' =>$where, 'merid' => $merid])
				->count();
			
			$shipping = $model
				->where(['shipping_time' => $where, 'merid' => $merid])
				->count();
			
			$cofirm = $model
				->where(['confirm_time' => $where, 'merid' => $merid])
				->count();
			
			$res = Db::name('countOrder')->insert([
				'time' => $beginTime,
				'all' => $all,
				'new' => $new,
				'pay' => $pay,
				'shipping' => $shipping,
				'cofirm' => $cofirm,
				'merid' => $merid
			]);
			
			if($res) {
				echo date('Y-m-d H:i:s', $beginTime).'商户'.$merid.'统计订单完成'."\r\n";
			} else {
				echo date('Y-m-d H:i:s', $beginTime).'商户'.$merid.'统计订单出错'."\r\n";
			}
		}
	
		
	}
	
	/**
	 * 发送微信发货提醒,10分钟一次
	 */
	public function sendShipTemplate(){
		$orderModel = new \app\common\model\Order();
		$orders = Db::name('order')->alias('o')
			->join('shipping s', 'o.shipping_id = s.id', 'left')
			->join('orderAddress oa', 'oa.order_id = o.id', 'left')
			->join('area pa', 'oa.province_id = pa.id', 'left')
			->join('area ca', 'oa.city_id = ca.id', 'left')
			->join('area aa', 'oa.area_id = aa.id', 'left')
			->join('weixinInfo w', 'o.user_id = w.user_id', 'left')
			->join('batchOrder bo', 'o.id = bo.order_ids', 'left')
			->where([
				'o.order_status' => $orderModel::STATUS_WAIT_SIGN,
				'o.send_template_status' => 0,
				'bo.prepay_id' => ['neq', ''],
				'w.openid' => ['neq', '']
			])
			->field('o.id, o.order_no, o.shipping_code, s.name as shipping_name, pa.areaname as province_name, ca.areaname as city_name, aa.areaname as area_name, oa.address, oa.recipients, oa.mobile, w.openid, bo.prepay_id')
			->select();
		
		$ids = [];
		if($orders) {
			$obj = new Weixin();
			foreach($orders as $order) {
				$goods = Db::name('orderGoods')
					->where(['order_id' => $order['id']])
					->column('goods_name', 'id');
				$goodsName = implode(',', $goods);
				
				$address = $order['province_name'].$order['city_name'].$order['area_name'].$order['address'].' '.$order['recipients'].' '.$order['mobile'];
				$data = [
					'keyword1' => ['value' => $goodsName], //物品名称
					'keyword2' => ['value' => $order['order_no']], //订单号
					'keyword3' => ['value' => $address], //收货地址
					'keyword4' => ['value' => $order['shipping_code']], //物流单号
					'keyword5' => ['value' => $order['shipping_name']], //物流公司
				];
				$res = $obj->sendTemplate($order['openid'],'o2Yla366l71AoQK3KS3L7U5_Jw1yT_xpjj-ls1UEusI', $order['prepay_id'], $data, 'pages/order/detail/index?order_id='.$order['id']);
				if($res) {
					$ids[] = $order['id'];
				}
				
			}
		}
		
		if($ids) {
			Db::name('order')->where(['id' => ['in', $ids]])->update(['send_template_status' => 1]);
		}
	}
	
	
	/**
	 * 查询拼多多推广订单
	 * @throws \think\Exception
	 * @throws \think\db\exception\DataNotFoundException
	 * @throws \think\db\exception\ModelNotFoundException
	 * @throws \think\exception\DbException
	 * @throws \think\exception\PDOException
	 */
	public function queryPddOrder(){
		header('Content-type:text/html;charset=utf8');
		$model = new \app\common\model\Pdd();
		$startTime = strtotime(date('Y-m-d 00:00:00', strtotime('-1 days')));
		$endTime = strtotime(date('Y-m-d 00:00:00'));
//		$endTime = time();
//		$startTime = strtotime('2019-01-21 00:00:00');
//		$endTime = strtotime('2019-01-22 00:00:00');
		$page = 1;
		$pageNumber = 100;
		$res = $model->orderListIncrementGet($startTime, $endTime, $page);
		$str = '============'.date('Y-m-d H:i:s').'================'.PHP_EOL;
		if(!isset($res['order_list_get_response'])){
			die($str.'请求出错'.$res['error_response']['error_msg']);
		}
		if(isset($res['order_list_get_response']['order_list'])) {
			//查询到的订单列表
			$orders = $res['order_list_get_response']['order_list'];
			if($orders){
				$orderTable = Db::name('orderPdd');
				$orderModel = new OrderPdd();
				
				$config = Db::name('commissionRebate')
					->where(['rebate_type' => CommissionRebate::REBATE_TYPE_PDD])
					->group('merid')
					->select();
				
				$configs = [];
				if($config) {
					foreach($config as $v) {
						$configs[$v['merid']] = $v;
					}
					unset($config);
				}
				
				foreach($orders as $order) {
					$orderSn = $order['order_sn'];
					$custom = $order['custom_parameters'];
					
					//从自定义参数中切割出用户和商户
					$arr = explode('_', $custom);
					$order['user_id'] = $arr[0];
					$order['merid'] = isset($arr[1]) ? $arr[1] : 888;
					
					//查找是否已经添加了这个订单
					$row = $orderTable
						->where(['order_sn' => $orderSn])
						->find();
					
					if($row) {
						
						//拼多多已返利,系统状态为待结算,更改为待返利
						if($order['order_status'] == 5 && $row['status'] == OrderPdd::STATUS_N){
							$order['status'] = OrderPdd::STATUS_W;
						}
						$res = $orderTable->where(['order_sn' => $orderSn])->update($order);
						if($res !== false) {
							$str .= $row['id'].'更新成功'.PHP_EOL;
						} else {
							$str .= $row['id'].'更新出错'.PHP_EOL;
						}
					} else {
						//没有添加过订单
						if($order['order_status'] == 5){
							$order['status'] = OrderPdd::STATUS_W;
						}
						$rule = isset($configs[$order['merid']]) ? $configs[$order['merid']] : [];
						$res = $orderModel->addRow($order, $rule);
						if($res) {
							$str .= $order['order_sn'].'添加成功'.PHP_EOL;
						} else {
							$str .= $order['order_sn'].'添加出错'.PHP_EOL;
						}
					}
				}
			}
		}
		echo $str;
	}
	
	
	/**
	 * 拼多多返利
	 * @throws \think\db\exception\DataNotFoundException
	 * @throws \think\db\exception\ModelNotFoundException
	 * @throws \think\exception\DbException
	 * @throws \think\exception\PDOException
	 */
	public function pddRebate(){
		header('Content-type:text/html; charset=utf8');
		$model = new OrderPdd();
		$orders = Db::name('orderPdd')
			->where(['status' => $model::STATUS_W])
			->select();
		$str = '============'.date('Y-m-d H:i:s').'================'.PHP_EOL;
		if(!$orders) {
			die($str . '没有需要结算的订单'.PHP_EOL);
		}
		
		
		
		foreach($orders as $order) {
			$res = $model->rebate($order);
			if($res) {
				$str .= $order['id'] . "返利成功\r\n";
			} else {
				$str .= $order['id'] . "返利出错【{$model->getError()}】\r\n";
			}
		}
		echo $str;
		
	}
	
	
	/**
	 * 清除7天前的日志
	 */
	public function clearLog(){
		$apiLogPath = RUNTIME_PATH.'apiLog';
		$arr_file = array();
		readDirFile($arr_file, $apiLogPath);
		if($arr_file) {
			$startTime = strtotime('-1 weeks');
			foreach($arr_file as $file) {
				if(filemtime($file) < $startTime) {
					$res = unlink($file);
					if($res) {
						echo $file.'删除成功<br>';
					} else {
						echo $file.'删除出错<br>';
					}
				}
			}
		}
	}
	
	/**
	 * 运营商团队业绩统计,每月一号凌晨统计
	 */
	public function operatorSaleCount (){
		//开始时间,上个月的1号0点
		$begin_time = strtotime(date('Y-m-01 00:00:00', strtotime('-1 months')));
		//结束时间,这个月的1号0点
		$end_time = strtotime(date('Y-m-01 00:00:00'));
		
		
		$detailModel = new OperatorSaleDetail();
		
		$where['status'] = $detailModel::STATUS_W;
		$where['create_time']  = [
			['egt', $begin_time],
			['lt', $end_time]
		];
		
		//计算自己的销量
		$selfRows = Db::name('operatorSaleDetail')
			->where(['type' => $detailModel::TYPE_SELF])
			->group('user_id')
			->column('sum(amount)', 'user_id');
		
		//计算下级带来的销量
		$sonRows = Db::name('operatorSaleDetail')
			->where(['type' => $detailModel::TYPE_SON])
			->group('user_id')
			->column('sum(amount)', 'user_id');
		
		$datas = [];
		if($selfRows) {
			foreach($selfRows as $k => $v) {
				$datas[$k] = [
					'self' => $v,
					'son' => 0,
				];
			}
		}
		
		if($sonRows) {
			foreach($sonRows as $sk => $sv) {
				if(isset($datas[$sk])) {
					$datas[$sk]['son'] = $sv;
				} else {
					$datas[$sk] = [
						'self' => 0,
						'son' => $sv
					];
				}
			}
		}
		
		if($datas) {
			$agents = [];
			foreach ($datas as $key => $value) {
				//总销量金额
				$totalAmount = $value['self'] + $value['son'];
				//计算自己领取比例
				$proportion = $detailModel->getProportion($totalAmount);
				//计算自己领取的部分
				$selfAmount = $value['self']*$proportion;
				$agents[$key] = [
					'user_id' => $key,
					'time' => $begin_time,
//					'amount' => $totalAmount,
					'self_sale' => $value['self'],
					'sons_sale' => $value['son'],
					'self_profit' => $selfAmount,
					'sons_profit' => 0,
					'update_time' => time(),
					'proportion' => $proportion
				];
			}
			
			
			foreach($agents as $ak => $agent) {
				if($agent['proportion'] < 0.15) {
					//查找用户信息
					$user = Db::name('user')->where(['id' => $agent['user_id']])->field('id,parent_path')->find();
					if($user['parent_path']) {
						$pids = explode(',', $user['parent_path']);
						//查找上级推荐人中最靠近的运营商
						$pAgent = Db::name('agent')->alias('a')
							->join('user u', 'a.user_id = u.id', 'left')
							->where(['u.id' => ['in',$pids], 'a.level' => Agent::LEVEL_3])
							->order('u.id DESC')
							->field('u.id')
							->find();
						
						if($pAgent) {
							//下级的分红为上级的分红比例-下级的分红比例*下级的总销量
							$sonAmount = ($agents[$pAgent['id']]['proportion']-$agent['proportion'])*($agent['self_sale'] + $agent['sons_sale']);
							$agents[$pAgent['id']]['sons_profit'] += $sonAmount;
						}
					}
				}
			}
//			dump($agents);
//			die;
			Db::startTrans();
			try {
				$datas = array_values($agents);
				$res = Db::name('operatorSaleCount')->insertAll($datas);
				if(!$res) {
					throw new Exception('添加出错');
				}
				
				Db::commit();
				echo 'OK';
			} catch (Exception $e) {
				Db::rollback();
				echo $e->getMessage();
			}
		}
	}
	
	
	/**
	 * 检查拼团订单,10分钟一次
	 */
	public function checkGroupOrder() {
		$model = new OrderGroup();
		$res = $model->checkGroupOrder();
		echo date('Y-m-d H:i:s')."\r\n".$model->getError()."\r\n";
		
		
	}
	
	/**
	 * 淘宝客返利, 更改淘宝订单状态,更改返利记录状态,加钱
	 */
	public function tbkRebate(){
		header('Content-type:text/html; charset=utf8');
		$model = new OrderTbk();
		$orders = Db::name('orderTbk')
			->where(['status' => $model::STATUS_S])
			->field('id, user_id, merid, record_id, auctionId, createTime, feeString, taobaoTradeParentId')
			->select();
		
		$str = '============'.date('Y-m-d H:i:s').'================'.PHP_EOL;
		if(!$orders) {
			die($str . '没有需要结算的订单'.PHP_EOL);
		}
		
		$str = '';
		foreach($orders as $order) {
			$str .= $model->rebate($order).PHP_EOL;
		}
		
		echo $str;
		
	}
	
	/**
	 * 淘宝客订单匹配用户,更改领取记录状态,添加待返利记录
	 */
	public function tbkPregUser(){
		header('Content-type:text/html; charset=utf8');
		$model = new OrderTbk();
		
		//查找待匹配用户的订单
		$orders = Db::name('orderTbk')
			->where(['status' => $model::STATUS_P])
			->field('id, auctionId, createTime, feeString, taobaoTradeParentId')
			->select();
		
		$str = '============'.date('Y-m-d H:i:s').'================'.PHP_EOL;
		if(!$orders) {
			die($str . '没有需要匹配的订单'.PHP_EOL);
		}
		
		//查找返利配置
		$config = Db::name('commissionRebate')
			->where(['rebate_type' => CommissionRebate::REBATE_TYPE_TBK])
			->group('merid')
			->select();
		
		if(!$config) {
			die($str . '没有配置返利设置'.PHP_EOL);
		}
		
		//转成商户号为下标的数组
		$configs = [];
		foreach($config as $v) {
			$configs[$v['merid']] = $v;
		}
		unset($config);
		
		$str = '';
		$recordModel = new CouponCollectRecord();
		
		//需求返利的数据
		$rebateOrder = [];
		
		foreach($orders as $order) {
			//查找领取类型为淘宝客,状态为待匹配的,商品ID和订单ID相同的记录
			$records = Db::name('couponCollectRecord')
				->where([
					'type' => $recordModel::TYPE_TBK,
					'status' => $recordModel::STATUS_N,
					'goods_id' => $order['auctionId']])
				->field('id as record_id, merid, user_id')
				->select();
			
			if(!$records || count($records) > 1) {
				//没有记录或记录数量 大于1,更改状态为异常
				$orderRes = Db::name('orderTbk')
					->where(['id' => $order['id']])
					->update([
						'status' => $model::STATUS_N,
					]);
				if(!$orderRes) {
					$str .= $order['id'].'更改状态为匹配失败出错'.PHP_EOL;
				}
				
			} else {
				//商户号
				$merid = $records[0]['merid'];
				$data = array_merge($order, $records[0]);
				$rule = isset($configs[$merid]) ? $configs[$merid] : [];
				$data['rule'] = $rule;
				$rebateOrder[] = array_merge($order, $data);
			}
		}
		
		//有要返利的数据,去添加返利记录
		if($rebateOrder) {
			foreach ($rebateOrder as $order) {
				$str .= $model->changeStauts($order).PHP_EOL;
			}
		}
		
		echo $str;
		
	}
	
	
	/**
	 * 查询京东新订单,每分钟一次
	 * @param int $page
	 */
	public function queryJdNewOrder($page = 1){
		header('Content-type:text/html;charset=utf8');
		$obj = new \app\common\controller\Jd();
		$time = date('YmdHi', time()-60);
		$res = $obj->orderQuery(1, $time, $page);
		if(!isset($res['jd_union_open_order_query_response']['result'])) {
			die('查询京东新订单出错'.PHP_EOL);
		}
		$str = date('Y-m-d H:i:s').PHP_EOL;
		$res = json_decode($res['jd_union_open_order_query_response']['result'], true);
		$resData = isset($res['data'])?$res['data']:[];
		if($resData) {
			$str .= $obj->operateOrder($resData);
		} else {
			die($str.'没有新订单'.PHP_EOL);
		}
		
		
		if($res['hasMore']) {
			$this->queryJdOrder($page++);
		}
		
		die($str);
	}
	
	/**查询京东结算订单,每分钟一次
	 * @param int $page
	 */
	public function queryJdOverOrder($page = 1){
		header('Content-type:text/html;charset=utf8');
		$obj = new \app\common\controller\Jd();
		$time = date('YmdHi', time()-60);
//		$time= '201812251531';
		$res = $obj->orderQuery(2, $time, $page);
		if(!isset($res['jd_union_open_order_query_response']['result'])) {
			die('查询京东结算订单出错'.PHP_EOL);
		}
		$str = date('Y-m-d H:i:s').PHP_EOL;
		$res = json_decode($res['jd_union_open_order_query_response']['result'], true);
		$str .= var_export($res, true);
		$resData = isset($res['data'])?$res['data']:[];
		
		if($resData) {
			$str .= $obj->operateOrder($resData);
		} else {
			die($str.'没有新结算订单'.PHP_EOL);
		}
		
		
		if($res['hasMore']) {
			$this->queryJdOrder($page++);
		}
		
		die($str);
	}
	
	
	/**
	 * 京东返利
	 * @throws \think\db\exception\DataNotFoundException
	 * @throws \think\db\exception\ModelNotFoundException
	 * @throws \think\exception\DbException
	 * @throws \think\exception\PDOException
	 */
	public function jdRebate(){
		header('Content-type:text/html; charset=utf8');
		$model = new Orderjd();
		$orders = Db::name('orderJd')
			->where(['status' => $model::STATUS_R])
			->select();
		
		$str = '============'.date('Y-m-d H:i:s').'================'.PHP_EOL;
		if(!$orders) {
			die($str . '没有需要结算的订单'.PHP_EOL);
		}
		
		
		foreach($orders as $order) {
			$res = $model->rebate($order);
			if($res) {
				$str .= $order['id'] . "返利成功\r\n";
			} else {
				$str .= $order['id'] . "返利出错【{$model->getError()}】\r\n";
			}
		}
		echo $str;
	}
}