track_no:原始单号 | expresses : 订单表
========================新 添 加 的 东 西 [ 接 口 interface ] ==================
下单API: 查询老窖运单&并下单 【Get】

http://127.0.0.1:8000/api/express/lzlj/query?start=2022-11-07 06:00:00&end=2022-11-08 06:00:00

========================新 添 加 的 东 西 [ 路 由 rout ] ==================

tms-sheet/-/tree/develop [LZLJ_QUERY.md]
泸州老窖下单
/api/routes
/console.php下:
/api.php下: 第 128 行[Post]:$router->post('express/lzlj/query', [ExpressController::class, 'lzljQuery']);
第 148 行[get]: $router->get('express/lzlj/query', [ExpressController::class, 'lzljQuery']);
一个带admin(上,需登录),一个不带admin(下,不需登录)。

========================新 添 加 的 东 西 [ 控 制 器 controller] ==================
api/app/Http/Controllers/ExpressController.php:第42行

//应该是在Apipost–>body—>raw中传入[JSON],代表请求数据

{
	"key": "test",
	"secret": "done",
	"sign": "xxxx",
	"time": 1666672744000,
	"param": {
		"rec": {
			"name": "张三",
			"mobile": "13888888888",
			"address": "广东深圳市南山区金蝶软件园"
		},
		"send": {
			"name": "李四",
			"mobile": "13888888888",
			"address": "广东深圳市南山区金蝶软件园"
		},
		"cargo": "test", //文件名
		"remark": "测试下单,请勿发货",
	}
}

—/api/express/lzlj/query?start=2022-11-07 06:00:00&end=2022-11-08 06:00:00

public function LzljQuery(Request $request)
 {
        try {
	//获取原始单号
            $track_no = $request->get('track_no');
	//获取开始时间戳,地址url 传过来的
            $start = $request->get('start');
	//获取结束时间戳,地址url 传过来的
            $end = $request->get('end');
	//如果原始单号不为空【工程化】
            if (!$track_no) {
	//如果开始时间戳或者结束时间戳为空那么报错~【为什么知道需要传这两个值,应该是从前端看的】
                if (!$start || !$end) {
	    //badRequest是写在model控制器中的
                    return $this->badRequest('查询泸州老窖订单,无订单号请传入开始和截止时间!');
                } else {
                    // 接受的是时间戳参数 字符串 转 时间
                    $start = strtotime($start) * 1000;
                    $end = strtotime($end) * 1000;
                }
            }
	//LZLJProxy这个是业务类,看不懂很多
            $res = LZLJProxy::getExpress($track_no, $start, $end);
            if ($res['RESULT'] === "FAILURE") {
                return $this->badRequest($res['MESSAGE']);
            } else {
                $waitInserts = LZLJProxy::formatter($res['DATA']);
                $i = 0;
                foreach ($waitInserts as $key => $save) {
                    $d = $this->model::firstOrCreate(['origin_hash' => $save['origin_hash']], $save);
                    $d->wasRecentlyCreated ? $i++ : 0;
                }
                // 返回新增的条数
                return $this->dataSuccess($i);
                // return $this->dataSuccess($res['DATA']);
            }
            //code...
        } catch (\Throwable $th) {
            //throw $th;
            dd($th);
            return $this->badRequest($th->getMessage());
        }
 }

》》》》》》》》》》》》》》》》》》》》》》—-LZLJProxy—-》》》》》》》》》》》》》》》》》》》》》》》

<?php

namespace App\Services\LZLJ;

