Prechádzať zdrojové kódy

部署京东SDK和接口

reloadnike 2 rokov pred
rodič
commit
079cef7ee5

+ 652 - 0
App/Com/JdSdk.php

@@ -0,0 +1,652 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: LZP
+ * Date: 2022/4/14
+ * Time: 15:21
+ */
+namespace App\Com;
+
+use App\Com\Redis;
+use App\Models\JdConfig;
+use EasySwoole\EasySwoole\Logger;
+
+class JdSdk
+{
+    protected $host = "https://bizapi.jd.com";
+    protected $edition = "";
+
+    protected $grant_type = "access_token";
+    protected $scope = "";
+
+
+
+    protected $time_stamp = "";
+
+//    protected $client_id = 'FlCa4YWCw3m7XcrD2ki0';
+//    protected $client_secret = 'zWkZHHRc6hwJmCy0XRQq';
+
+    // 企业内购
+//    protected $username = '中航物业VOP';
+//    protected $password = '123000';
+
+    // 福利商城
+//    protected $username = '中航物业员工福利';
+//    protected $password = '123000';
+
+    protected $client_id = '';
+    protected $client_secret = '';
+
+    protected $username = '';
+    protected $password = '';
+
+
+    protected $access_token = "NIwoLn95BLs0ZdKLyawIiuFPM";
+
+    protected $timeout = 30;
+    protected $connecttimeout = 30;
+    protected $ssl_verifypeer = FALSE;
+    protected $useragent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36';
+    protected $format = 'form';// form || json
+    protected $decode_json = true;
+    protected $debug = false;
+    protected $params_base = array();
+
+    protected $redis = null;	//redis客户端
+
+    protected static $boundary = '';
+
+    function __construct()
+    {
+
+        $this->time_stamp = date('Y-m-d H:i:s', time());//时间 yyyyMMddhhmmss
+//        $this->params_base['IMEI']          = '0000';//设备串号(移动终端设备串号,默认0000)
+//        $this->params_base['apiVersion']    = $this->api_version;//接口版本号(服务端向下版本兼容控制),默认值为1
+//        $this->params_base['SIGN']          = md5($this->params_base['IMEI']."&".$this->client_id."&".$this->params_base['timeStamp']);
+
+//        echo $this->params_base['IMEI']."&".$this->client_id."&".$this->params_base['timeStamp'];
+
+        // 设定default时产生
+
+        //加载redis
+        $this->redis = Redis::getInstance()->getConnect();
+
+        //从redis中拿参数..这些参数来自于数据库ims_superdesk_jd_vop_configs表..然后设置默认的时候存到了redis    zjh 2018年8月17日 14:22:06
+        $key      = 'superdesk_jd_vop_' . 'web_jd_vop_configs_manage' . ':' . 17;
+        $api_conf = $this->redis->get($key);
+
+        if (!empty($api_conf)) {
+            $api_conf = json_decode($api_conf, true);
+
+            $this->client_id     = $api_conf['client_id'];
+            $this->client_secret = $api_conf['client_secret'];
+            $this->username      = $api_conf['username'];
+            $this->password      = $api_conf['password'];
+        } else {
+
+            $api_conf = JdConfig::create()->where('is_default',1)->get()->toArray();
+
+            if(!empty($api_conf)){
+                $this->client_id     = $api_conf['client_id'];
+                $this->client_secret = $api_conf['client_secret'];
+                $this->username      = $api_conf['username'];
+                $this->password      = $api_conf['password'];
+            } else {
+                //手动配置 201998
+                $this->client_id     = 'nuAeRH1KFlSeiIrfPYTZ';
+                $this->client_secret = 'ioyqcauADf0v3ayE73I5';
+                $this->username      = '中航物业员工福利';
+                $this->password      = 'avic-s';
+            }
+        }
+
+
+    }
+
+
+    function init_access_token()
+    {
+
+        global $_W;
+
+        /******************************************************* redis *********************************************************/
+
+        $table__key = 'superdesk_jd_vop_' . 'sdk_access_token' . ':' . 17;
+        $colunm_key = 'jd_vop_access_token';
+
+        //microtime_format('Y-m-d H:i:s.x',microtime())
+
+
+        $result = $this->redis->hget($table__key, $colunm_key);
+
+        $result = json_decode($result, true);
+
+//        echo json_encode($result,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
+
+        if (empty($result) || empty($result['result'])) {
+            $result = $this->access_token();
+            $this->redis->hset($table__key, $colunm_key, $result);
+            $result = json_decode($result, true);
+        }
+
+        if (intval(floatval($result['result']['time']) / 1000) + intval($result['result']['expires_in']) <= time()) {
+
+            $result = $this->refresh_token($result['result']['refresh_token']);
+            $this->redis->hset($table__key, $colunm_key, $result);
+
+            // BUG 当要去刷时 $result 变回字符串
+
+            $result = json_decode($result, true);
+        }
+
+        $this->access_token = $result['result']['access_token'];
+
+//        echo $this->access_token;
+//        echo "<br/>";
+//        echo date('Y-m-d H:i:s', floatval($result['result']['time']) / 1000);
+//        echo "<br/>";
+//        echo "<br/>";
+
+        /******************************************************* redis *********************************************************/
+    }
+
+    /**
+     * 签名,生成规则如下:
+     * 1. 按照以下顺序将字符串拼接起来
+     *  client_secret+timestamp+client_id+username+password+grant_type+scope+client_secret
+     *  其中
+     *  client_secret的值是京东分配的
+     *  username使用原文
+     *  password需要md5加密后的
+     * 2. 将上述拼接的字符串使用MD5加密,加密后的值再转为大写
+     */
+    function create_sign()
+    {
+
+        $sign_str =
+            $this->client_secret .
+            $this->time_stamp . $this->client_id . $this->username . md5($this->password) . $this->grant_type . $this->scope .
+            $this->client_secret;
+
+        $sign_md5    = md5($sign_str);
+        $sign_result = strtoupper($sign_md5);
+
+        return $sign_result;
+
+    }
+
+    /**
+     * TODO 已测 1.3  获取Access Token
+     * HTTPS请求方式:POST
+     *
+     * @return string
+     */
+    function access_token_url()
+    {
+        return $this->host . $this->edition . "/oauth2/accessToken";
+    }
+
+    function access_token()
+    {
+
+        $params                  = array();
+        $params['grant_type']    = $this->grant_type;//该值固定为access_token
+        $params['client_id']     = $this->client_id;
+        $params['client_secret'] = $this->client_secret;
+        $params['timestamp']     = $this->time_stamp;
+        $params['username']      = $this->username;
+        $params['password']      = md5($this->password);
+        $params['scope']         = $this->scope;//非必须 申请权限。(目前推荐为空。为以后扩展用)
+        $params['sign']          = $this->create_sign();
+
+        $response = $this->post($this->access_token_url(), $params, true);
+
+//        {
+//            "success": true,
+//            "resultMessage": "",
+//            "resultCode": "0000",
+//            "result": {
+//                "uid": "6165718786",
+//                "refresh_token_expires": 1525071742348,
+//                "time": 1509346942348,
+//                "expires_in": 86400,
+//                "refresh_token": "A23k88ryXJx9QJBay7QEmdPcM0GoJk8uidR2pIjy",
+//                "access_token": "NIwoLn95BLs0ZdKLyawIiuFPM"
+//            }
+//        }
+        return $response;
+
+    }
+
+    /**
+     * TODO 已测 1.4  使用Refresh Token 刷新 Access Token
+     * HTTPS请求方式:POST
+     *
+     * @return string
+     */
+    function refresh_token_url()
+    {
+        return $this->host . $this->edition . "/oauth2/refreshToken";
+    }
+
+    function refresh_token($refresh_token)
+    {
+
+        $params                  = array();
+        $params['refresh_token'] = $refresh_token;
+        $params['client_id']     = $this->client_id;
+        $params['client_secret'] = $this->client_secret;
+
+
+        $response = $this->post($this->refresh_token_url(), $params, true);
+
+//        {
+//            "success": true,
+//            "resultMessage": "",
+//            "resultCode": "0000",
+//            "result": {
+//                "uid": "6165718786",
+//                "refresh_token_expires": 1525077000000,
+//                "time": 1509352200000,
+//                "expires_in": 86400,
+//                "refresh_token": "lhC8Btoft3GovRWad71v7b2RZ0ZQ45wQWjNmn46j",
+//                "access_token": "yEZ3Ut9m1Np4XAGm8Qaq0f9s2"
+//            }
+//        }
+        return $response;
+    }
+
+    //======================Other End========================
+
+    /**
+     * GET wrappwer for oAuthRequest.
+     *
+     * @return mixed
+     */
+    function get($url, $parameters = array())
+    {
+        $response = $this->oAuthRequest($url, 'GET', $parameters);
+        if ($this->format === 'json' && $this->decode_json) {
+            return json_decode($response, true);
+        }
+        return $response;
+    }
+
+    /**
+     * POST wreapper for oAuthRequest.
+     *
+     * @return mixed
+     */
+    function post($url, $parameters = array(), $multi = false)
+    {
+
+        $response = $this->oAuthRequest($url, 'POST', $parameters, $multi);
+        if ($this->format === 'json' && $this->decode_json) {
+            return json_decode($response, true);
+        }
+        return $response;
+    }
+
+    /**
+     * Format and sign an OAuth / API request
+     *
+     * @return string
+     * @ignore
+     */
+    function oAuthRequest($url, $method, $params, $multi = false)
+    {
+        if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
+            $url = "{$this->host}/{$this->edition}/{$url}";
+        } else {
+            $url = $url . '?client_id=' . $this->client_id . '&client_secret=' . $this->client_secret;
+        }
+
+        $parameters = array_merge_recursive($this->params_base, $params);
+
+        // TODO jd_vop_api_logs
+
+        switch ($method) {
+            case 'GET' :
+                $url = $url . http_build_query($parameters);
+                return $this->http($url, 'GET');
+            case 'PUT' :
+                $headers = array();
+                if (!$multi && (is_array($parameters) || is_object($parameters))) {
+
+                    if ($this->format === 'json' && $this->decode_json) {
+                        $body = json_encode($parameters);
+                        if ($this->debug) {
+                            echo '============= BODY =============';
+                            echo '<br/>';
+                            echo $body;
+                            echo '<br/>';
+                            echo '============= BODY =============';
+                            echo '<br/>';
+                        }
+                    } else {
+                        $body = http_build_query($parameters);
+                    }
+
+                } else {
+                    $body       = self::build_http_query_multi($parameters);
+                    $headers [] = "Content-Type: multipart/form-data; boundary=" . self::$boundary;
+                }
+                return $this->http($url, 'PUT', $body, $headers);
+            case 'DELETE' :
+                if (!empty($parameters)) {
+                    $url = $url . '&' . http_build_query($parameters);
+                }
+
+                return $this->http($url, 'DELETE');
+            default :
+                $headers = array();
+                if (!$multi && (is_array($parameters) || is_object($parameters))) {
+
+                    if ($this->format === 'json' && $this->decode_json) {
+                        $body = json_encode($parameters);
+                        if ($this->debug) {
+                            echo '============= BODY =============';
+                            echo '<br/>';
+                            echo $body;
+                            echo '<br/>';
+                            echo '============= BODY =============';
+                            echo '<br/>';
+                        }
+                    } else {
+                        $body = http_build_query($parameters);
+                    }
+
+                } else {
+                    $body       = self::build_http_query_multi($parameters);
+                    $headers [] = "Content-Type: multipart/form-data; boundary=" . self::$boundary;
+                }
+                return $this->http($url, $method, $body, $headers);
+        }
+    }
+
+    /**
+     * Make an HTTP request
+     *
+     * @return string API results
+     * @ignore
+     */
+    function http($url, $method, $postfields = NULL, $headers = array())
+    {
+        $this->http_info = array();
+        $ci              = curl_init();
+        /* Curl settings */
+        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+        curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
+        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
+        curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
+        curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
+        curl_setopt($ci, CURLOPT_ENCODING, "");
+        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
+//      curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
+        curl_setopt($ci, CURLOPT_HEADER, FALSE);
+
+        switch ($method) {
+
+            case 'GET':
+
+                curl_setopt($ci, CURLOPT_HTTPGET, TRUE);
+                if (!empty($postfields)) {
+                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
+                    $this->postdata = $postfields;
+                }
+                break;
+
+            case 'POST':
+
+                curl_setopt($ci, CURLOPT_POST, TRUE);
+
+                if ($this->format === 'json') {
+                    $headers [] = "Content-Type: application/json;";
+                }
+
+                if (!empty($postfields)) {
+                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
+                    $this->postdata = $postfields;
+                }
+                break;
+
+            case 'PUT':
+                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'PUT');
+                $headers [] = "Content-Type: application/json;";
+                if (!empty($postfields)) {
+                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
+                    $this->postdata = $postfields;
+                }
+                break;
+
+            case 'DELETE':
+                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
+                if (!empty($postfields)) {
+                    $url = "{$url}?{$postfields}";
+                    echo $url;
+                    echo '<br/>';
+                } else {
+                    $url = $url;
+                }
+                break;
+
+        }
+
+
+//      $headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];
+        curl_setopt($ci, CURLOPT_URL, $url);
+        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
+        curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);
+        $response        = curl_exec($ci);
+        $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
+        $this->http_info = array_merge($this->http_info, curl_getinfo($ci));
+        $this->url       = $url;
+
+        if ($this->debug) {
+            echo "=====post data======\r\n";
+            echo '<br/>';
+            var_dump($postfields);
+            echo '<br/>';
+
+            echo '=====info=====' . "\r\n";
+            echo '<br/>';
+            print_r(curl_getinfo($ci));
+            echo '<br/>';
+
+            echo '=====$response=====' . "\r\n";
+            echo '<br/>';
+            print_r($response);
+            echo '<br/>';
+        }
+
+
+        $code     = curl_getinfo($ci);
+        $response = json_decode($response, true);
+
+        if (!$response) {// TODO 暂时修正京东返回空的问题
+            $response = array();
+        }
+
+        $response['code'] = $code['http_code'];
+
+        $___url___                 = str_replace($this->host . $this->edition, '', $url);
+        $log_data                  = array();
+        $log_data['url']           = $url;
+        $log_data['api']           = substr($___url___, 0, strpos($___url___, '?'));
+        $log_data['method']        = $method;
+        $log_data['post_fields']   = $postfields;
+        $log_data['curl_info']     = json_encode(curl_getinfo($ci), JSON_UNESCAPED_UNICODE);
+        $log_data['success']       = isset($response['success']) ? $response['success'] : "exit0";
+        $log_data['resultMessage'] = isset($response['resultMessage']) ? $response['resultMessage'] : "exit0";
+        $log_data['resultCode']    = isset($response['resultCode']) ? $response['resultCode'] : "exit0";
+        $log_data['result']        = isset($response['result']) ? json_encode($response['result'], JSON_UNESCAPED_UNICODE) : "";
+
+        /**************************  2019年12月31日 09:42:42 zjh 改数据库为文件   *************************************/
+
+//        $this->_logsModel->insert($log_data);// TODO 屏蔽测试
+
+        //日志记录
+        Logger::getInstance()->info('京东请求日志:' . json_encode($log_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
+
+        /**************************  2019年12月31日 09:42:42 zjh 改数据库为文件   *************************************/
+
+
+        if (!empty($response['status']) && $response['status'] == 'Unauthorized.') {
+            /* header("Location:".site_url("Login/logout"));
+             exit();*/
+            $response['status'] = 'Unauthorized.';
+        }
+
+        $response = json_encode($response);
+
+        curl_close($ci);
+
+        return $response;
+    }
+
+
+    /**
+     * 处理多媒体数据内容
+     *
+     * @ignore
+     */
+    public static function build_http_query_multi($params)
+    {
+        if (!$params) return '';
+
+        uksort($params, 'strcmp');
+
+        $pairs = array();
+
+        self::$boundary = $boundary = uniqid('------------------');
+        $MPboundary     = '--' . $boundary;
+        $endMPboundary  = $MPboundary . '--';
+        $multipartbody  = '';
+
+        foreach ($params as $parameter => $value) {
+
+            if (in_array($parameter, array('pic', 'image', 'Filedata')) && $value{0} == '@') {
+                $url      = ltrim($value, '@');
+                $content  = file_get_contents($url);
+                $array    = explode('?', basename($url));
+                $filename = $array[0];
+
+                $multipartbody .= $MPboundary . "\r\n";
+                $multipartbody .= 'Content-Disposition: form-data; name="' . $parameter . '"; filename="' . $filename . '"' . "\r\n";
+                $multipartbody .= "Content-Type: image/unknown\r\n\r\n";
+                $multipartbody .= $content . "\r\n";
+            } else {
+                $multipartbody .= $MPboundary . "\r\n";
+                $multipartbody .= 'content-disposition: form-data; name="' . $parameter . "\"\r\n\r\n";
+                $multipartbody .= $value . "\r\n";
+            }
+
+        }
+
+        $multipartbody .= $endMPboundary;
+        return $multipartbody;
+    }
+
+
+    /***********************************************************************************************************************/
+
+    /**************** 以下处理业务逻辑 *******************/
+
+    /**
+     * TODO 已测 3.5  商品上下架状态接口
+     * HTTPS请求方式:POST
+     *
+     * @return string
+     */
+    function api_product_sku_state_url()
+    {
+        return $this->host . $this->edition . "/api/product/skuState";
+    }
+
+    function api_product_sku_state($sku)
+    {
+
+        $params          = array();
+        $params['token'] = $this->access_token; //授权时获取的access token
+        $params['sku']   = $sku;//商品编号,支持批量,以,分隔  (最高支持100个商品)1为上架,0为下架
+
+        $response = $this->post($this->api_product_sku_state_url(), $params, true);
+
+        // 参见:3.5  获取商品上下架状态接口.json
+
+        return $response;
+    }
+
+    /**
+     * TODO 待测 6.2  批量获取库存接口(建议订单详情页、下单使用)
+     * HTTPS请求方式:POST
+     *
+     * @return string
+     */
+    function api_stock_get_new_stock_by_id_url()
+    {
+        return $this->host . $this->edition . "/api/stock/getNewStockById";
+    }
+
+    function api_stock_get_new_stock_by_id($skuNums/*商品和数量  [{skuId: 569172,num:101}]*/, $area/*格式:1_0_0 (分别代表1、2、3级地址)*/)
+    {
+
+        $params            = array();
+        $params['token']   = $this->access_token;
+        $params['skuNums'] = $skuNums;//商品和数量  [{skuId: 569172,num:101}]
+        $params['area']    = $area;//格式:1_0_0 (分别代表1、2、3级地址)
+
+
+        $response = $this->post($this->api_stock_get_new_stock_by_id_url(), $params, true);
+
+//参数名称 意义 
+//areaId 配送地址id
+//desc 描述
+//skuId 商品编号
+//stockStateId 库存状态编号 33,39,40,36,34
+//StockStateDesc 库存状态描述
+//33 有货 现货-下单立即发货
+//39 有货 在途-正在内部配货,预计2~6天到达本仓库
+//40 有货 可配货-下单后从有货仓库配货
+//36 预订
+//34 无货
+//remainNum 剩余数量 -1未知;当库存小于5时展示真实库存数量
+
+
+        // 参见:6.2  批量获取库存接口(建议订单详情页、下单使用).json
+
+        return $response;
+    }
+
+    /**
+     * TODO 待测 5.2  批量查询协议价价格
+     * HTTPS请求方式:POST
+     *
+     * @return string
+     */
+    function api_price_get_price_url()
+    {
+        return $this->host . $this->edition . "/api/price/getPrice";
+    }
+
+    function api_price_get_price($sku)
+    {
+
+//        $start = microtime(true);
+
+        $params          = array();
+        $params['token'] = $this->access_token;//授权时获取的access token
+        $params['sku']   = $sku;//商品编号,请以,分割。例如:J_129408,J_129409(最高支持100个商品)
+
+        $response = $this->post($this->api_price_get_price_url(), $params, true);
+
+        // 参见:5.2  批量查询协议价价格.json
+
+//        $end = microtime(true);
+//        echo 'api_price_get_price 耗时'.round($end - $start,4).'秒';
+//        echo '<br/>';
+
+        return $response;
+    }
+
+}

