Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 70
LogisticNumberFeatureController
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 12
812.00
0.00% covered (danger)
0.00%
0 / 70
 index
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 create
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 store
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 show
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 edit
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 update
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 destroy
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 apiComputeLogisticByNumber
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getLogisticByFeatures
0.00% covered (danger)
0.00%
0 / 1
72.00
0.00% covered (danger)
0.00%
0 / 25
 createFeatures
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 16
 createFeature
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 11
 loadRecentRejectedsToFeatures
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 6
<?php
namespace App\Http\Controllers;
use App\Logistic;
use App\LogisticNumberFeature;
use App\Rejected;
use App\RejectedBill;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class LogisticNumberFeatureController extends Controller
{
    public function index()
    {
        //
    }
    public function create()
    {
        //
    }
    public function store(Request $request)
    {
        //
    }
    public function show(LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }
    public function edit(LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }
    public function update(Request $request, LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }
    public function destroy(LogisticNumberFeature $logisticNumberFeature)
    {
        //
    }
    public function apiComputeLogisticByNumber(Request $request)
    {
        $logisticNumber=$request->input('logistic_number_return');
        $logistic=$this->getLogisticByFeatures($logisticNumber);
        if(!$logistic){
            return ['success'=>'false',];
        }
        return ['success'=>'true','logistic'=>$logistic];
    }
    private function getLogisticByFeatures(string $logisticNumber)
    {
        $numberLength=strlen($logisticNumber);
        $char0 = mb_strcut($logisticNumber, 0, 1);
        $logistic_items = DB::table(DB::raw("(select logistic_id,updated_at from logistic_number_features as a where logistic_id in (select logistic_id from
             (select logistic_id from logistic_number_features where name='length' and value='$numberLength') feLen) and
             (name='char0' and value='$char0')) as tableA")
        )->get();
        $targetsIds=$logistic_items->map(function($id){return $id->logistic_id;})->unique()->toArray();
        for ($i=1;$i<LogisticNumberFeature::$featureConsideringLength;$i++){
            if(count($targetsIds)<=1)break;
            $paramName='char'.$i;
            $$paramName = mb_strcut($logisticNumber, 0, 2);
            $logistic_itemsTemp=LogisticNumberFeature::select(['logistic_id','updated_at'])->where('name',$paramName)
                ->where('value',$$paramName)->whereIn('logistic_id',$targetsIds)->get();
            if($logistic_itemsTemp->isNotEmpty()){
                $targetsIds=$logistic_itemsTemp->map(function($id){return $id->logistic_id;})->unique()->toArray();
                $logistic_items=$logistic_itemsTemp;
            }
        }
        if(count($targetsIds)==0)return null;
        $result_logistic_id=$targetsIds[0];
        if(count($targetsIds)>1){
            $finalTarget=$logistic_items->reduce(function ($carry,$item){
               if($carry){
                   if($carry->updated_at > $item->updated_at){
                       return $carry;
                   }
                   return $item;
               }
               return $item;
            });
            $result_logistic_id=$finalTarget->logistic_id;
        }
        return Logistic::find($result_logistic_id);
    }
    public function createFeatures(string $logisticNumber,int $logisticId)
    {
        $logisticNumber = trim($logisticNumber);
        $featureConsideringLength=LogisticNumberFeature::$featureConsideringLength;
        $numberLength=strlen($logisticNumber);
        if($numberLength<$featureConsideringLength)
            $featureConsideringLength=$numberLength;
        if(!$logisticNumber){
            $this->log(__METHOD__, 'error', '创建退货快递单号特征时,单号传入了空值');
            return null;
        };
        $featuresCreated=[];
        $feature=$this->createFeature($logisticId,'length',$numberLength,100);
        if($feature)$featuresCreated[]=$feature;
        for($i=0;$i<$featureConsideringLength;$i++){
            $chars=mb_strcut($logisticNumber,0,$i+1);
            $feature=$this->createFeature($logisticId,"char$i",$chars,99-$i);
            if($feature)$featuresCreated[]=$feature;
        }
        return $featuresCreated;
    }
    private function createFeature(int $logisticId,string $featureName, string $value,int $weight)
    {
        if(!$value){
            $this->log(__METHOD__, 'error', "创建退货快递单号特征{$featureName}时,特征值为空");
            return null;
        };
        $feature=LogisticNumberFeature::where('logistic_id',$logisticId)
            ->where('name',$featureName)->where('value',$value)->first();
        if($feature){
            $feature->touch();
        }else{
            $feature=new LogisticNumberFeature(['logistic_id'=>$logisticId,'name'=>$featureName,'value'=>$value,'weight'=>$weight]);
            $feature->save();
            return $feature;
        }
        return null;
    }
    static public function loadRecentRejectedsToFeatures($days,$limit){
        $rejecteds=RejectedBill::where('created_at','>',Carbon::today()->subDays($days))->limit($limit)->get();
        $featureController=new LogisticNumberFeatureController();
        $rejecteds->each(function ($rejected)use($featureController){
            if($rejected['logistic_number_return'])
                $featureController->createFeatures($rejected['logistic_number_return'],$rejected['id_logistic_return']);
        });
    }
}