• h5 进入小程序 生成小程序临时链接


    h5端进入小程序
    
    private function get_wxapp_temp_url()
        {
            $url = '';
            $wxappConfig = WxappService::wxappConfig(null);
    
            $config = [
                'appid' => $wxappConfig['wx_appid'] ?? '这个appid',
                'secret' => $wxappConfig['wx_appsecret'] ?? '这个是秘钥',
            ];
            $wxapp = new Wxapp($config);
            $res = $wxapp->getTempUrl('pages/shop/shopHome/shopHome', 'ru_id=888'); // 访问店铺小程序页面路径
            $res = json_decode($res, true);
            if ($res) {
                $url = isset($res['openlink']) ? $res['openlink'] : '';
            }
            return $url;
        }
    
    /**
         * 唤起小程序临时访问链接
         */
        public function getTempUrl($path = '', $query = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
            $jump_wxa = [
                'path' => $path,
                'query' => $query
            ];
            $expire_time = time() + 60 * 60;
            $data = ['jump_wxa' => $jump_wxa, 'expire_time' => $expire_time];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GEN_SCHEME . 'access_token=' . $this->access_token, self::json_encode($data));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $result;
            }
            return false;
        }
    
    
    
    
    以下的详情文件方法
    
    
    
    
    
    
    wx_mini_appid = isset($options['appid']) ? $options['appid'] : '';
            $this->wx_mini_secret = isset($options['secret']) ? $options['secret'] : '';
        }
    
        /**
         * code 换取 session_key
         * 调用接口获取登录凭证(code)
         * @param $code
         * @return bool|mixed
         */
        public function getOauthOrization($code)
        {
            $params = [
                'appid' => $this->wx_mini_appid,
                'secret' => $this->wx_mini_secret,
                'js_code' => $code,
                'grant_type' => 'authorization_code'
            ];
            $result = $this->curlGet(self::API_URL_PREFIX . self::AUTH_ORIZATION . http_build_query($params, '', '&'));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
    
                return $json;
            }
            return false;
        }
    
        /**
         *  code 换取 unionid
         * 调用接口获取登录凭证(code)
         * @param $token
         * @param $openid
         * @return bool|mixed
         */
        public function getUnionid($token, $openid)
        {
            $params = [
                'withCredentials' => true,
                'access_token' => $token,
                'openid' => $openid,
                'lang' => 'zh_CN'
            ];
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_USER_INFO, self::json_encode($params));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
                return $json;
            }
            return false;
        }
    
        /**
         * 换取 access_token 缓存
         * @return bool|mixed
         */
        protected function checkAuth()
        {
            $cache_id = md5('wxapp_access_token' . $this->wx_mini_secret);
    
            if (($access_token = $this->getCache($cache_id)) && !empty($access_token)) {
                return $this->access_token = $access_token;
            }
    
            $result = $this->curlGet(self::API_URL_PREFIX . self::GET_ACCESS_TOKEN . "grant_type=client_credential&appid=" . $this->wx_mini_appid . "&secret=" . $this->wx_mini_secret);
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
    
                $this->access_token = $json['access_token'];
    
                $expire = $json['expires_in'] ? intval($json['expires_in']) - 300 : 7200;
                $this->setCache($cache_id, $this->access_token, $expire);
    
                return $this->access_token;
            }
    
            return false;
        }
    
        /**
         * 删除 access_token 缓存
         */
        public function resetAuth()
        {
            $this->access_token = null;
            $cache_id = md5('wxapp_access_token' . $this->wx_mini_secret);
            $this->removeCache($cache_id);
            return true;
        }
    
        /**
         * 接口失败重试
         * @param string $method SDK方法名称
         * @param array $arguments SDK方法参数
         * @return bool|mixed
         */
        protected function checkRetry($method, $arguments = [])
        {
            // access_token 超时过期重试
            if (!$this->_retry && in_array($this->errCode, ['40014', '40001', '41001', '42001'])) {
                ($this->_retry = true) && $this->resetAuth();
                $this->errCode = 40001;
                $this->errMsg = 'no access';
                return call_user_func_array([$this, $method], $arguments);
            }
            return false;
        }
    
        /**
         * 唤起小程序临时访问链接
         */
        public function getTempUrl($path = '', $query = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
            $jump_wxa = [
                'path' => $path,
                'query' => $query
            ];
            $expire_time = time() + 60 * 60;
            $data = ['jump_wxa' => $jump_wxa, 'expire_time' => $expire_time];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GEN_SCHEME . 'access_token=' . $this->access_token, self::json_encode($data));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $result;
            }
            return false;
        }
    
        /**
         * 获取小程序码 接口A
         * 适用于需要的码数量较少的业务场景
         * @param string $path 小程序路径
         * @param string $width
         * @param bool $auto_color
         * @param string $line_color
         * @return bool|mixed 返回的图片 Buffer
         */
        public function getWaCode($path = '', $width = '430', $auto_color = false, $line_color = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'path' => $path,
                'width' => $width,
                'auto_color' => $auto_color,
                'line_color' => $line_color
            ];
            if ($auto_color === false) {
                unset($data['line_color']);
            }
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_CODE . 'access_token=' . $this->access_token, self::json_encode($data));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $result;
            }
            return false;
        }
    
        /**
         * 获取小程序码 接口B
         * 适用于需要的码数量极多,或仅临时使用的业务场景
         * @param string $scene 值 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符 例如:自定义推荐参数 scene=uid
         * @param string $path 小程序路径
         * @param string $width 二维码的宽度
         * @param bool $auto_color 自动配置线条颜色
         * @param string $line_color
         * @param bool $is_hyaline 是否需要透明底色
         * @return bool|mixed 返回的图片 Buffer
         */
        public function getWaCodeUnlimit($scene = '', $path = '', $width = '', $auto_color = false, $line_color = '', $is_hyaline = true)
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'scene' => $scene,
                'page' => $path,
                'width' => $width,
                'auto_color' => $auto_color,
                'line_color' => $line_color,
                'is_hyaline' => $is_hyaline
            ];
            if ($auto_color === false) {
                unset($data['line_color']);
            }
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_CODE_UNLIMIT . 'access_token=' . $this->access_token, self::json_encode($data));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return $result;
            }
            return false;
        }
    
        /*生成小程序店铺二维码*/
        public function getWaCodeNew($path = '', $width = '430', $auto_color = false, $line_color = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'path' => $path,
                'width' => $width,
                'auto_color' => $auto_color,
                'line_color' => $line_color
            ];
            if ($auto_color === false) {
                unset($data['line_color']);
            }
    
            $url = "https://api.weixin.qq.com/wxa/getwxacode?access_token=";
            $result = $this->curlPost($url . $this->access_token, self::json_encode($data));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $result;
            }
            return false;
        }
    
        /**
         * 获取小程序码 接口C
         * 适用于需要的码数量较少的业务场景
         * 通过该接口生成的小程序二维码,永久有效,数量限制见文末说明,请谨慎使用。
         * @param string $path
         * @param string $width
         * @return bool|mixed
         */
        public function getWxaCode($path = '', $width = '430')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'path' => $path,
                'width' => $width
            ];
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_QRCODE . 'access_token=' . $this->access_token, self::json_encode($data));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $result;
            }
            return false;
        }
    
        /**
         * 获取模板库某个模板标题下关键词库KeywordList
         * 成功返回消息模板标题下关键词库
         * @param string $tpl_id 模板库中模板的编号
         * @return boolean|string
         */
        public function getWxTemplateKeywordList($tpl_id = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $tpl_id = [
                'id' => $tpl_id,
            ];
    
            //获取模板库某个模板标题下关键词库
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_KEYWORD_LIST . 'access_token=' . $this->access_token, self::json_encode($tpl_id));
    
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
    
                return $json;
            }
            return false;
        }
    
    
        /**
         * 模板消息 添加消息模板
         * 成功返回消息模板的调用id
         * @param string $tpl_id 模板的编号
         * @param string $keyword_id 关键词库id
         * @return boolean|string
         */
        public function wxaddTemplateMessage($tpl_id = '', $keyword_id = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $tpl_id = [
                'id' => $tpl_id,
                'keyword_id_list' => $keyword_id
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_TEMPLATE_ADD . 'access_token=' . $this->access_token, self::json_encode($tpl_id));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
                return $json['template_id'];
            }
            return false;
        }
    
        /**
         * 删除模板消息
         * @param string $template_id 模板消息ID
         * @return boolean|array
         */
        public function wxDelTemplate($template_id = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'template_id' => $template_id
            ];
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_TEMPLATE_DEL . 'access_token=' . $this->access_token, self::json_encode($data));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
                return $json;
            }
            return false;
        }
    
        /**
         * 获取帐号下已存在的模板列表
         * @param int $offset 用于分页,表示从offset开始。从 0 开始计数。
         * @param int $count 用于分页,表示拉取count条记录。最大为 20。最后一页的list长度可能小于请求的count。
         * @return boolean|array
         */
        public function wxTemplateList($offset = 0, $count = 20)
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'offset' => $offset,
                'count' => $count
            ];
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_TEMPLATE_LIST . 'access_token=' . $this->access_token, self::json_encode($data));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return false;
                }
                return $json;
            }
            return false;
        }
    
    
        /**
         * 发送模板消息
         * @param array $data 消息结构
         *{
         *"touser": "OPENID",
         * "template_id": "TEMPLATE_ID",
         *"page": "index",
         *"form_id": "FORMID",
         *"data": {
         *   "keyword1": {
         *       "value": "339208499",
         *       "color": "#173177"
         *  },
         * "keyword2": {
         *    "value": "2015年01月05日 12:30",
         *   "color": "#173177"
         * },
         *"keyword3": {
         *   "value": "粤海喜来登酒店",
         *  "color": "#173177"
         *} ,
         *"keyword4": {
         *   "value": "广州市天河区天河路208号",
         *  "color": "#173177"
         *}
         *},
         *"emphasis_keyword": "keyword1.DATA"
         *}
         * @return boolean|array
         */
        public function sendTemplateMessage($data = [])
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_WXA_TEMPLATE_SEND_URL . 'access_token=' . $this->access_token, self::json_encode($data));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json;
            }
            return false;
        }
    
        /**
         * 订阅消息 组合模板并添加至帐号下的个人模板库
         * @param string $tid 模板标题 id,可通过接口获取,也可登录小程序后台查看获取
         * @param array $kidList 开发者自行组合好的模板关键词列表,关键词顺序可以自由搭配(例如 [3,5,4] 或 [4,5,3]),最多支持5个,最少2个关键词组合
         * @param string $sceneDesc 服务场景描述,15个字以内
         * @return boolean|string
         */
        public function subscribeMessageAddTemplate($tid = '', $kidList = [], $sceneDesc = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'tid' => $tid,
                'kidList' => $kidList
            ];
    
            if (!empty($sceneDesc)) {
                $data['sceneDesc'] = $sceneDesc;
            }
    
            // 此处官方文档 使用 json 请求失败,改成 http_build_query
            $result = $this->curlPost(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_ADD_TEMPLATE . 'access_token=' . $this->access_token, http_build_query($data));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json['priTmplId'];
            }
    
            return false;
        }
    
        /**
         * 订阅消息 删除帐号下的个人模板
         * @param string $priTmplId 要删除的模板id
         * @return boolean|string
         */
        public function subscribeMessageDeleteTemplate($priTmplId = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $params = [
                'priTmplId' => $priTmplId,
            ];
    
            // 此处官方文档 使用 json 请求失败,改成 http_build_query
            $result = $this->curlPost(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_DELETE_TEMPLATE . 'access_token=' . $this->access_token, http_build_query($params));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return true;
            }
    
            return false;
        }
    
        /**
         * 订阅消息 获取小程序账号的类目
         * @return boolean|array
         */
        public function subscribeMessageGetCategory()
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $result = $this->curlGet(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_GET_CATEGORY . 'access_token=' . $this->access_token);
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json['data'];
            }
    
            return false;
        }
    
        /**
         * 订阅消息 获取模板标题下的关键词列表
         * @param string $tid 模板标题 id,可通过接口获取
         * @return boolean|string
         */
        public function subscribeMessageGetPubTemplateKeywords($tid = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $params = [
                'tid' => $tid
            ];
    
            $result = $this->curlGet(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_GET_PUB_TEMPLATE_KEYWORDS . 'access_token=' . $this->access_token . '&' . http_build_query($params, '', '&'));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json['data'];
            }
    
            return false;
        }
    
        /**
         * 订阅消息 获取帐号所属类目下的公共模板标题
         * @param string $ids 类目 id,多个用逗号隔开
         * @param int $start 用于分页,表示从 start 开始。从 0 开始计数。
         * @param int $limit 用于分页,表示拉取 limit 条记录。最大为 30
         * @return boolean|string
         */
        public function subscribeMessageGetPubTemplateTitle($ids = '', $start = 0, $limit = 30)
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $params = [
                'ids' => $ids,
                'start' => $start,
                'limit' => $limit > 30 ? 30 : $limit
            ];
    
            $result = $this->curlGet(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_GET_PUB_TEMPLATE_TITLE . 'access_token=' . $this->access_token . '&' . http_build_query($params, '', '&'));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json['data'];
            }
    
            return false;
        }
    
        /**
         * 订阅消息 获取当前帐号下的个人模板列表
         * @return boolean|string
         */
        public function subscribeMessageGetTemplateList()
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $result = $this->curlGet(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_GET_TEMPLATE_LIST . 'access_token=' . $this->access_token);
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json['data'];
            }
    
            return false;
        }
    
        /**
         * 订阅消息 发送订阅消息
         * @link https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
         * @param string $touser 接收者(用户)的 openid
         * @param string $template_id 所需下发的订阅模板id
         * @param array $data 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
         * @param string $page 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
         * @param string $miniprogram_state 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
         * @param string $lang 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
         * @return boolean|string
         */
        public function subscribeMessageSend($touser = '', $template_id = '', $data = [], $page = '', $miniprogram_state = '', $lang = '')
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $params = [
                'touser' => $touser,
                'template_id' => $template_id,
                'data' => $data
            ];
    
            if (!empty($page)) {
                $params['page'] = $page;
            }
    
            if (!empty($miniprogram_state)) {
                $params['miniprogram_state'] = $miniprogram_state;
            }
    
            if (!empty($lang)) {
                $params['lang'] = $lang;
            }
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::SUBSCRIBE_MESSAGE_SEND . 'access_token=' . $this->access_token, self::json_encode($params));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return true;
            }
    
            return false;
        }
    
        /**
         * 创建直播间
         * @param array $data
         * @return bool|mixed
         */
        public function liveRoomCreate($data = [])
        {
            if (empty($data)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_ROOM_CREATE . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json['roomId'];
            }
    
            return false;
        }
    
        /**
         * 获取直播房间列表
         * @param int $start 起始拉取房间,start = 0 表示从第 1 个房间开始拉取
         * @param int $limit 每次拉取的个数上限,不要设置过大,建议 100 以内
         * @return bool|mixed
         */
        public function liveRoom($start = 0, $limit = 10)
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'start' => $start,
                'limit' => $limit
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_LIVE_INFO . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return $json;
            }
    
            return false;
        }
    
        /**
         * 获取直播间回放
         *
         * 接口说明:调用接口获取已结束直播间的回放源视频(一般在直播结束后10分钟内生成,源视频无评论等内容)
         *
         * @param int $room_id 直播间id
         * @param int $start 起始拉取视频,0表示从第一个视频片段开始拉取
         * @param int $limit 每次拉取的数量,建议100以内
         * @return bool|mixed
         */
        public function liveRoomReplay($room_id = 0, $start = 0, $limit = 10)
        {
            if (empty($room_id)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'action' => 'get_replay',
                'room_id' => $room_id,
                'start' => $start,
                'limit' => $limit
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_LIVE_INFO . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return $json;
            }
    
            return false;
        }
    
        /**
         * 直播间导入已入库的商品
         *
         * @param int $room_id
         * @param array $goods_ids
         * @return bool
         */
        public function liveRoomAddGoods($room_id = 0, $goods_ids = [])
        {
            if (empty($room_id) || empty($goods_ids)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'ids' => $goods_ids,
                'roomId' => $room_id
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_ROOM_ADD_GOODS . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return true;
            }
    
            return false;
        }
    
        /**
         * 上传临时素材,有效期为3天(仅小程序接口可用)
         * 注意:数组的键值任意,但文件名前必须加@,使用单引号以避免本地路径斜杠被转义
         * 注意:临时素材的media_id是可复用的!
         * @param array $data {"media":'@Path\filename.jpg'}
         * @param string $type 类型:图片:image 语音:voice 视频:video 缩略图:thumb
         * @return boolean|array
         */
        public function uploadMedia($data = [], $type = '')
        {
            if (empty($data)) {
                return false;
            }
    
            // 小程序 access_token
            if (!$this->checkAuth()) {
                return false;
            }
    
            $result = $this->curlFilePost(self::API_URL_PREFIX . self::MEDIA_UPLOAD_URL . 'access_token=' . $this->access_token . '&type=' . $type, $data);
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json;
            }
            return false;
        }
    
        /**
         * 商品添加并提审
         *
         * 调用此接口上传并提审需要直播的商品信息,审核通过后商品录入【小程序直播】商品库
         * 注意:开发者必须保存【商品ID】与【审核单ID】,如果丢失,则无法调用其他相关接口
         *
         * @param array $goodsInfo
         * @return bool|mixed
         */
        public function liveGoodsAdd($goodsInfo = [])
        {
            if (empty($goodsInfo)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'goodsInfo' => $goodsInfo
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_GOODS_ADD . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return $json;
            }
            return false;
        }
    
        /**
         * 撤回审核
         *
         * 用此接口,可撤回直播商品的提审申请,消耗的提审次数不返还
         * @param string $auditId
         * @param int $goodsId
         * @return bool|mixed
         */
        public function liveGoodsReset($auditId = '', $goodsId = 0)
        {
            if (empty($auditId) || empty($goodsId)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'auditId' => $auditId,
                'goodsId' => $goodsId
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_GOODS_RESETAUDIT . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return true;
            }
            return false;
        }
    
        /**
         * 重新提交审核
         *
         * 调用此接口可以对已撤回提审的商品再次发起提审申请
         *
         * @param int $goodsId
         * @return bool|mixed
         */
        public function liveGoodsAudit($goodsId = 0)
        {
            if (empty($goodsId)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'goodsId' => $goodsId
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_GOODS_AUDIT . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return $json;
            }
            return false;
        }
    
        /**
         * 删除商品
         *
         * 调用此接口,可删除【小程序直播】商品库中的商品,删除后直播间上架的该商品也将被同步删除,不可恢复;
         * @param int $goodsId
         * @return bool|mixed
         */
        public function liveGoodsDelete($goodsId = 0)
        {
            if (empty($goodsId)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'goodsId' => $goodsId
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_GOODS_DELETE . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return true;
            }
            return false;
        }
    
        /**
         * 更新商品
         *
         * 调用此接口可以更新商品信息,审核通过的商品仅允许更新价格类型与价格,审核中的商品不允许更新,未审核的商品允许更新所有字段, 只传入需要更新的字段。
         * @param int $goodsId
         * @param array $goodsInfo 需要更新哪个字段就传入哪个字段,goodsId 必传
         * @return bool|mixed
         */
        public function liveGoodsUpdate($goodsId = 0, $goodsInfo = [])
        {
            if (empty($goodsId) || empty($goodsInfo)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $goodsInfo['goodsId'] = $goodsId;
    
            $data = [
                'goodsInfo' => $goodsInfo
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::BROADCAST_GOODS_UPDATE . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
                return true;
            }
            return false;
        }
    
        /**
         * 获取商品状态
         *
         * 调用此接口可获取商品的信息与审核状态
         * @param array $goods_ids
         * @return bool|mixed
         */
        public function getGoodsWarehouse($goods_ids = [])
        {
            if (empty($goods_ids)) {
                return false;
            }
    
            if (!$this->checkAuth()) {
                return false;
            }
    
            $data = [
                'goods_ids' => $goods_ids
            ];
    
            $result = $this->curlPost(self::API_URL_PREFIX . self::GET_GOODS_WAREHOUSE . 'access_token=' . $this->access_token, self::json_encode($data), 'json');
    
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return $json;
            }
            return false;
        }
    
        /**
         * 获取商品列表
         *
         * 调用此接口可获取商品列表
         * @param int $start 分页条数起点
         * @param int $limit 分页大小,默认30,不超过100
         * @param int $status 商品状态,0:未审核。1:审核中,2:审核通过,3:审核驳回
         * @return bool|mixed
         */
        public function getGoodsList($start = 0, $limit = 30, $status = 0)
        {
            if (!$this->checkAuth()) {
                return false;
            }
    
            $params = [
                'offset' => $start,
                'limit' => $limit,
                'status' => $status
            ];
    
            $result = $this->curlGet(self::API_URL_PREFIX . self::GET_GOODS_LIST . 'access_token=' . $this->access_token . '&' . http_build_query($params, '', '&'));
            if ($result) {
                $json = json_decode($result, true);
                if (!$json || !empty($json['errcode'])) {
                    $this->errCode = $json['errcode'];
                    $this->errMsg = $json['errmsg'];
                    return $this->checkRetry(__FUNCTION__, func_get_args());
                }
    
                return $json;
            }
            return false;
        }
    
        /**
         * GET 请求
         * @param $url
         * @param int $timeout
         * @param string $header
         * @return bool|mixed
         */
        protected function curlGet($url, $timeout = 5, $header = "")
        {
            $ch = curl_init();
            if (stripos($url, "https://") !== false) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
            }
            curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [$header]);//模拟的header头
            $result = curl_exec($ch);
            $aStatus = curl_getinfo($ch);
            curl_close($ch);
            if (intval($aStatus["http_code"]) == 200) {
                return $result;
            } else {
                return false;
            }
        }
    
        /**
         * POST 请求 文件上传
         * @param string $url
         * @param array $post_data
         * @param int $timeout
         * @return string content
         */
        protected function curlFilePost($url, $post_data = [], $timeout = 60)
        {
            $ch = curl_init();
            if (stripos($url, "https://") !== false) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
            }
    
            curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    
            $result = curl_exec($ch);
            $aStatus = curl_getinfo($ch);
            curl_close($ch);
            if (intval($aStatus["http_code"]) == 200) {
                return $result;
            } else {
                return false;
            }
        }
    
        /**
         * POST 请求
         * @param $url
         * @param $post_data
         * @param string $contentType
         * @param int $timeout
         * @return bool|mixed
         */
        protected function curlPost($url = '', $post_data, $contentType = 'form_params', $timeout = 60)
        {
            $ch = curl_init();
            if (stripos($url, "https://") !== false) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
            }
    
            if (is_string($post_data)) {
                $strPOST = $post_data;
            } else {
                $aPOST = [];
                foreach ($post_data as $key => $val) {
                    $aPOST[] = $key . "=" . urlencode($val);
                }
                $strPOST = join("&", $aPOST);
            }
    
            curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $strPOST);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    
            if ($contentType == 'form_params') {
                $header = [
                    "Content-type: application/x-www-form-urlencoded",
                ];
            } elseif ($contentType == 'json') {
                $header = [
                    "Content-type: application/json",
                ];
            }
    
            if (isset($header)) {
                curl_setopt($ch, CURLOPT_HTTPHEADER, $header);//模拟的header头
            }
    
            $result = curl_exec($ch);
            $aStatus = curl_getinfo($ch);
            curl_close($ch);
            if (intval($aStatus["http_code"]) == 200) {
                return $result;
            } else {
                return false;
            }
        }
    
        /**
         * 微信api不支持中文转义的json结构
         * @param $arr
         * @return string
         */
        public static function json_encode($arr)
        {
            if (count($arr) == 0) {
                return "[]";
            }
            $parts = [];
            $is_list = false;
            //Find out if the given array is a numerical array
            $keys = array_keys($arr);
            $max_length = count($arr) - 1;
            if (($keys [0] === 0) && ($keys [$max_length] === $max_length)) { //See if the first key is 0 and last key is length - 1
                $is_list = true;
                for ($i = 0; $i < count($keys); $i++) { //See if each key correspondes to its position
                    if ($i != $keys [$i]) { //A key fails at position check.
                        $is_list = false; //It is an associative array.
                        break;
                    }
                }
            }
            foreach ($arr as $key => $value) {
                if (is_array($value)) { //Custom handling for arrays
                    if ($is_list) {
                        $parts [] = self::json_encode($value);
                    } /* :RECURSION: */
                    else {
                        $parts [] = '"' . $key . '":' . self::json_encode($value);
                    } /* :RECURSION: */
                } else {
                    $str = '';
                    if (!$is_list) {
                        $str = '"' . $key . '":';
                    }
                    //Custom handling for multiple data types
                    if (!is_string($value) && is_numeric($value) && $value < 2000000000) {
                        $str .= $value;
                    } //Numbers
                    elseif ($value === false) {
                        $str .= 'false';
                    } //The booleans
                    elseif ($value === true) {
                        $str .= 'true';
                    } else {
                        $str .= '"' . addslashes($value) . '"';
                    } //All other things
                    // :TODO: Is there any more datatype we should be in the lookout for? (Object?)
                    $parts [] = $str;
                }
            }
            $json = implode(',', $parts);
            if ($is_list) {
                return '[' . $json . ']';
            } //Return numerical JSON
            return '{' . $json . '}'; //Return associative JSON
        }
    
        /**
         * 设置缓存,按需重载
         * @param string $name
         * @param mixed $value
         * @param int $expired
         * @return boolean
         */
        protected function setCache($name, $value, $expired)
        {
            Cache::put($name, $value, Carbon::now()->addSeconds($expired));
            return true;
        }
    
        /**
         * 获取缓存,按需重载
         * @param string $name
         * @return mixed
         */
        protected function getCache($name)
        {
            return Cache::get($name);
        }
    
        /**
         * 清除缓存,按需重载
         * @param string $name
         * @return boolean
         */
        protected function removeCache($name)
        {
            return Cache::forget($name);
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562
    • 563
    • 564
    • 565
    • 566
    • 567
    • 568
    • 569
    • 570
    • 571
    • 572
    • 573
    • 574
    • 575
    • 576
    • 577
    • 578
    • 579
    • 580
    • 581
    • 582
    • 583
    • 584
    • 585
    • 586
    • 587
    • 588
    • 589
    • 590
    • 591
    • 592
    • 593
    • 594
    • 595
    • 596
    • 597
    • 598
    • 599
    • 600
    • 601
    • 602
    • 603
    • 604
    • 605
    • 606
    • 607
    • 608
    • 609
    • 610
    • 611
    • 612
    • 613
    • 614
    • 615
    • 616
    • 617
    • 618
    • 619
    • 620
    • 621
    • 622
    • 623
    • 624
    • 625
    • 626
    • 627
    • 628
    • 629
    • 630
    • 631
    • 632
    • 633
    • 634
    • 635
    • 636
    • 637
    • 638
    • 639
    • 640
    • 641
    • 642
    • 643
    • 644
    • 645
    • 646
    • 647
    • 648
    • 649
    • 650
    • 651
    • 652
    • 653
    • 654
    • 655
    • 656
    • 657
    • 658
    • 659
    • 660
    • 661
    • 662
    • 663
    • 664
    • 665
    • 666
    • 667
    • 668
    • 669
    • 670
    • 671
    • 672
    • 673
    • 674
    • 675
    • 676
    • 677
    • 678
    • 679
    • 680
    • 681
    • 682
    • 683
    • 684
    • 685
    • 686
    • 687
    • 688
    • 689
    • 690
    • 691
    • 692
    • 693
    • 694
    • 695
    • 696
    • 697
    • 698
    • 699
    • 700
    • 701
    • 702
    • 703
    • 704
    • 705
    • 706
    • 707
    • 708
    • 709
    • 710
    • 711
    • 712
    • 713
    • 714
    • 715
    • 716
    • 717
    • 718
    • 719
    • 720
    • 721
    • 722
    • 723
    • 724
    • 725
    • 726
    • 727
    • 728
    • 729
    • 730
    • 731
    • 732
    • 733
    • 734
    • 735
    • 736
    • 737
    • 738
    • 739
    • 740
    • 741
    • 742
    • 743
    • 744
    • 745
    • 746
    • 747
    • 748
    • 749
    • 750
    • 751
    • 752
    • 753
    • 754
    • 755
    • 756
    • 757
    • 758
    • 759
    • 760
    • 761
    • 762
    • 763
    • 764
    • 765
    • 766
    • 767
    • 768
    • 769
    • 770
    • 771
    • 772
    • 773
    • 774
    • 775
    • 776
    • 777
    • 778
    • 779
    • 780
    • 781
    • 782
    • 783
    • 784
    • 785
    • 786
    • 787
    • 788
    • 789
    • 790
    • 791
    • 792
    • 793
    • 794
    • 795
    • 796
    • 797
    • 798
    • 799
    • 800
    • 801
    • 802
    • 803
    • 804
    • 805
    • 806
    • 807
    • 808
    • 809
    • 810
    • 811
    • 812
    • 813
    • 814
    • 815
    • 816
    • 817
    • 818
    • 819
    • 820
    • 821
    • 822
    • 823
    • 824
    • 825
    • 826
    • 827
    • 828
    • 829
    • 830
    • 831
    • 832
    • 833
    • 834
    • 835
    • 836
    • 837
    • 838
    • 839
    • 840
    • 841
    • 842
    • 843
    • 844
    • 845
    • 846
    • 847
    • 848
    • 849
    • 850
    • 851
    • 852
    • 853
    • 854
    • 855
    • 856
    • 857
    • 858
    • 859
    • 860
    • 861
    • 862
    • 863
    • 864
    • 865
    • 866
    • 867
    • 868
    • 869
    • 870
    • 871
    • 872
    • 873
    • 874
    • 875
    • 876
    • 877
    • 878
    • 879
    • 880
    • 881
    • 882
    • 883
    • 884
    • 885
    • 886
    • 887
    • 888
    • 889
    • 890
    • 891
    • 892
    • 893
    • 894
    • 895
    • 896
    • 897
    • 898
    • 899
    • 900
    • 901
    • 902
    • 903
    • 904
    • 905
    • 906
    • 907
    • 908
    • 909
    • 910
    • 911
    • 912
    • 913
    • 914
    • 915
    • 916
    • 917
    • 918
    • 919
    • 920
    • 921
    • 922
    • 923
    • 924
    • 925
    • 926
    • 927
    • 928
    • 929
    • 930
    • 931
    • 932
    • 933
    • 934
    • 935
    • 936
    • 937
    • 938
    • 939
    • 940
    • 941
    • 942
    • 943
    • 944
    • 945
    • 946
    • 947
    • 948
    • 949
    • 950
    • 951
    • 952
    • 953
    • 954
    • 955
    • 956
    • 957
    • 958
    • 959
    • 960
    • 961
    • 962
    • 963
    • 964
    • 965
    • 966
    • 967
    • 968
    • 969
    • 970
    • 971
    • 972
    • 973
    • 974
    • 975
    • 976
    • 977
    • 978
    • 979
    • 980
    • 981
    • 982
    • 983
    • 984
    • 985
    • 986
    • 987
    • 988
    • 989
    • 990
    • 991
    • 992
    • 993
    • 994
    • 995
    • 996
    • 997
    • 998
    • 999
    • 1000
    • 1001
    • 1002
    • 1003
    • 1004
    • 1005
    • 1006
    • 1007
    • 1008
    • 1009
    • 1010
    • 1011
    • 1012
    • 1013
    • 1014
    • 1015
    • 1016
    • 1017
    • 1018
    • 1019
    • 1020
    • 1021
    • 1022
    • 1023
    • 1024
    • 1025
    • 1026
    • 1027
    • 1028
    • 1029
    • 1030
    • 1031
    • 1032
    • 1033
    • 1034
    • 1035
    • 1036
    • 1037
    • 1038
    • 1039
    • 1040
    • 1041
    • 1042
    • 1043
    • 1044
    • 1045
    • 1046
    • 1047
    • 1048
    • 1049
    • 1050
    • 1051
    • 1052
    • 1053
    • 1054
    • 1055
    • 1056
    • 1057
    • 1058
    • 1059
    • 1060
    • 1061
    • 1062
    • 1063
    • 1064
    • 1065
    • 1066
    • 1067
    • 1068
    • 1069
    • 1070
    • 1071
    • 1072
    • 1073
    • 1074
    • 1075
    • 1076
    • 1077
    • 1078
    • 1079
    • 1080
    • 1081
    • 1082
    • 1083
    • 1084
    • 1085
    • 1086
    • 1087
    • 1088
    • 1089
    • 1090
    • 1091
    • 1092
    • 1093
    • 1094
    • 1095
    • 1096
    • 1097
    • 1098
    • 1099
    • 1100
    • 1101
    • 1102
    • 1103
    • 1104
    • 1105
    • 1106
    • 1107
    • 1108
    • 1109
    • 1110
    • 1111
    • 1112
    • 1113
    • 1114
    • 1115
    • 1116
    • 1117
    • 1118
    • 1119
    • 1120
    • 1121
    • 1122
    • 1123
    • 1124
    • 1125
    • 1126
    • 1127
    • 1128
    • 1129
    • 1130
    • 1131
    • 1132
    • 1133
    • 1134
    • 1135
    • 1136
    • 1137
    • 1138
    • 1139
    • 1140
    • 1141
    • 1142
    • 1143
    • 1144
    • 1145
    • 1146
    • 1147
    • 1148
    • 1149
    • 1150
    • 1151
    • 1152
    • 1153
    • 1154
    • 1155
    • 1156
    • 1157
    • 1158
    • 1159
    • 1160
    • 1161
    • 1162
    • 1163
    • 1164
    • 1165
    • 1166
    • 1167
    • 1168
    • 1169
    • 1170
    • 1171
    • 1172
    • 1173
    • 1174
    • 1175
    • 1176
    • 1177
    • 1178
    • 1179
    • 1180
    • 1181
    • 1182
    • 1183
    • 1184
    • 1185
    • 1186
    • 1187
    • 1188
    • 1189
    • 1190
    • 1191
    • 1192
    • 1193
    • 1194
    • 1195
    • 1196
    • 1197
    • 1198
    • 1199
    • 1200
    • 1201
    • 1202
    • 1203
    • 1204
    • 1205
    • 1206
    • 1207
    • 1208
    • 1209
    • 1210
    • 1211
    • 1212
    • 1213
    • 1214
    • 1215
    • 1216
    • 1217
    • 1218
    • 1219
    • 1220
    • 1221
    • 1222
    • 1223
    • 1224
    • 1225
    • 1226
    • 1227
    • 1228
    • 1229
    • 1230
    • 1231
    • 1232
    • 1233
    • 1234
    • 1235
    • 1236
    • 1237
    • 1238
    • 1239
    • 1240
    • 1241
    • 1242
    • 1243
    • 1244
    • 1245
    • 1246
    • 1247
    • 1248
    • 1249
    • 1250
    • 1251
    • 1252
    • 1253
    • 1254
    • 1255
    • 1256
    • 1257
    • 1258
    • 1259
    • 1260
    • 1261
    • 1262
    • 1263
    • 1264
    • 1265
    • 1266
    • 1267
    • 1268
    • 1269
    • 1270
    • 1271
    • 1272
    • 1273
    • 1274
    • 1275
    • 1276
    • 1277
    • 1278
    • 1279
    • 1280
    • 1281
    • 1282
    • 1283
    • 1284
    • 1285
    • 1286
    • 1287
    • 1288
    • 1289
    • 1290
    • 1291
    • 1292
    • 1293
    • 1294
    • 1295
    • 1296
    • 1297
    • 1298
    • 1299
    • 1300
    • 1301
    • 1302
    • 1303
    • 1304
    • 1305
    • 1306
    • 1307
    • 1308
    • 1309
    • 1310
    • 1311
    • 1312
    • 1313
    • 1314
    • 1315
    • 1316
    • 1317
    • 1318
    • 1319
    • 1320
    • 1321
    • 1322
    • 1323
    • 1324
    • 1325
    • 1326
    • 1327
    • 1328
    • 1329
    • 1330
    • 1331
    • 1332
    • 1333
    • 1334
    • 1335
    • 1336
    • 1337
    • 1338
    • 1339
    • 1340
    • 1341
    • 1342
    • 1343
    • 1344
    • 1345
    • 1346
    • 1347
    • 1348
    • 1349
    • 1350
    • 1351
    • 1352
    • 1353
    • 1354
    • 1355
    • 1356
    • 1357
    • 1358
    • 1359
    • 1360
    • 1361
    • 1362
    • 1363
    • 1364
    • 1365
    • 1366
    • 1367
    • 1368
    • 1369
    • 1370
    • 1371
    • 1372
    • 1373
    • 1374
    • 1375
    • 1376
    • 1377
    • 1378
    • 1379
    • 1380
    • 1381
    • 1382
    • 1383
    • 1384
    • 1385
    • 1386
    • 1387
    • 1388
    • 1389
    • 1390
    • 1391
    • 1392
    • 1393
    • 1394
    • 1395
    • 1396
    • 1397
    • 1398
    • 1399
    • 1400
    • 1401
    • 1402
    • 1403
    • 1404
    • 1405
    • 1406
    • 1407
    • 1408
    • 1409
    • 1410
    • 1411
    • 1412
    • 1413
    • 1414
    • 1415
    • 1416
    • 1417
    • 1418
    • 1419
    • 1420
    • 1421
    • 1422
    • 1423
    • 1424
    • 1425
    • 1426
    • 1427
    • 1428
    • 1429
    • 1430
    • 1431
    • 1432
    • 1433
    • 1434
    • 1435
    • 1436
    • 1437
    • 1438
    • 1439
    • 1440
    • 1441
    • 1442
    • 1443
    • 1444
    • 1445
    • 1446
    • 1447
    • 1448
    • 1449
    • 1450
    • 1451
    • 1452
    • 1453
    • 1454
    • 1455
    • 1456
    • 1457
    • 1458
    • 1459
    • 1460
    • 1461
    • 1462
    • 1463
    • 1464
    • 1465
    • 1466
    • 1467
    • 1468
    • 1469
    • 1470
    • 1471
    • 1472
    • 1473
    • 1474
    • 1475
    • 1476
    • 1477
    • 1478
    • 1479
    • 1480
    • 1481
    • 1482
    • 1483
    • 1484
    • 1485
    • 1486
  • 相关阅读:
    MYSQL:Select语句顺序
    DC-9 靶机
    小程序中如何查看会员的余额和变更记录
    Unity | 模型动态效果插件总结
    强推这款丝滑酷炫酷的keychron K8键盘
    活动回顾∣企企通亮相高质量企业数字化活动,深入探讨各领域采购数字化转型与变革
    【temu】分析拼多多跨境电商Temu数据分析数据采集
    数据结构与算法_AVL平衡二叉树_四种旋转,插入和删除
    别的电脑访问不到我本机上的gitea是为什么呀?
    Java中的String类真的不可变吗?java面试常见问题
  • 原文地址:https://blog.csdn.net/weixin_41865469/article/details/126409579