validate($data,[ 'keyword'=>['max:11'], 'num_max'=>['integer','between:0,9'], 'rule_position'=>['in:middle,tail'], ]); if(empty($data['type'])){ $data['type']=1; } if(in_array($data['type'],[Mobile::BEAUTI,Mobile::API])){ $this->listBeauti($data['type']); } $hiddenColumn = Mobile::hiddenColumn(); $model=Mobile::show($data); // $model->field($hiddenColumn,true); $model->field('mobile.`id`,`status`,`logo`,`name`,`brand`,`no`,`type`,`network`,`city_id`,`city`,`province_id`,`province`,`amount_exists`,`amount_original`,`amount_base`,`amount_charge`,`amount_proxy`,`amount_kill`,`amount`,`top_time`,`rec_time`,`summary`,`is_activity`,`activity_time_end`,`sort`,`sort_line`,`activity_time`,`stock_num`,`is_offer`,`card_status`,`select_num_status`,`product_no`,mobile.`proxy_status`,`send_template`,`not_send_template`,`min_age`,`max_age`,`link`,`sort_proxy`'); $model->where('type',$data['type']); if(isset($data['price_min']) && is_numeric($data['price_min'])){ $model->where('amount','>=',$data['price_min']); } if(!empty($data['price_max']) && is_numeric($data['price_max'])){ $model->where('amount','<=',$data['price_max']); } if(!empty($data['search_type']) && !empty($data['keyword'])){ if($data['search_type']=='fuzzy'){ if(isset($data['search_last']) && $data['search_last']==1){ $no=str_pad($data['keyword'],11,'-',STR_PAD_LEFT); for ($i=0;$i<11;$i++){ if($no[$i]=='-'){ continue; } if($i==0){ continue; } $pos=$i+1; $model->where("filter_no_pos_{$pos}",$no[$i]); } }else { $model->where('no', 'like', "%{$data['keyword']}%"); } }elseif ($data['search_type']=='precise'){ foreach ($data['keyword'] as $k=>$v){ $pos=$k+1; if($pos==1||$v===""||is_null($v))continue; $model->where("filter_no_pos_{$pos}",$v); } } } if(!empty($data['city_id'])){ if (str_contains($data['city_id'],'-all')){ $model->where('province_id',str_replace('-all','',$data['city_id'])); }elseif (is_numeric($data['city_id'])) { $model->where('city_id', $data['city_id']); }elseif (preg_match('/\d+-\d+/',$data['city_id'])){ $model->where('city_id',explode('-',$data['city_id']))[1]; } } if(!empty($data['network'])){ /*$network=array_column(MobileConstant::getNetwork(),'search','name'); $works=[$data['network']]; foreach ($network as $key=>$networkArr){ if($key==$data['network']){ $works=$networkArr; break; } } $model->whereIn('network',$works);*/ $model->where('network',$data['network']); } if(isset($data['is_activity']) && $data['is_activity']){ $model->where('is_activity',1); } if(!empty($data['exclude_num']) && is_array($data['exclude_num'])){ //$model->whereNotLike('no',"%{$data['exclude_num']}%"); foreach ($data['exclude_num'] as $num){ if($num==1){ continue; } $model->where("filter_num_{$num}",0); } } if(!empty($data['num_max'])){ $model->where("filter_num_{$data['num_max']}",'>',3); } $rules=MobileConstant::getFilters(); if(!empty($data['rule_name'])){ if (!isset($rules[$data['rule_name']])) { $this->error('规律规则不支持'); } $rule=$rules[$data['rule_name']]; if(!empty($data['rule_position'])) { $model->where($rule[$data['rule_position']], 1); }else{ $model->where(function (Query $query)use ($rule){ $query->where($rule['middle'],1)->whereOr($rule['tail'],1); }); } } if(!empty($data['is_offer'])){ $model->where('is_offer','>',0); } /*if($chanId){ $model->whereIn('hold_chan',[0,$chanId]); }else{ $model->where('hold_chan',0); }*/ $subIds=[]; if($chanId){ if(empty($data['sort'])) { $activityData = (clone $model)->where('hold_chan', $chanId)->order('sort_line')->select(); /*$topRecData = (clone $model) ->join('mobile_sub', "mobile_sub.mobile_id=mobile.id and sub_admin_id=$chanId") ->where('sub_top_time|sub_rec_time', 1) ->where(function (Query $query) use ($activityData) { if ($activityData && $activityData->column('id')) { $query->whereNotIn('id', $activityData->column('id')); } }) ->field('mobile.*') ->order('sub_sort_line') ->select(); $subData = $activityData->merge($topRecData); $subIds = $subData->column('id');*/ $subData=$activityData; $subIds=$activityData->column('id'); $model->where('is_activity',0); } // $model->where('proxy_status', 0) // $model->where('proxy_id', $chanId); $model->join('mobile_proxy_status ps', 'mobile.id=ps.mobile_id', 'LEFT')->where(function($q) use($chanId){ $q->where('mobile.proxy_id', $chanId)->where('ps.proxy_id', $chanId)->whereOr(function($q) use($chanId){ $q->where('status', 0)->where('mobile.proxy_id is null')->where('ps.proxy_status', 0)->where('ps.proxy_id', $chanId); }); }); }else{ $model->where('hold_chan',0)->where('proxy_id is null'); } if($subIds){ $model->whereNotIn('mobile.id',$subIds); } if(!empty($data['sort'])){ if($data['sort']=='price_asc'){ $model->order('amount','asc'); }elseif($data['sort']=='price_desc'){ $model->order('amount','desc'); } }else{ if($data['type']==1) { $model->order('sort_line'); } elseif($chanId){ $model->order('sort_proxy asc, sort asc'); } else{ $model->order('sort'); } } // dump($model->fetchSql()->select());exit; $list=$model->paginate($limit,true)->toArray(); $listData=$list['data']; if($page==1 && isset($subData)){ foreach (array_reverse($subData->toArray()) as $item){ array_unshift($listData,$item); } } $list['data']=$listData; $this->success('',$list); } protected function listBeauti($type){ $chanId=getChanId(); $data=input(); $page=empty($data['page'])?1:$data['page']; $limit=input('limit')?:15; $query=[ 'query'=>[ "bool"=>[ 'should'=>[ [ 'bool'=>[ 'must'=>[ [ 'terms'=>[ 'status'=>Mobile::beautiFrontShowStatus(), ], ], [ 'bool'=>[ 'must'=>[ [ 'term'=>[ 'is_activity'=>0, ], ], [ 'term'=>[ 'hold_chan'=>0, ] ] ] ] ], [ 'term'=>[ 'type'=>$type, ] ] ] ] ], [ 'bool'=>[ 'must'=>[ [ 'terms'=>[ 'status'=>Mobile::beautiFrontShowStatus(), ], ], [ 'bool'=>[ 'must'=>[ [ 'term'=>[ 'is_activity'=>1, ], ], [ 'term'=>[ 'hold_chan'=>$chanId, ] ] ] ] ], [ 'term'=>[ 'type'=>$type, ] ] ] ] ] ] ] ], 'size'=>$limit, 'from'=>($page-1)*$limit, ]; // dump($query); if(isset($data['price_min']) && is_numeric($data['price_min'])){ $query['query']['bool']['should'][0]['bool']['must'][]['range']['total']['gte']=(int)$data['price_min']; $query['query']['bool']['should'][1]['bool']['must'][]['range']['total']['gte']=(int)$data['price_min']; } if(!empty($data['price_max']) && is_numeric($data['price_max'])){ $query['query']['bool']['should'][0]['bool']['must'][]['range']['total']['lte']=(int)$data['price_max']; $query['query']['bool']['should'][1]['bool']['must'][]['range']['total']['lte']=(int)$data['price_max']; } if(!empty($data['sort'])){ if($data['sort']=='price_asc'){ if (!isset($data['price_min']) || !is_numeric($data['price_min'])) { $query['query']['bool']['should'][0]['bool']['must'][]['range']['total']['gte']=3; } $query['sort']['total']['order']='asc'; }elseif($data['sort']=='price_desc'){ $query['sort']['total']['order']='desc'; } }elseif(isset($data['num_max']) && is_numeric($data['num_max'])){ $query['sort']["filter_num_{$data['num_max']}"]['order']='desc'; }else{ /*$query['sort']['activity_time']['order'] = 'desc'; $query['sort']['rec_time']['order'] = 'desc'; $query['sort']['top_time']['order'] = 'desc'; $query['sort']['sort']['order'] = 'asc';*/ $query['sort']['sort_line']['order'] = 'asc'; } if(!empty($data['search_type']) && !empty($data['keyword'])){ if($data['search_type']=='fuzzy'){ if(isset($data['search_last']) && $data['search_last']==1){ $query['query']['bool']['should'][0]['bool']['must'][]['wildcard']['no']=['value'=>"*{$data['keyword']}"]; $query['query']['bool']['should'][1]['bool']['must'][]['wildcard']['no']=['value'=>"*{$data['keyword']}"]; }else { $query['query']['bool']['should'][0]['bool']['must'][]['wildcard']['no']=['value'=>"*{$data['keyword']}*"]; $query['query']['bool']['should'][1]['bool']['must'][]['wildcard']['no']=['value'=>"*{$data['keyword']}*"]; } }elseif ($data['search_type']=='precise'){ foreach ($data['keyword'] as $k=>$v){ $pos=$k+1; if($pos==1||!is_numeric($v))continue; $query['query']['bool']['should'][0]['bool']['must'][]['term']["filter_no_pos_{$pos}"]=$v; $query['query']['bool']['should'][1]['bool']['must'][]['term']["filter_no_pos_{$pos}"]=$v; } } } if(!empty($data['is_offer'])){ $query['query']['bool']['should'][0]['bool']['must'][]['range']["is_offer"]['gt']=0; $query['query']['bool']['should'][1]['bool']['must'][]['range']["is_offer"]['gt']=0; } if(!empty($data['city_id'])){ if (str_contains($data['city_id'],'-all')){ $provinceId=str_replace('-all','',$data['city_id']); $query['query']['bool']['should'][0]['bool']['must'][]['term']["province_id"]=$provinceId; $query['query']['bool']['should'][1]['bool']['must'][]['term']["province_id"]=$provinceId; }elseif (is_numeric($data['city_id'])) { $query['query']['bool']['should'][0]['bool']['must'][]['term']["city_id"]=$data['city_id']; $query['query']['bool']['should'][1]['bool']['must'][]['term']["city_id"]=$data['city_id']; }elseif (preg_match('/\d+-\d+/',$data['city_id'])){ $cityId=explode('-',$data['city_id'])[1]; $query['query']['bool']['should'][0]['bool']['must'][]['term']["city_id"]=$cityId; $query['query']['bool']['should'][1]['bool']['must'][]['term']["city_id"]=$cityId; } } $rules=MobileConstant::getFilters(); if(!empty($data['rule_name'])){ if (!isset($rules[$data['rule_name']])) { $this->error('规律规则不支持'); } $rule=$rules[$data['rule_name']]; if(!empty($data['rule_position'])) { $query['query']['bool']['should'][0]['bool']['must'][]['term'][$rule[$data['rule_position']]]=1; $query['query']['bool']['should'][1]['bool']['must'][]['term'][$rule[$data['rule_position']]]=1; }else{ $ruleQuery=[ 'bool'=>[ 'should'=>[ [ 'term'=>[ $rule['middle']=>1, ] ], [ 'term'=>[ $rule['tail']=>1, ] ] ] ] ]; $query['query']['bool']['should'][0]['bool']['must'][]=$ruleQuery; $query['query']['bool']['should'][1]['bool']['must'][]=$ruleQuery; } } if(!empty($data['network'])){ $yys = EsMobileService::network($data['network']); $query['query']['bool']['should'][0]['bool']['must'][]['term']['yys']=$yys; $query['query']['bool']['should'][1]['bool']['must'][]['term']['yys']=$yys; // $query['query']['bool']['should'][0]['bool']['must'][]['term']['network']=['value'=>"*{$data['network']}*"]; // $query['query']['bool']['should'][1]['bool']['must'][]['term']['network']=['value'=>"*{$data['network']}*"]; // $query['query']['bool']['should'][0]['bool']['must'][]['term']['network']=["*{$data['network']}*"]; // $query['query']['bool']['should'][1]['bool']['must'][]['term']['network']=["*{$data['network']}*"]; // $query['query']['bool']['should'][0]['bool']['must'][]['term']['network']='移'; // $query['query']['bool']['should'][1]['bool']['must'][]['term']['network']='移'; // $query['query']['bool']['should'][0]['bool']['must'][]['term']['network']='动'; // $query['query']['bool']['should'][0]['bool']['must'][]['term']['network']='网'; // $query['query']['bool']['must'][0]['bool']['should'][]['match_phrase']['network']['query']=$data['network']; // $query['query']['bool']['must'][0]['bool']['should'][]['match_phrase']['network']['operator']='and'; // $query['query']['bool']['must'][1]['bool']['should'][]['match_phrase']['network']['query']=$data['network']; } if(!empty($data['exclude_num']) && is_array($data['exclude_num'])){ $data['exclude_num']=array_unique($data['exclude_num']); foreach ($data['exclude_num'] as $num){ if(!is_numeric($num)){ continue; } $query['query']['bool']['should'][0]['bool']['must'][]['term']["filter_num_{$num}"]=0; $query['query']['bool']['should'][1]['bool']['must'][]['term']["filter_num_{$num}"]=0; } } if(isset($data['is_activity']) && $data['is_activity']){ $query['query']['bool']['should'][0]['bool']['must'][]['term']['is_activity']=1; $query['query']['bool']['should'][1]['bool']['must'][]['term']['is_activity']=1; }else{ $activityShow=config('site.activity_no_show')?:1; if($activityShow==2){ $query['query']['bool']['should'][0]['bool']['must'][]['term']['is_activity']=0; $query['query']['bool']['should'][1]['bool']['must'][]['term']['is_activity']=0; } } //dump($query); $esData = EsMobileService::get($query); // dump($esData); $esData['current_page']=$page; $esData['per_page']=$limit; $esData['has_more']=count($esData['data'])>=$limit; $rulePosition=$data['rule_position']??''; if(!empty($data['rule_name'])){ foreach ($esData['data'] as &$mobile){ $computer=MobileComputer::setMobile($mobile['no']); if($rulePosition=='tail'){ App::invokeMethod([$computer,'check_'.$rule['tail']]); $hitTail=$computer->getHits(); $mobile['hits']=MobileComputer::makeHits($mobile['no'],[$hitTail]); }elseif ($rulePosition=='middle'){ App::invokeMethod([$computer,'check_'.$rule['middle']]); $hitMiddle=$computer->getHits(); if($hitMiddle){ $mobile['hits']=MobileComputer::makeHits($mobile['no'],[$hitMiddle]); } }else{ // $mobile['hits']=[]; App::invokeMethod([$computer,'check_'.$rule['tail']]); $hitTail=$computer->getHits(); $hits=MobileComputer::makeHits($mobile['no'],[$hitTail]); $hitResult = false; foreach ($hits as $hit) { if ($hit) { $hitResult = true; break; } } if (!$hitResult) { App::invokeMethod([$computer,'check_'.$rule['middle']]); $hitMiddle=$computer->getHits(); if($hitMiddle){ $hits=MobileComputer::makeHits($mobile['no'],[$hitMiddle]); } } $mobile['hits'] = $hits; } } }elseif(!empty($data['search_type']) && empty($data['rule_name'])){ if(is_array($data['keyword'])){ if(strlen(implode($data['keyword']))==1){ $rule_position = config('site.rule_position'); if($rule_position){ $ruless = MobileConstant::getFilterss(); foreach ($esData['data'] as &$mobile){ $computer=MobileComputer::setMobile($mobile['no']); if($rulePosition=='tail'){ foreach ($ruless as $v){ App::invokeMethod([$computer,'check_'.$v['tail']]); $hitTail=$computer->getHits(); $mobile['hits']=MobileComputer::makeHits($mobile['no'],[$hitTail]); if(!in_array('true',$mobile['hits'])){ App::invokeMethod([$computer,'check_'.$v['middle']]); $mobile['hits']=MobileComputer::makeHits($mobile['no'],[$hitTail]); }else{ break; } // print_r($mobile['hits']); // exit(); } } } } } }elseif (empty($data['keyword'])){ $rule_position = config('site.rule_position'); if($rule_position){ $ruless = MobileConstant::getFilterss(); foreach ($esData['data'] as &$mobile){ $computer=MobileComputer::setMobile($mobile['no']); if($rulePosition=='tail'){ foreach ($ruless as $v){ App::invokeMethod([$computer,'check_'.$v['tail']]); $hitTail=$computer->getHits(); $mobile['hits']=MobileComputer::makeHits($mobile['no'],[$hitTail]); if(!in_array('true',$mobile['hits'])){ App::invokeMethod([$computer,'check_'.$v['middle']]); $mobile['hits']=MobileComputer::makeHits($mobile['no'],[$hitTail]); }else{ break; } // print_r($mobile['hits']); // exit(); } } } } } } // 判断数据有无 $mobile_ids = []; foreach ($esData['data'] as $dv){ $mobile_ids[] = $dv['id']; } $mobile_db_ids=Mobile::whereIn('id',$mobile_ids)->column('id'); // es 需要删除的id $mobile_ids_es_del = array_diff($mobile_ids,$mobile_db_ids); if($mobile_ids_es_del){ EsMobileService::delMobiles($mobile_ids_es_del); user_log("EsMobileService_indexList_delByMobile", $mobile_ids_es_del); $new_Data = []; foreach ($esData['data'] as $idk => $idv){ if(!in_array($idv['id'],$mobile_ids_es_del)){ // unset($esData['data'][$idk]); $new_Data[] = $idv; } } $esData['data'] = $new_Data; } $this->success('',$esData); } /** * 号码详情 * @ApiParams (name=id,description=号码id) * @ApiReturnParams (name=copy_word,description=复制的内容) * @ApiReturnParams (name=card_status,description=1需上传三张身份证照片) */ public function show(){ $data=$this->_validate([ 'id'=>['require'] ]); $user=$this->auth->getUser(); $mobile=Mobile::where('id','id')->with(['info'])->find($data['id']); if(!$mobile){ EsMobileService::delMobiles([$data['id']]); $this->error('您查找的手机号已下架或不存在'); } if($mobile['type']==1) { EsMobileService::addMobile($mobile); } //MobileUserHistory::add($user,$mobile); $mobile->addViewCount(); $mobile->append(['view_count','copy_word']); $mobile->makeHidden(); MobileInfo::makeFreeApp($mobile['info']); $this->success('',$mobile); } /** * 下单 * @ApiMethod (POST) * @ApiParams (name=mobile_id,description=手机号ID) * @ApiParams (name=name,description=姓名) * @ApiParams (name=phone,description=手机号) * @ApiParams (name=sms_code,description=验证码) * @ApiParams (name=id_no,description="身份号码,450804198608275870",sample="450804198608275870") * @ApiParams (name=open_idcard_face_img,description="身份证正面照片",required=false) * @ApiParams (name=open_idcard_back_img,description="身份证反面照片",required=false) * @ApiParams (name=open_face_img,description="脸部照片",required=false) * @ApiParams (name=county,description="城市ID,区县id") * @ApiParams (name=address,description=详细地址) * @ApiParams (name=remark,description=备注) * @ApiParams (name=no,description=选号) * @ApiParams (name=pay_type,description="1微信2支付宝3京东4抖音小程序5快手小程序") * @ApiParams (name=return_url,description="支付完成回调页面链接") * @ApiParams (name=clickid,description="巨量引擎clickid") * @ApiParams (name=platform_source,description="来源平台") * @ApiReturnParams (name=pay_url,description="支付链接") * @ApiReturnParams (name=without_pay,description="是否不需要支付") * @ApiReturnParams (name=res,description="抖音支付时返回参数") */ public function apply(){ $needId=config('site.system_id_form_open')?true:false; $user=$this->auth->getUser(); $data=$this->_validate([ 'mobile_id'=>'require', 'name|姓名'=>['require','max:20'], 'phone|手机号'=>'require|mobile', //'id_no|身份证'=>['require','regex'=>'/^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/'], 'county|地区'=>'require|integer', 'address|详细地址'=>['require','min:4', 'max:100'], ]); if($needId){ $this->_validate([ 'id_no|身份证'=>['require','regex'=>'/^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/'], ]); } Db::startTrans(); $mobile=Mobile::lock(true)->findOrFail($data['mobile_id']); if($mobile['type']==1){ $this->_validate([ 'pay_type'=>'require|in:'.implode(',',array_keys(MobileOrder::$payTypes)), ]); } if($mobile['type'] == 2){ $this->_validate([ 'id_no|身份证'=>['require','regex'=>'/^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/'], ]); if($mobile['card_status']){ $this->_validate([ 'open_idcard_face_img|身份证正面照片' => 'require', 'open_idcard_back_img|身份证反面照片' => 'require', 'open_face_img|脸部照片' => 'require', ]); } $blackListConfig = config('site.flow_blacklist'); if($blackListConfig){ $blackList = []; $blackListTmp = explode("\r\n", $blackListConfig); foreach($blackListTmp as $key=>$val){ $tmpId = explode(' ', $val); if(isset($tmpId[1]) && $tmpId[1]) $blackList[] = $tmpId[1]; } if(in_array($data['id_no'], $blackList)) $this->error('该身份证号已被禁用'); } $flowLimitAgeStart = $mobile['min_age']; $flowLimitAgeEnd = $mobile['max_age']; $birthDay = IdVerify::instance()->getBirthDay($data['id_no']); $age = $this->countAge($birthDay); if($flowLimitAgeStart && $age < $flowLimitAgeStart) $this->error('该身份证号年龄被限制'); if($flowLimitAgeEnd && $age > $flowLimitAgeEnd) $this->error('该身份证号年龄被限制'); if($mobile['send_template']){ if(!Mobile::sendTemplateLimit($mobile, $data['county'])) $this->error('该地区暂不支持订购'); } if($mobile['not_send_template']){ if(Mobile::notSendTemplateLimit($mobile, $data['county'])) $this->error('该地区暂不支持订购'); } } $mobile->shouldBuy(); Area::shouldSend($data['county']); $system_sms_open = config('site.system_sms_open') ? true : false; if($system_sms_open && $mobile->needCheckSmsCode()) { SmsSend::setMobile($data['phone'])->setCode($data['sms_code'] ?? '')->setEvent('order')->check(); } #禁止重复下单 $hasOrder=MobileOrder::where('mobile_id',$mobile->id) ->where('phone',$data['phone']) ->where('create_time','>',time()-10) ->value('id'); if($hasOrder){ Db::rollback(); $this->error('操作频繁'); } // if($needId && Mobile::isType($mobile['type'])){ if(Mobile::isType($mobile['type'])){ // if($needId && !App::$debug) { if($needId || $mobile['type'] == 2) { IdVerify::instance()->check($data['name'] ?? '', $data['id_no'] ?? ''); } if($mobile['type'] == 2){ $orderLimit = config('site.'.$mobile['brand']); if($orderLimit && MobileOrder::orderLimit($data['id_no'], $orderLimit, $mobile['brand'])) $this->error('订购频繁'); } //elseif(MobileOrder::hasOrdered($data['phone'],$mobile)){ elseif(MobileOrder::hasOrdered($data['phone'],$mobile['brand'])){ $this->error('订购频繁1'); } } $order = $data; $order['s_id']=getChanId(); $order['admin_id'] = $mobile['proxy_id']; $order['no'] = array_key_exists('no',$data)?$data['no']:$mobile['no']; $order['city'] = implode(',', Area::getTreeId($data['county'])); $order['amount_original'] = $mobile['amount_original']; $order['amount_hd'] = $mobile['amount']; $order['amount_charge'] = $mobile['amount_charge']; $order['amount'] = $mobile['amount']; $order['amount_di'] = $mobile['amount_di']; $order['amount_base'] = bcsub($mobile['amount'],$mobile['amount_charge']); $order['type'] = $mobile['type']; $order['status'] = 0; $order['platform_source'] = input('platform_source'); $order['api_goods_id'] = $mobile['api_goods_id']; if($user){ $order['user_id']=$user['id']; } unset($order['county'], $order['sms_code']); $mobileOrder = (new MobileOrder); if($mobile['type']==2){ $mobileOrder->flowOrderSubmit(); } $mobileOrder->allowField(true)->save($order); // $mobileOrderProduce = (new MobileOrderProduce()); // if($mobile['api_goods_id'] == 982203315714){ // $mobileOrderProduce->allowField(true)->save($order); // // print_r(7777); // } // exit(); //$succ=$mobileOrder; //if($mobile['type']==1) { $succ = $this->pay($mobileOrder, $data); //} #下架号码 /*$mobile['status']=$mobile::S_DOWN; $mobile->save();*/ Db::commit(); $this->success('', $succ); } /** * 感叹号订单 * @ApiMethod (POST) * @ApiParams (name=no,description=手机号) * @ApiParams (name=order_no,description=订单号) * @ApiParams (name=name,description=姓名) * @ApiParams (name=phone,description=联系人手机号) * @ApiParams (name=id_no,description="身份号码,450804198608275870",sample="450804198608275870") * @ApiParams (name=open_idcard_face_img,description="身份证正面照片",required=false) * @ApiParams (name=open_idcard_back_img,description="身份证反面照片",required=false) * @ApiParams (name=open_face_img,description="脸部照片",required=false) * @ApiParams (name=county,description="城市ID,区县id") * @ApiParams (name=address,description=详细地址) * @ApiParams (name=remark,description=备注) * @ApiParams (name=api_goods_id,description=商品编码) * @ApiParams (name=contact_code,description=触点编码) * @ApiParams (name=create_time,description=创建时间) * @ApiReturnParams (name=pay_url,description="支付链接") * @ApiReturnParams (name=without_pay,description="是否不需要支付") * @ApiReturnParams (name=res,description="抖音支付时返回参数") */ public function gantanSynchronizeOrders(){ // $needId=config('site.system_id_form_open')?true:false; // $user=$this->auth->getUser(); $data=$this->_validate([ 'no|手机号'=>'require', 'order_no|订单号'=>'require', 'name|姓名'=>['require','max:20'], 'phone|联系人手机号'=>'require|mobile', 'id_no|身份证'=>['require','regex'=>'/^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/'], 'county|地区'=>'require|integer', 'address|详细地址'=>['require','min:4', 'max:100'], 'api_goods_id|商品编码'=>['require'], 'contact_code|触点编码'=>['require'], 'create_time|创建时间'=>['require'] ]); Db::startTrans(); $order = $data; // $order['admin_id'] = $mobile['proxy_id']; $order['no'] = $data['no']; $order['city'] = implode(',', Area::getTreeId($data['county'])); // $order['amount_original'] = $mobile['amount_original']; // $order['amount_hd'] = $mobile['amount']; // $order['amount_charge'] = $mobile['amount_charge']; // $order['amount'] = $mobile['amount']; // $order['amount_di'] = $mobile['amount_di']; // $order['amount_base'] = bcsub($mobile['amount'],$mobile['amount_charge']); // $order['type'] = $mobile['type']; $order['status'] = 10; // if($user){ // $order['user_id']=$user['id']; // } unset($order['county']); MobileOrder::insert($order); $mobileOrder = (new MobileOrder); // $mobileOrder->allowField(true)->save($order); // $mobileOrder->info()->save([ // 'mobile'=>$mobileOrder['mobile'], // // 'info'=>$mobileOrder['mobile']['info'], // ]); // } Db::commit(); $this->success('', $order); } /** * 查询订单状态 * @ApiMethod (GET) * * @ApiParams (name=order_no, description=订单编号) * @ApiReturnParams (name=order_no, description="订单编号") * @ApiReturnParams (name=produce_status, description="订单状态: 1. 已开卡, 0.未开卡") * @ApiReturnParams (name=produce_activation, description="激活状态: 1.已激活, 0.未激活") * @ApiReturnParams (name=produce_is_recharge, description="是否首充: 1.已首充, 0.未首充") * @ApiReturnParams (name=first_amount, description="首充金额") * @ApiReturnParams (name=no, description="生产号码") * @ApiReturnParams (name=logistics_numbers, description="物流编号") * @ApiReturnParams (name=failure_reason, description="失败原因") * @ApiReturnParams (name=create_time, description="下单时间") * @ApiReturnParams (name=update_time, description="更新时间") */ public function getOrderStatus() { $orderNo = input('order_no'); if (empty($orderNo)) { $this->error('订单编号不能为空'); } $order = MobileOrder::where([ 'order_no' => $orderNo, 'platform_source' => '敢探号' ])->field([ 'order_no', 'produce_status', 'produce_activation', 'produce_is_recharge', 'first_amount', 'no', 'logistics_numbers', 'failure_reason', 'create_time', 'update_time', ]) ->find(); if (!$order) { $this->error('订单不存在'); } $this->success('', $order); } protected function pay(MobileOrder $mobileOrder,$data,$is_continue=false){ $params = input('param.'); $clickid = $params['clickid'] ?? ''; $data['return_url']=h5_link('pages/PaySuccess/PaySuccess?id='.$mobileOrder['id']); // if($mobileOrder['type']==2){ // OceanEngineService::setQuery(['clickid'=>input('clickid')])->setAddon(['order_no'=>input('clickid')])->form(); // } $succ=[ 'pay_url'=>'', 'id'=>$mobileOrder['id'], 'without_pay'=>0, 'res'=>null, ]; if($mobileOrder['amount']==0){ $succ['without_pay']=1; $mobileOrder->paySuccessCallback(); try { OceanEngineService::setQuery(['clickid'=>$clickid])->setAddon(['order_no'=>$clickid])->shopping(); GantanhaoService::orderPurchase($mobileOrder); }catch (\Exception $e){} return $succ; } $payment=Payment::create([ 'order_no'=>session_create_id(), 'amount'=>$mobileOrder['amount'], 'mobile_order_id'=>$mobileOrder['id'], 'params'=>[ 'clickid'=>$clickid, ] ]); $filename=session_create_id(date('Ymd')); if(!is_dir($dir=RUNTIME_PATH.'/payment/')) { @mkdir($dir, 0777, true); } if($data['pay_type']==1){ $info=Service::submitOrder($payment['amount'], $payment['order_no'],'wechat',"购买手机号{$mobileOrder['no']}", Service::notifyUrl('wechat',$payment['order_no']),$data['return_url']??'','wap'); file_put_contents(RUNTIME_PATH.'/payment/'.$filename,$info->getContent()); $succ['pay_url']=url('/index/index/payment/a/'.$filename,[],true,true); }elseif ($data['pay_type']==2){ $info=Service::submitOrder($payment['amount'], $payment['order_no'],'alipay',"购买手机号{$mobileOrder['no']}", Service::notifyUrl('alipay',$payment['order_no']),$data['return_url']??'','wap'); file_put_contents(RUNTIME_PATH.'/payment/'.$filename,view('alipay',['form'=>$info->getContent()])->getContent()); $succ['pay_url']=url('/index/index/payment/a/'.$filename,[],true,true); }elseif ($data['pay_type']==3){ $jdpay=App::invokeClass(Jdpay::class); $payData=$jdpay->order($payment['order_no'],$payment['amount'],"购买手机号{$mobileOrder['no']}"); $succ=array_merge($succ,$payData); }elseif ($data['pay_type']==4){ if($mobileOrder['platform_source'] == '美美靓号'){ $payData=ByteDancePay::setInfo($payment['order_no'],$payment['amount'],"购买手机号{$mobileOrder['no']}")->get(); $succ['res']=$payData; if(!$is_continue) { $push = new ByteDanceOrderPush(); $push->setOrder($mobileOrder); $push->setPayment($payment); $push->get(); } }else{ $payData=ByteDancePay::setInfo2($payment['order_no'],$payment['amount'],"购买手机号{$mobileOrder['no']}")->getWangKa(); // print_r($payData); $succ['res']=$payData; if(!$is_continue) { $push = new ByteDanceOrderPush(); $push->setOrder($mobileOrder); $push->setPayment($payment); $push->getWangka(); } } }elseif ($data['pay_type']==5){ $getData['access_token'] = $this->_getKsAccessToken(); $getData['app_id'] = config('kuaishou.appid'); $user=$this->auth->getUser(); $postData['open_id'] = Db('user')->where(['id'=>$user['id']])->value('k_openid'); //用户的openid $postData['out_order_no'] = $payment['order_no']; // $postData['total_amount'] = $payment['amount']; $postData['total_amount'] = $payment['amount']*100; $postData['subject'] = "购买手机号{$mobileOrder['no']}"; $postData['detail'] = "购买手机号{$mobileOrder['no']}"; // $postData['attach'] = 'asdfasdf'; $postData['type'] = 1856; $postData['expire_time'] = 172800; $postData['notify_url'] =request()->domain()."/index/payment/notify_ks/order_no/{$payment['order_no']}"; $sign = _makeKsSgin($getData, $postData); $postData['sign'] = $sign; $url = 'https://open.kuaishou.com/openapi/mp/developer/epay/create_order?' . http_build_query($getData); $json = json_encode($postData, 320); $res = jsonPost($url, $json); $resArr=json_decode($res,true); if(!is_array($resArr)){ $this->error('请求支付失败'); } if($resArr['result']!=1){ $this->error($resArr['error_msg'],$postData); } $succ['res']=$resArr['order_info']; } return $succ; } private function _getKsAccessToken() { return AccessToken::get(); } /** * 继续支付 * @ApiParams (name=id,description=订单id) * @ApiParams (name=pay_type,description=支付方式与下单一样) * @ApiParams (name=return_url,description="支付完成回调页面链接") */ public function continue_pay(){ $data=$this->_validate([ 'id'=>['require'], 'pay_type'=>'require|in:'.implode(',',array_keys(MobileOrder::$payTypes)), ]); $mobileOrder=MobileOrder::whereNull('pay_time')->findOrFail($data['id']); $mobileOrder->continuePay(); $succ=$this->pay($mobileOrder,$data,true); $this->success('',$succ); } /** * 订单详情 * @ApiParams (name=id,description=订单id) * @ApiReturnParams (name=no,description=手机号) * @ApiReturnParams (name=order_no,description=订单号) * @ApiReturnParams (name=amount_hd,description=活动价) * @ApiReturnParams (name=amount_original,description=原价) * @ApiReturnParams (name=amount_charge,description=预充) * @ApiReturnParams (name=describe,description=套餐说明) * @ApiReturnParams (name=proxy.wx_qr,description=客服二维码) * @ApiReturnParams (name=name,description=收货人) * @ApiReturnParams (name=phone,description=收货人手机号) * @ApiReturnParams (name=id_no,description=收货人身份证) * @ApiReturnParams (name=address,description=收货地址) * @ApiReturnParams (name=remark,description=备注) * @ApiReturnParams (name=create_time,description=下单时间) * @ApiReturnParams (name=amount,description=订单金额) * @ApiReturnParams (name=trans_name,description=快递名称) * @ApiReturnParams (name=trans_no,description=快递单号) * @ApiReturnParams (name=status,description="0=>'待付款',10=>'已付款',15=>'待发货',17=>'有号码未发货',20=>'待开卡',25=>'已完成',30=>'申请退款',50=>'已关闭',60=>'无号码',70=>'换卡',80=>'争议单',90=>'已退款',100=>'退款驳回',110=>'审核失败'") * @ApiReturnParams (name=reason,description="状态为110审核失败时,敢探号审核失败原因") * @ApiReturnParams (name=open_uploaded,description=是否已上传开卡资料) * @ApiReturnParams (name=open_idcard_face_img,description=身份证正面照) * @ApiReturnParams (name=open_idcard_back_img,description=身份证反面照) * @ApiReturnParams (name=open_face_img,description=头像照) * @ApiReturnParams (name=open_name,description=姓名) * @ApiReturnParams (name=open_id_no,description=身份证号码) * @ApiReturnParams (name=open_phone,description=手机号) * @ApiReturnParams (name=pay_time,description=支付时间) * @ApiReturnParams (name=expire_time,description=过期时间) */ public function order_detail(){ $order = MobileOrder::with(['proxy','info'])->findOrFail(input('id')); $order['proxy'] && $order['proxy']->hidden(['password']); $order['describe'] = $order['info']['info']['describe']??''; $reason = $order['gantanhao_data_notify'] ? json_decode($order['gantanhao_data_notify'], true) : ''; $order['reason'] = $reason ? $reason['reason'] : ''; $this->success('',$order); } /** * 订单列表 * @ApiParams (name=page,description=page) * @ApiParams (name=limit,description=limit) * @ApiParams (name=phone,description="手机号,小程序可不传") * @ApiParams (name=type,description=1靓号2流量卡) * @ApiParams (name=status,description="状态:0待付款10:已付款15:待发货17:有号码未发货20:待开卡25:已完成30:申请退款50:已关闭60:无号码70:换卡80:争议单90:已退款100:退款驳回110:审核失败") * @ApiSummary (流量卡状态15:已提运营25:已完成) */ public function order_list(){ $user=$this->auth->getUser(); $data=input(); $this->_validate([ 'type|类型'=>['in:1,2'], ]); if(!$user){ $this->_validate([ 'phone|手机号'=>['require'], ]); } $type=$data['type']??1; $type=$type?:1; $order=MobileOrder::with(['proxy','info']) ->where(function ($q)use ($user,$data){ if(!empty($data['phone'])){ $q->where('phone',$data['phone']); }elseif ($user){ $q->where('user_id',$user['id']); }else{ $q->where('id',1); } }) ->filterShow($type) ->where('type',$type) ->order('id','desc'); if(isset($data['status']) && $data['status']!==''){ if($data['status']==0){ $status=[ $data['status'],17,60,70,80, ]; $order->whereIn('status',$status); }else { $order->where('status', $data['status']); } } $ret=$order->paginate(input('limit',15)); $this->success('',$ret); } /** * 筛选配置 * */ public function config(){ $config=[]; $networks=MobileConstant::getNetworkString(); $config['network']=$networks; $config['rule']=MobileConstant::getRuleKeys(); $this->success('',$config); } /** * 上传开卡资料 * @ApiParams (name=id,description=订单id) * @ApiParams (name=idcard_face_img,description=身份证正面照片) * @ApiParams (name=idcard_back_img,description=身份证反面照片) * @ApiParams (name=face_img,description=本人照片) * @ApiParams (name=name,description=本人姓名) * @ApiParams (name=id_no,description=本人身份证号码) * @ApiParams (name=phone,description=本人联系电话) */ public function upload_identity(){ $data=$this->_validate([ 'id'=>['require'], 'idcard_face_img|身份证正面照片'=>['require','url'], 'idcard_back_img|身份证反面照片'=>['require','url'], 'face_img|本人照片'=>['require','url'], 'name|本人姓名'=>['require','max:10'], 'id_no|本人身份证号码'=>['require'], 'phone|本人联系电话'=>['require','integer'], ]); $order=MobileOrder::findOrFail($data['id']); if($order['open_uploaded']){ $this->error('请勿再次上传'); } IdVerify::instance()->check($data['name'],$data['id_no']); $order['open_uploaded']=1; $order['open_idcard_face_img']=$data['idcard_face_img']; $order['open_idcard_back_img']=$data['idcard_back_img']; $order['open_face_img']=$data['face_img']; $order['open_name']=$data['name']; $order['open_id_no']=$data['id_no']; $order['open_phone']=$data['phone']; if(!$order->save()){ $this->error('保存失败'); } $this->success(''); } /** * 预定号码 * @ApiParams (name=no,description=号码) * @ApiParams (name=price_min,description=最低承受价格) * @ApiParams (name=price_max,description=最高承受价格) * @ApiParams (name=remark,description=备注) * @ApiParams (name=name,description=姓名) * @ApiParams (name=phone,description=联系电话) * @ApiParams (name=county,description=区县ID) * @ApiParams (name=address,description=详细地址) */ public function order_no(){ $data=$this->_validate([ 'no|预定号码'=>['require','integer','min:3','max:8'], //'price_min'=>['require','integer','min:0'], 'price_max|可承受价格'=>['require','integer','min:0'], 'name|姓名'=>['require'], 'phone|联系电话'=>['require','integer','length:11'], 'county|城市'=>['require','integer'], 'address|详细地址'=>['require','length:0,250'], ]); $no=new MobileOrderNo; $data['city']=implode(',',Area::getTreeId($data['county'])); $no->allowField(true)->save($data); $this->success(''); } /** * 横幅播报 * @ApiReturnParams (name=ordered_num,description=已订购人数) * @ApiReturnParams (name=no,description=号码) * @ApiReturnParams (name=name,description=人名) * @ApiReturnParams (name=num,description=人数) */ public function ordered_show(){ $data=[]; $data['ordered_num']=SysConfig::look('mo_ordered_num',0); $data['ordered_list']=AdIndexOrderedFlow::field('name,no,num') ->order('num','asc') ->select(); foreach ($data['ordered_list'] as $item){ $item['no']=substr($item['no'],0,3).'****'.substr($item['no'],7,4); $item['name']=mb_substr($item['name'],0,mb_strlen($item['name'])-1).'*'; } $this->success('',$data); } /** * 退款 * @ApiMethod (POST) * @ApiParams (name=id,description=订单id) * @ApiParams (name=reason,description=退款原因) */ public function refund(){ $data=$this->_validate([ 'id'=>'require', 'reason'=>'require|max:250', ]); Db::startTrans(); $order=MobileOrder::lock(true)->findOrFail($data['id']); $order->checkAllowRefund(); $order->makeUserRefund($data['reason']); Db::commit(); $this->success(); } /** * 查询物流 * @ApiMethod (POST) * @ApiParams (name=id,description=订单id) * @ApiReturnParams (name=AcceptTime,description=时间) * @ApiReturnParams (name=AcceptStation,description=描述) */ public function logistics(){ $data=$this->_validate([ 'id'=>['require'], ]); $order=MobileOrder::findOrFail($data['id']); $logistics=[]; if(!$order['trans_id']||!$order['trans_no']){ $this->success('',$logistics); } $logistics=TransferCheck::instance()->setNo($order['trans_no'])->setLogisticsCompany(LogisticsCompany::get($order['trans_id']))->setPhone($order['phone'])->setName($order['name'])->get(); $this->success('',$logistics); } /** * 预占号码 * @ApiParams (name=id,description=号码ID) * @ApiParams (name=chanId,description=通道ID) */ public function take(){ $data=$this->_validate([ 'id|号码'=>['require','gt:0'], ]); $open=config('site.auto_take_open'); $discount=config('site.auto_take_discount'); if(!$open){ $this->success('未开启'); } if($discount<=0||$discount>10){ $this->success('参数错误'); } Db::startTrans(); $mobile=Mobile::lock(true)->findOrFail($data['id']); if($mobile['is_activity']){ Db::rollback(); $this->success('已开启'); } $chanId=getChanId(); $amount_kill=bcmul($mobile['amount_base'],$discount/10,0); $mobile->makeActivity($amount_kill,$chanId); Db::commit(); $this->success('改价成功'); } /** * 流量卡上传身份证照片 * @ApiMethod (POST) * @ApiParams (name=id,description=订单id) * @ApiParams (name=idcard_face_img,description=身份证正面照片) * @ApiParams (name=idcard_back_img,description=身份证反面照片) * @ApiParams (name=face_img,description=本人照片) */ public function upload_identity_flow(){ $data = $this->_validate([ 'id'=>['require'], 'idcard_face_img|身份证正面照片'=>['require','url'], 'idcard_back_img|身份证反面照片'=>['require','url'], 'face_img|本人照片'=>['require','url'] ]); $order = MobileOrder::findOrFail($data['id']); $dataGantanhao = $order['gantanhao_data'] ? json_decode($order['gantanhao_data'], true) : []; if(!$dataGantanhao || !isset($dataGantanhao['str_rand']) || !$dataGantanhao['str_rand']){ $this->error('暂无法重新上传'); } try{ GantanhaoService::orderPhotos($dataGantanhao['str_rand'], $data); $order['open_idcard_face_img'] = $data['idcard_face_img']; $order['open_idcard_back_img'] = $data['idcard_back_img']; $order['open_face_img'] = $data['face_img']; $order->save(); } catch(\Exception $e){ if(stripos($e,'413')){ $this->error('图片过大'); } Log::error("流量卡上传身份证照片:".json_encode($e)); $this->error('保存失败'); } $this->success('上传成功'); } /** * 计算年龄 */ private function countAge($birthDay = ''){ if(!$birthDay) return false; $age = strtotime($birthDay['year'].$birthDay['month'].$birthDay['day']); if($age === false) return false; list($y, $m, $d) = explode('-', date('Y-m-d')); $age = $y - $birthDay['year']; if((int)($m.$d) < (int)($birthDay['month'].$birthDay['day'])) $age -= 1; return $age; } public function test(){ dump(ROOT_PATH); dump(parse_url('https://lh.hdlkeji.com/uploads/20230221/0866987639c981b0f59dcc43cdffdc16_hr5n1hkhdap6gcadj63eh7vrmg.jpeg')); } /** * 选号 * @ApiMethod (POST) * @ApiParams (name=product_no,description=产品编码) */ public function select_num_flow(){ $data = $this->_validate([ 'product_sku'=>['require'], ]); $list = GantanhaoService::getSelectNum($data['product_sku']); $this->success('成功',$list); } //es缓存测试 public function es_ceshi(){ $mobile = Mobile::where('id',142519741)->with(['info'])->find(); // $mobile=Mobile::where('id','id')->with(['info'])->find($data['id']); EsMobileService::addMobile($mobile); // $mobile['amount']=intval($mobile['amount']); // $mobile['amount'] = $a; // dump($mobile['amount']); // EsMobileService::delMobiles([$mobile['id']]); // EsMobileService::addMobiles($mobile); // EsMobileService::delMobile($mobile); // $mobile=Mobile::where('id','id')->with(['info'])->find($data['id']); // print_r(EsMobileService::get(13155666082)); } }