use App\Models\Express;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class LZLJProxy
{
    // 订单同步 API
    const ENVURL = [
        'dev' => 'http://wwesbtest.lzlj.com/WP_LZLJ_SOA/APP_YZ_SERVICES/Proxy_Services/',
        // 'pro' => 'http://wwesbtest.lzlj.com/WP_LZLJ_SOA/APP_YZ_SERVICES/Proxy_Services/',
    ];
    // -->USERID (用户ID)
    const USERID = 10000;
    // -->COMPANYID (公司ID)
    const COMPANYID = 10000;
    // -->EMERGENCY (紧急情况) 数组
    const EMERGENCY = [
        '常规' => 0,
        '紧急' => 1,
    ];
    // -->url-->在构造中赋值,后边
    public $url;
    // -->CityProvince-->空数组
    const CityProvince = [];

    // 构造【将env存,和当前对象的url存 self::ENVURL[$env]-->self::ENVURL[dev]--->也就是获取到了上边那个!奥这里是为了只修改上边的变量就能切换环境应该是!】
    // 什么情况下 会有多个目的地
    public function __construct()
    {
        $env = 'dev';
        $this->url = self::ENVURL[$env];
    }
    //获取表示?三参:原始订单ID、开始时间、结束时间、承运人密钥【承运人是指本人或者委托他人以本人名义与托运人订立海上货物运输合同的人】
    public static function getExpress($TRACK_NO = null, $START_DATE = null, $END_DATE = null, $CARRIER_KEY = null)
    {
        // 测试环境使用 【https://www.cnblogs.com/huilange/p/3380613.html——CONF_PATH 项目配置文件目录地址,APP_PATH 项目地址】
        $file = app_path('../LZLJ_QUERY.md');
        // https://www.runoob.com/php/func-filesystem-fopen.html【fopen() 函数打开一个文件或 URL。】
        $fp = fopen($file, 'r');
        // https://www.runoob.com/php/func-filesystem-fread.html 【fread() 函数读取打开的文件。】
        $str = fread($fp, filesize($file));
        // https://blog.csdn.net/weixin_31767787/article/details/115592962 【用于解码JSON字符串。它将JSON编码的字符串转换为PHP变量】
        return json_decode($str, 1);
        // 测试环境使用
        // https://www.csdn.net/tags/NtDaYgxsMDQ0LWJsb2cO0O0O.html 【当使用env()函数获取 .env文件中的值时 ,开发环境都是正常的 ,线上服务获取的是null】
        $env = env('LZLJENV', 'dev');
        // appurl --> appurl地址
        $appurl = 'TA_OSB/LZLJ_1143_YZ_OrderSynchronize_PS';
        
       // http://www.phpxs.com/post/6742/ 【array_get()函数使用点符号从多维数组中检索值】
       // self::ENVURL--->是上边的那个dev url常量,$env 是环境
        $preurl = array_get(self::ENVURL, $env, 'env');
       // 上个变量能点出东西,就是因为array_get
        $url = $preurl . $appurl;
        // dd($url); //测试的应该是
        // 查询数据数组 $queryData
        $queryData = [];
       // 第三个参数承运人是否为空
        if ($CARRIER_KEY) {
            // 
            $queryData['CARRIER_KEY'] = $CARRIER_KEY;
        } else {
            // 
            $queryData['CARRIER_KEY'] = '10019033';
        }
        //第一个参数:原始订单ID
        if ($TRACK_NO) {
            $queryData['TRACK_NO'] = $TRACK_NO;
        }
        //第二个参数:开始时间戳
        if ($START_DATE) {
            $queryData['START_DATE'] = $START_DATE;
        }
       //第三个参数:结束时间戳
        if ($END_DATE) {
            $queryData['END_DATE'] = $END_DATE;
        }
       //self::setReqHeader: 是在调用下边的函数,只要看到self:: 就是自己的对象,然后双冒号往往就是自己的方法, 参数: $queryData 数组
        $headers = self::setReqHeader($queryData);
       //关联数组 定义给 postD 第一个参数是$headers[上边],$queryData[也是一个关联数组]
        $postD = ['REQUEST' => ['HEAD' => $headers, 'LIST' => $queryData]];
       // http://t.zoukankan.com/johnson108178-p-8023972.html
       // Log::info:Laravel记录多日志,使用 Log::info() 会让日志全部记录在 storage/logs/laravel.log 文件里
        Log::info('泸州请求:' . $url, $postD);
       // 调用另一个函数,为什么有的时候,用self::调,有的时候可以直接调?好像当函数是静态的时候,或者是变量是const修饰的时候就用self::
        return glz($url, $postD, 'POST');
    }
    // setReqHeader() 函数,两个参数,一个:$data,一个$count
    public static function setReqHeader($data, $count = null)
    {   // https://www.runoob.com/php/php-date.html
        // https://blog.csdn.net/lmp5023/article/details/101297195 【PHP date() 函数可把时间戳格式化为可读性更好的日期和时间。】
        $date = date('Y-m-d H:i:s');
        // resHeader(结果header) : 键值数组
        $resHeader = [
            "ACCOUNT" => "YD",
            "PASSWORD" => null,
            "CONSUMER" => "YD",
            "REQUESTDATE" => $date,
            "BIZTRANSACTIONID" => "LZLJ_YDOTB_" . date('YmdHis') . Str::limit(time(), 3, ''),
            // 20181109 112002 167
            "SRVLEVEL" => "OTB",
        ];
        // 当使用env()函数获取 .env文件中的值时 ,开发环境都是正常的 ,线上服务获取的是null】env是从哪里获取值的
        $LZPWD = env('LZPWD', 'System1qaz*');
        // 
        $LZSALT = env('LZSALT', '&%5123***&&%%$$#@');
        // 签署 (数组中的用户),密码,日期点盐--》字符串拼接
        $signed = md5($resHeader['ACCOUNT'] . $LZPWD . $date . $LZSALT);
        // 签署 数组中的密码
        $resHeader['PASSWORD'] = $signed;
        // $count 是订单数量吗???
        if ($count) {
            // 直接在原有键值数组中再加一个键和值? 增加元素
            $resHeader['COUNT'] = $count;
        }
       // 返回数组【结合下边的参数:真实resHeader中的键,应该也是数据库express表中必传的字段】
        return $resHeader;
        // COUNT(必传):交易数量,明确单次数据交互的条目,用于业务检查。对于查询服务无法确定交易数量的不必提供(传多少条数据)
        // CONSUMER(必传):调用此服务的系统标识(系统名称)
        // SRVLEVEL(必传):服务级别,值为1时,记录调用日志并落地报文;值为2时,记录调用日志但不落地报文;值为3时,不记录调用日志也不落地报文(默认1)
        // ACCOUNT:本次调用此服务的系统用户名(OSB初始配置给某系统的用户名???)
        // PASSWORD:本次调用使用的系统用户密码(OSB初始配置给对应系统的用户密码,该密码可以用MD5加密后的密码)
    }
    // 同步路由 
    public static function syncRoute()
    {
        // $dev:是同步url,当这个是字符串,?
        $env = env('LZLJENV', 'dev');
        // appurl--->
        $appurl = 'TA_OSB/LZLJ_1144_YZ_BaseOrderFeedback_PS';
        // preurl--->
        $preurl = array_get(self::ENVURL, $env, 'env');
        // url 为 前两者的拼接
        $url = $preurl . $appurl;
        // data 数据数组(包含): 响应中的数据
        $data = [
            // 	轨道NO
            "TRACK_NO" => "",
            //  状态
            "STATUS" => "",
            // 时间节点
            "NODETIME" => "",
            // 操作人员
            "OPERATOR" => "",
            // 操作人员时间
            "OPERATORTIME" => "",
            // 描述
            "DESCRIPTION" => "",
            // 接收者
            "RECEIVER" => "",
            // 条形码
            "SMSCODE" => "",
            // 运输码
            "TRANSPORTCODE" => "",
            // 传输名称
            "TRANSPORTNAME" => "",
            // 延申
            "EXTEND1" => "",
            "EXTEND2" => "",
            "EXTEND3" => "",
            "EXTEND4" => "",
            "EXTEND5" => "",
            "EXTEND6" => "",
            "EXTEND7" => "",
            "EXTEND8" => "",
            "EXTEND9" => "",
            "EXTEND10" => ""
        ];
        // 获取一条(count=1)数据,
        $headers = self::setReqHeader($data, 1);
        // 应该是单件反馈【glz是在api/app/Helpers/index.php中的一个函数】
        return glz($url, $data, 'POST', $headers);
    }

    /** 
     * 地址结构体
     * `rec_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人名',
     * `rec_mobile` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人电话',
     * `rec_address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人地址',
     * `rec_province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人省份',
     * `rec_city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人市',
     * `rec_district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人区县',
     * `rec_lng` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人经度',
     * `rec_lat` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人纬度',
     * `send_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人名',
     * `send_mobile` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人电话',
     * `send_address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人地址',
     * `send_province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人省份',
     * `send_city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人市',
     * `send_district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人区县',
     * `send_lng` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人经度',
     * `send_lat` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人纬度',
     */
    // 泸州数据
    public static function formatter($datas)
    {
        // dd($datas);
        $sendAddress = [
            'company_id' => self::COMPANYID,
            'user_id' => self::USERID,
            'send_name' => '泸州老窖销售有限公司',
            'send_mobile' => '0830-2752111',
            'send_address' => '四川省泸州市龙马潭区鱼塘街道望江路11号',
            'send_province' => '四川省',
            'send_city' => '泸州市',
            'send_district' => '龙马潭区',
        ];
        $d = [];
        foreach ($datas as $data) {
            // dd($data);
            $temp['origin_data'] = $data;
            $temp['origin_hash'] = md5(json_encode($data));
            $temp['track_no'] = $data['TRACK_NO'];
            $temp['num'] = getUniqueNum(Express::class, 'num', 'LZ');
            $temp['level'] = self::EMERGENCY[$data['EMERGENCY']] ?? 0;

            $temp['rec_name'] = $data['TONAME'];
            $temp['rec_mobile'] = $data['TOMOBILE'];
            $temp['rec_address'] = $data['TOADDRESS'];
            $temp['rec_province'] = $data['TOPROVINCE'];
            $temp['rec_city'] = $data['TOCITY'];
            $temp['rec_district'] = $data['TOAREA'];

            $temp['cargo'] = array_get($data['DETAILS'], 'ITEM_NAME');
            $temp['pay_type'] = 0;
            $temp['insure_value'] = 0;
            if (isset($data['PLAN_ARRIVAL_DATE']) && $data['PLAN_ARRIVAL_DATE']) {
                $temp['expecte_at'] = $data['PLAN_ARRIVAL_DATE'];
            }

            $temp['send_name'] = $data['SALES_NAME'];

            $d[] = array_merge($sendAddress, $temp);
        }
        return $d;
    }
    /** 
     * type send/done
     */
    public static function getAreaId($addr, $type = 'send')
    {
        $areaKey = 'areas';
        $areas = cacheGet($areaKey);
        if (!$areas->count()) {
            return 0;
        }
        $addLngLat = $addr['lng'] && $addr['lat'] ? [$addr['lng'], $addr['lat']] : getGeoLocation($addr['address'] . $addr['full_address']);
        $area = getArea($areas->sortBy('priority_' . $type), $addLngLat);
        $addr['area_id'] = $area->id ?? 0;
        $formatAddr = [];
        foreach ($addr as $key => $value) {
            $formatAddr[$type . '_' . $key] = $value;
        }
        return $formatAddr;
    }
}