+ 4 - 0
App/Com/Redis.php

@@ -27,4 +27,8 @@ class Redis
     	return $this->connect;
     }
 
+    public function get($key) {
+
+    }
+
 }

+ 121 - 0
App/HttpController/ProductService.php

@@ -0,0 +1,121 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: LZP
+ * Date: 2022/4/15
+ * Time: 11:23
+ */
+namespace App\HttpController;
+
+use EasySwoole\Http\AbstractInterface\Controller;
+use App\Com\JdSdk;
+
+class ProductService extends Controller
+{
+    private $JdSdk;
+
+    public function __construct()
+    {
+        $this->JdSdk = new JdSdk();
+    }
+
+    /**
+     * 3.5  商品上下架状态接口
+     *
+     * @param $skuArr
+     *
+     * @return array|bool
+     */
+    public function skuState($skuArr)
+    {
+        // 获取 `POST` 或者 `GET` 提交的所有参数
+        $data = $this->request()->getRequestParam();
+var_dump($data);
+
+        // 返回给客户端
+        $this->response()->write($data . PHP_EOL);
+
+        $skuArr = $data['skuArr'];
+
+        $sku = implode(',', $skuArr);
+
+
+        $response = $this->JdSdk->api_product_sku_state($sku);
+        //$response = json_decode($response, true);
+//        =====$response=====
+//        { "success": true, "resultMessage": "操作成功", "resultCode": "0000", "result": [ { "state": 0, "sku": 5729524 } ], "code": 200 }
+
+        return $response;
+
+    }
+
+    /**
+     * 6.2  批量获取库存接口(建议订单详情页、下单使用)
+     *
+     * @param $skuNums
+     * @param $area
+     * $skuNums商品和数量 此是个String 再重构吧  [{skuId: 569172,num:101}], $area格式:1_0_0 (分别代表1、2、3级地址)
+     * @return mixed
+     */
+    public function getNewStockById()
+    {
+        // 获取 `POST` 或者 `GET` 提交的所有参数
+        $data = $this->request()->getRequestParam();
+
+        $skuNums = $data['skuArr'];
+
+        $area = $data['area'];
+
+
+        $response = $this->JdSdk->api_stock_get_new_stock_by_id($skuNums, $area);
+
+        return $response;
+    }
+
+    /**
+     * TODO 待测 5.2  批量查询协议价价格
+     * HTTPS请求方式:POST
+     *
+     * @return string
+     */
+    function api_price_get_price($sku)
+    {
+        // 获取 `POST` 或者 `GET` 提交的所有参数
+        $data = $this->request()->getRequestParam();
+
+        $sku = $data['sku'];
+
+        $response = $this->JdSdk->api_price_get_price($sku);
+
+        return $response;
+    }
+
+
+    /**
+     * 当请求方法未找到时,自动调用该方法,可自行覆盖该方法实现自己的逻辑
+     *
+     */
+    protected function actionNotFound(?string $action)
+    {
+        $this->response()->withStatus(404);
+        $file = EASYSWOOLE_ROOT.'/vendor/easyswoole/easyswoole/src/Resource/Http/404.html';
+        if(!is_file($file)){
+            $file = EASYSWOOLE_ROOT.'/src/Resource/Http/404.html';
+        }
+        $this->response()->write(file_get_contents($file));
+    }
+
+
+    /**
+     * 此控制器抛异常时会执行此方法
+     *
+     * @param \Throwable $throwable
+     * @throws \Throwable
+     * CreateTime: 2020/8/19 12:48 上午
+     */
+    public function onException(\Throwable $throwable): void
+    {
+        parent::onException($throwable); // TODO: Change the autogenerated stub
+    }
+
+}

+ 4 - 0
App/HttpController/Router.php

@@ -25,5 +25,9 @@ class Router extends AbstractRouter
             //不再进入控制器解析
             return false;
         });
+
+        /*商品上下架状态接口*/
+        $routeCollector->get('/ProductService','/skuState');
+
     }
 }

+ 23 - 0
App/Models/JdConfig.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: LZP
+ * Date: 2022/4/15
+ * Time: 9:41
+ */
+namespace App\Models;
+
+use EasySwoole\ORM\AbstractModel;
+
+/**
+ * 运营商表
+ * Class BalancePushSet
+ */
+class JdConfig extends AbstractModel
+{
+    /**
+     * @var string
+     */
+    protected $tableName = 'ims_superdesk_jd_vop_configs';
+
+}