========================新 添 加 的 东 西 [ 模 型 modle ] ==================
/api/app/Models下: 不怎么知道模型该怎么写~
泸州老窖下单 2个:Company.php、Express.php

Company.php

<?php
namespace App/Models;
use Osi\LaravelControllerTrait\Models\FilterAndSorting;
class Company extends BaseModel
{
  use FilterAndSorting;
  protected $guarded = [];
  protected $casts = [
    'options' => 'json',
  ];
}

Express.php

<?php
namespace App/Models;
use Osi\LaravelController\Models\FilterAndSorting;
class Express extends BaseModel
{
  use FilterAndSorting;
  protected $guarded = [];
  protected $hidden = ['origin_data'];
  
  const PRE_STATUS = [
    0  => 'SHIP',
    10 => 'SHIP',
        50 => 'INTRANSIT',
        90 => 'ARRIVE',
        100 => 'SIGE',
        110 => 'RETURN',
    ];
   const PRE_STATUS_CN = [
        0 => '待发',
        10 => '发运',
        50 => '在途',
        90 => '运抵',
        100 => '签收',
        110 => '退件入库',
    ];
    // 运抵:ARRIVE
    // 签收:SIGE
    // 发运:SHIP
    // 在途:INTRANSIT
    // 退件入库:RETURN

    const STATUS_CN = [
        0 => '待发',
        10 => '发运',
        50 => '在途',
        90 => '运抵',
        100 => '签收',
        101 => '退件中',
        110 => '退件入库',
    ];
    protected $casts = [
        'origin_data' => 'json',
        'carrier_data' => 'json'
    ];
    public function router_latest()
    {
        return $this->hasOne(Router::class)->latest()->first();
    }
    public function router()
    {
        return $this->hasMany(Router::class);
    }
    public function print_latest()
    {
        return $this->hasOne(ExpressPrint::class)->latest()->first();
    }
    public function print_log()
    {
        return $this->hasMany(ExpressPrint::class);
    }
    public function change_log()
    {
        return $this->hasMany(ExpressChange::class);
    }
    public function carrier()
    {
        return $this->belongsTo(Carrier::class);
    }

    public static function cancelFromOtb($express)
    {
      if($express->status > 50){
            return false;
        }
        $express->status = 101;
        $express->save();
        return true;
    }
}

========================新 添 加 的 东 西 [ 中 间 件 Middleware ] ==========================
api/app/Http/Middleware/LZLJApiMiddleware.php

LZLJApiMiddleware.php

原文地址:http://www.cnblogs.com/Where-am-i/p/16887713.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性