快手开放平台对接内容管理demo
其中包括用户授权,获取accessToken,获取用户信息,自动上传视频,发布视频,视频列表,删除视频等
<?php
namespace app\controller;use app\BaseController;
use think\Exception;
use think\facade\App;class KuaiShou extends BaseController
{private $accessToken = "";private $appId = "";private $appSecret = "";private $uploadToken; // 上传令牌private $endpoint;//上传网关的域名private $redirectUri = '';/*** 用户授权* */public function authorize($name = 'ThinkPHP6'){// 要请求的 URL$url = 'https://open.kuaishou.com/oauth2/authorize?';$params = ['app_id' => $this->appId, // 应用唯一标识'scope' => 'user_info,user_base,user_video_publish,user_video_delete,user_video_info', // code'response_type' => 'code','redirect_uri' => $this->redirectUri,// 应用授权作用域,多个授权作用域以英文逗号(,)分隔'state' => '123456789', //安全参数,标识和用户或者设备相关的授权请求。建议开发者实现。回调的时候会带回。'ua' => 'pc', // 运行环境,普通网页传pc, H5网页不传此参数即可];//// 调用 CURL GET 请求方法$result = $this->performCurlGetRequestWithParameters($url,$params);exit;}/*** 获取access_token* */public function getAccessToken(){$url = "https://open.kuaishou.com/oauth2/access_token?";$data = ['app_id' => $this->appId,'app_secret' => $this->appSecret,'code' => 'b0881372a93aa4434335c4d3e9a1773dcc8cd759c65b965a727a6ec18b85699867841685','grant_type' => 'authorization_code',];$result = $this->performCurlGetRequestWithParameters($url,$data);dd($result);}/*** 刷新token* */public function refreshAccessToken(){$url = "https://open.kuaishou.com/oauth2/refresh_token?";$data = ['app_id' => $this->appId,'app_secret' => $this->appSecret,"refresh_token" => "ChJvYXV0aC5yZWZyZXNoVG9rZW4SoAEWZ1a48M_hdbBMnUf1R2Tep9mcpFOllaVLX_uHdVL-1D7pLxV1PrdS-cy44h1ecc8LaWeyA6By76joHJXUE8LHnPjWSq1lotOS1a4GczDxoDo9bAzkoln3lGdTxh3OaHkuXUAPku_IW7H7ql81DPORYZmVK6RQHNb3EVkLBuelvp9nxTwThxZxUYe1LZcMsKGAsbFrXtfMaIhrXclDfIVTGhJmpGi_HIZyL3299lSodYIPN3UiIInoA_U1haHPefAICe8rsnU1-tjTZu3NxcCPR3vzLlERKAUwAQ",'grant_type' => 'refresh_token',];$result = $this->performCurlGetRequestWithParameters($url,$data);dd($result);}/*** 获取用户信息* */public function getUserInfo(){$url = "https://open.kuaishou.com/openapi/user_info?";$data = ['app_id' => $this->appId,'access_token' => $this->accessToken];$result = $this->performCurlGetRequestWithParameters($url,$data);dd($result);}/*** 获取用户手机号码* */public function getUserPhone(){$url = "https://open.kuaishou.com/openapi/user_phone?";$data = ['app_id' => $this->appId,'access_token' => $this->accessToken];$result = $this->performCurlGetRequestWithParameters($url,$data);dd($result);}/*** 发起上传* */public function startUpload(){$url = "https://open.kuaishou.com/openapi/photo/start_upload?";$data = ['app_id' => $this->appId,'access_token' => $this->accessToken];$params = '';foreach ($data as $key => $val) {$params .= "$key=$val&";}$url .= rtrim($params, '&');$res = $this->sendPostRequest($url);$res = json_decode($res, true);if ($res['result'] == 1) {$this->uploadToken = $res['upload_token'];$this->endpoint = $res['endpoint'];}}/*** 视频上传 FormData* */public function uploadForFormData(){$basePath = App::getBasePath();// 构造runtime文件夹的完整路径$runtimePath = $basePath . '../runtime/storage/';;// 获取表单上传文件 例如上传了001.jpg$file = request()->file('file');// 上传到本地服务器$savename = \think\facade\Filesystem::putFile( 'topic', $file);$url = "http://{$this->endpoint}/api/upload/multipart?upload_token={$this->uploadToken}";$file_path = $runtimePath.$savename;$result = $this->sendPostFileRequest($url, $file_path);dd($result);}/*** body二进制 视频上传* */public function uploadForBinaryData(){$basePath = App::getBasePath();// 构造runtime文件夹的完整路径$runtimePath = $basePath . '../runtime/storage/';;// 获取表单上传文件 例如上传了001.jpg$file = request()->file('file');// 上传到本地服务器$savename = \think\facade\Filesystem::putFile( 'topic', $file);$url = "http://{$this->endpoint}/api/upload?upload_token={$this->uploadToken}";$file_path = $runtimePath.$savename;$result = $this->sendPostBinaryDataRequest($url, $file_path);dd($result);}/*** 分片上传* */public function uploadFragment(){$basePath = App::getBasePath();// 构造runtime文件夹的完整路径$runtimePath = $basePath . '../runtime/storage/';;// 获取表单上传文件 例如上传了001.jpg$file = request()->file('file');// 上传到本地服务器$savename = \think\facade\Filesystem::putFile( 'topic', $file);$file_path = $runtimePath.$savename;// 使用示例$chunkSize = 1024 * 1024 * 2; // 分片大小,例如:1MB$chunks = $this->splitFileIntoChunks($file_path, $chunkSize);$is_file = false;foreach ($chunks as $k => $chunk) {// 对每个分片进行处理,例如上传到服务器或写入到另一个文件$url = "http://{$this->endpoint}/api/upload/fragment?fragment_id={$k}&upload_token={$this->uploadToken}";$result = $this->sendPostBinaryDataRequest($url, $chunk, $is_file);}echo $k;}/*** 断点续传* */public function uploadResume(){$endpoint = "upload.kuaishouzt.com";$url = "http://{$endpoint}/api/upload/resume?upload_token={$this->uploadToken}";$this->performCurlGetRequestWithParameters($url);}/*** 完成分片上传* */public function uploadComplete(){$fragment_count = 10;$url = "http://{$this->endpoint}/api/upload/complete?upload_token={$this->uploadToken}&fragment_count={$fragment_count}";$this->sendPostRequest($url);}function splitFileIntoChunks($filePath, $chunkSize) {$fileHandle = fopen($filePath, 'rb'); // 以二进制读取模式打开文件if ($fileHandle === false) {return false;// 如果文件打开失败,返回false}$chunks = [];while (!feof($fileHandle)) {$buffer = fread($fileHandle, $chunkSize);// 读取文件的一个片段if ($buffer === false) {break;// 如果读取失败,跳出循环}$chunks[] = $buffer; // 将片段添加到数组中}fclose($fileHandle); // 关闭文件句柄return $chunks;// 返回包含所有片段的数组}/*** 发布视频* */public function publish(){$basePath = App::getBasePath();// 构造runtime文件夹的完整路径$runtimePath = $basePath . '../runtime/storage/';;// 获取表单上传文件 例如上传了001.jpg$file = request()->file('file');// 上传到本地服务器$savename = \think\facade\Filesystem::putFile( 'topic', $file);$file_path = $runtimePath.$savename;$url = "https://open.kuaishou.com/openapi/photo/publish?";$data = ['app_id' => $this->appId,'access_token' => $this->accessToken,'upload_token' => $this->uploadToken,];$params = '';foreach ($data as $key => $val) {$params .= "$key=$val&";}$url .= rtrim($params, '&');$title = "分片";$res = $this->sendPostFileRequest1($url,$file_path,$title);dd($res);}/*** 查询用户视频列表* */public function userVideoList(){$url = "https://open.kuaishou.com/openapi/photo/list?";$data = ['access_token' => $this->accessToken,'app_id' => $this->appId];$this->performCurlGetRequestWithParameters($url, $data);}/*** 删除视频* */public function deleteVideo(){$url = "https://open.kuaishou.com/openapi/photo/delete?";$data = ['access_token' => $this->accessToken,'app_id' => $this->appId,'photo_id' => '3xurpbkusbyh6hw'];$params = '';foreach ($data as $key => $val) {//if ($key=='redirect_uri') $val = urlEncode($val);$params .= "$key=$val&";}$url .= rtrim($params, '&');$res = $this->sendPostRequest($url);dd($res);}/*** params string $url 请求的url* $file_path 文件路径* */public function sendPostFileRequest1($url,$file_path, $title){// 初始化cURL会话$ch = curl_init();// 设置目标URLcurl_setopt($ch, CURLOPT_URL, $url);// 启用POST方法,并设置请求体的类型为multipart/form-datacurl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, array('cover' => new \CURLFile($file_path),'caption' => $title));curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 为cURL会话设置适当的请求头curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));// 设置cURL选项,以便将响应结果直接作为字符串返回,而不是输出到浏览器curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 执行cURL请求并获取结果$response = curl_exec($ch);// 检查是否有错误发生if (curl_errno($ch)) {echo 'cURL error: ' . curl_error($ch);}// 关闭cURL会话curl_close($ch);// 输出响应结果echo $response;return $response;}public function sendPostBinaryDataRequest($url, $binaryData, $is_file = true){// 初始化cURL会话$ch = curl_init();// 设置目标URL,替换{endpoint}为实际的服务器地址// 设置请求头$headers = array('Content-Type: video/mp4');if ($is_file) {// 准备二进制数据,这里假设$binaryData是文件的二进制内容$binaryData = file_get_contents($binaryData);}// 替换为实际的文件二进制内容// 设置cURL选项curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $binaryData);// 设置cURL选项,以便将响应结果直接作为字符串返回,而不是输出到浏览器curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 执行cURL请求$response = curl_exec($ch);// 检查是否有错误发生if(curl_errno($ch)) {echo 'cURL error: ' . curl_error($ch);}// 关闭cURL会话curl_close($ch);// 输出响应结果return $response;}public function sendPostFileRequest($url,$file_path ){// 初始化cURL会话$ch = curl_init();// 设置目标URLcurl_setopt($ch, CURLOPT_URL, $url);// 启用POST方法,并设置请求体的类型为multipart/form-datacurl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => new \CURLFile($file_path),));// 为cURL会话设置适当的请求头curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));// 设置cURL选项,以便将响应结果直接作为字符串返回,而不是输出到浏览器curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 执行cURL请求并获取结果$response = curl_exec($ch);// 检查是否有错误发生if (curl_errno($ch)) {echo 'cURL error: ' . curl_error($ch);}// 关闭cURL会话curl_close($ch);// 输出响应结果echo $response;return $response;}public function sendPostRequest($url, $data = array(), $headers = array()) {// 创建 curl 实例$ch = curl_init();// 设置请求 URLcurl_setopt($ch, CURLOPT_URL, $url);// 设置 POST 请求方式curl_setopt($ch, CURLOPT_POST, 1);// 设置请求头为 application/json//$headers[] = "Content-Type: application/json";if ($data) {// 将数据以 JSON 格式发送curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));}curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);// 忽略 SSL 认证curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);// 设置cURL选项,以便将响应结果直接作为字符串返回,而不是输出到浏览器curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 执行 curl 请求$response = curl_exec($ch);// 获取响应代码$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);// 关闭 curl 连接curl_close($ch);return $response;}function performCurlGetRequestWithParameters($url, $parameters = []) {// 构建带有参数的 URL$params = '';foreach ($parameters as $key => $val) {//if ($key=='redirect_uri') $val = urlEncode($val);$params .= "$key=$val&";}$url .= rtrim($params, '&');header("Content-Type: application/json");header("Location: $url");die();var_dump($url);exit;// 执行 CURL GET 请求$this->performCurlGetRequest($url);}/*** 执行 CURL GET 请求的方法** @param string $url 要请求的 URL* @return string 请求的结果*/function performCurlGetRequest($url,$data = array()) {// 初始化 CURL$ch = curl_init();// 设置请求方式为 GETcurl_setopt($ch, CURLOPT_HTTPGET, true);// 设置要请求的 URLcurl_setopt($ch, CURLOPT_URL, $url);// 禁用 SSL 证书验证curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 设置默认的头部信息$headers = ['Content-Type: application/json'];curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);// 将数据以 JSON 格式发送curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));// 执行请求$result = curl_exec($ch);// 检查请求是否成功if (curl_errno($ch)) {// 处理请求失败的情况echo "CURL 请求失败: ". curl_error($ch);return;}// 关闭 CURL 连接curl_close($ch);// 返回请求结果return $result;}}相关文章:
快手开放平台对接内容管理demo
其中包括用户授权,获取accessToken,获取用户信息,自动上传视频,发布视频,视频列表,删除视频等 <?php namespace app\controller;use app\BaseController; use think\Exception; use think\facade\App;…...
2024年32款数据分析工具分五大类总览
数据分析工具在现代商业和科学中扮演着不可或缺的角色,为组织和个人提供了深入洞察和明智决策的能力。这些工具不仅能够处理大规模的数据集,还能通过强大的分析和可视化功能揭示隐藏在数据背后的模式和趋势。数据分析工具软件主要可以划分为以下五个类别…...
WPS的JS宏如何批量实现文字的超链接
表格中需要对文字进行超链接,每个链接指引到不同的地址。例如: 实现如下表格中,文件名称超级链接到对应的文件路径上,点击对应的文件名称,即可打开对应的文件。 序号文件名称文件路径1变更申请与处理表.xls文档\系统…...
0203逆矩阵-矩阵及其运算-线性代数
文章目录 一、逆矩阵的定义、性质和求法二、逆矩阵的初步应用结语 一、逆矩阵的定义、性质和求法 定义7 对于 n n n阶矩阵A,如果有一个 n n n阶矩阵B,使 A B B A E ABBAE ABBAE 则说矩阵A是可逆的,并把矩阵B称为A的逆矩阵,简称逆…...
加州大学欧文分校英语基础语法专项课程03:Simple Past Tense 学习笔记(完结)
Learn English: Beginning Grammar Specialization Specialization Certificate course 3: Simple Past Tense Course Certificate 本文是学习 https://www.coursera.org/learn/simple-past-tense 这门课的学习笔记,如有侵权,请联系删除。…...
基于Java微信小程序的医院挂号小程序,附源码
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
7.网络编程-安全
目录 引言 Session Cookie JWT (JSON Web Token) 网络攻击 CSRF DDoS 其他常见网络攻击类型及应对措施 引言 Session、Cookie 和 JWT 都是Web开发中用于实现用户状态管理和身份验证的技术。它们各自有不同的特点和应用场景: Session Session 是一种服务器…...
信息泄露漏洞的JS整改方案
引言 🛡️ 日常工作中,我们经常会面临线上环境被第三方安全厂商扫描出JS信息泄露漏洞的情况,这给我们的系统安全带来了潜在威胁。但幸运的是,对于这类漏洞的整改并不复杂。本文将介绍几种可行的整改方法,以及其中一种…...
WKWebView的使用
一、简介 在iOS中,WKWebView是WebKit框架提供的一个用于展示网页内容的控件,相比UIWebView有更好的性能和功能。 以下是在iOS中使用WKWebView的基本步骤: 1.1 导入WebKit框架 import WebKit1.2 创建WKWebView实例 let webView WKWebVie…...
iOS MT19937随机数生成,结合AES-CBC加密算法实现。
按处理顺序说明: 1. 生成随机数序列字符串函数 生成方法MT19937,初始种子seed,利用C库方法,生成: #include <random> //C 库头文件引入NSString * JKJMT19937Seed(uint32_t seed) {NSLog("MT19937Seed种…...
阿里云2024年优惠券获取方法及使用教程详解
阿里云是阿里巴巴集团旗下的云计算服务提供商,是全球领先的云计算及人工智能科技公司之一。提供免费试用、云服务器、云数据库、云安全、云企业应用等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。 阿里云2024年优惠券的获取方…...
hadoop中hdfs的fsimage文件与edits文件
hadoop中hdfs的fsimage文件与edits文件的作用 首先,我们抛出fsimage和edits文件的功能描述。 Fsimage文件: HDFS文件系统元数据的一个永久性的检查点,其中包含HDFS文件系统的 所有目录和文件inode的序列化信息。 Edits文件:存放HDFS文件系统的所有更…...
最新版两款不同版SEO超级外链工具PHP源码
可根据个人感觉喜好自行任意选择不同版本使用(版V1或版V2) 请将zip文件全部解压缩即可访问! 源码全部开源,支持上传二级目录访问 已更新增加大量高质量外链(若需要增加修改其他外链请打开txt文件)修复优…...
.net框架和c#程序设计第二次测试
一、实验内容 1、设计一个用户登录页面webform1.aspx,效果如下图所示: 2、点击webform1.aspx中“还未注册”连接进入register.aspx,注册页面效果如下图所示:点击用户注册信息到usershow.aspx页面,并显示注册的用户信息…...
芒果YOLOv8改进组合157:动态标签分配ATSS+新颖高效AsDDet检测头组合改进,共同助力VisDrone涨点1.8%,小目标高效涨点
💡本篇内容:【芒果YOLOv8改进ATSS标签分配策略|第三集】芒果YOLOv8改进组合157:动态标签分配ATSS+新颖高效AsDDet检测头组合改进,共同助力VisDrone涨点1.8%,小目标高效涨点 💡🚀🚀🚀本博客 标签分配策略ATSS改进+ 新颖高效AsDDet检测头组合改进,适用于 YOLOv8 …...
自媒体内容创作助手:7款必备ai写作工具一览! #学习方法#科技#其他
这些工具不仅可以快速生成高质量的文本内容,还可以根据用户的需求进行个性化定制。它们可以帮助我们节省大量的时间和精力,让我们更加专注于创意和细节的打磨。本文将为大家详细介绍几个AI写作工具,让你在写作领域更上一层楼。 1.七燕写作 这…...
文心一言 vs GPT-4 -- 全面横向比较
文心一言和GPT-4都是当前非常先进的自然语言处理模型,它们在语言理解、生成和翻译等方面都展现出了出色的能力。以下是对这两个模型的全面横向比较: 核心技术基础: 文心一言:是基于BERT(Bidirectional Encoder Repre…...
Leetcode C语言习题
Leetcode习题27:移除元素 题目: 说明: 示例: 题解: 方法一:(开辟额外的数组空间) 我们可以创建一个新的数组,然后用循环来遍历原数组,将原数组中不为 val…...
比 Nest.js 更优雅的 TS 控制反转策略 - 依赖查找
一、Cabloy5.0 内测预告 Cabloy5.0 采用 TS 对整个全栈框架进行了脱胎换骨般的大重构,并且提供了更加优雅的 ts 控制反转策略,让我们的业务开发更加快捷顺畅 1. 新旧技术栈对比: 后端前端旧版js、egg2.0、mysqljs、vue2、framework7新版ts…...
java算法day43 | 动态规划part05 ● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零
1049. 最后一块石头的重量 II 核心思想: 尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。 是不是感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。那么分成两堆石头,一堆石头的…...
数据结构第7章图:课后习题全解析(选择题+综合题+算法设计题,含DFS/BFS遍历、拓扑排序、最小生成树)
第7章 图 课后习题一、单项选择题1. 设无向图的顶点个数为 n,则该图最多有(B )条边。A. n−1 B. n(n−1)/2 C. n(n1)/2 D. n(n−1)解析: 无向完全图边数最多,每对顶点之间有一条边,总边数为 n(n−1)/2。2. …...
如何免费解锁Cursor AI Pro功能:终极三步激活指南
如何免费解锁Cursor AI Pro功能:终极三步激活指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial r…...
基于ESP32与Pure Data的无线音乐控制器:从硬件到软件的完整实现
1. 项目概述与核心思路 如果你对用代码做音乐感兴趣,或者玩过像Pure Data、Max/MSP这样的可视化音频编程环境,那你肯定想过一个问题:能不能把物理世界里的动作,比如触摸、倾斜、敲击,直接变成控制音乐的声音参数&#…...
对比直接使用厂商API,Taotoken在计费透明与用量观测上的优势
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比直接使用厂商API,Taotoken在计费透明与用量观测上的优势 当个人开发者或小型团队开始将大模型能力集成到自己的项目…...
【依赖冲突实战】Java NoSuchFieldError:从版本地狱到优雅解决
1. 当Java程序突然崩溃:NoSuchFieldError的典型症状 那天下午我正在调试一个微服务项目,突然控制台抛出个鲜红的异常: java.lang.NoSuchFieldError: MAX_RETRY_COUNT这个错误看似简单,却让我花了三小时才找到根源。项目里明明有MA…...
AgentOps:AI Agent可观测性平台,解决LLM应用开发调试难题
1. 项目概述:从“AI Agent”到“AgentOps”的工程化跃迁如果你最近在折腾AI Agent,或者正带领团队尝试将大语言模型(LLM)的能力集成到你的产品流程中,那你大概率会遇到一个共同的瓶颈:开发调试过程像在“开…...
TencentDB Agent Memory 架构拆解:告别 Agent 失忆,构建四层可追溯记忆与上下文治理系统
拆解 TencentDB Agent Memory 如何用分层记忆、上下文卸载和降级检索,让 Agent 留住工作现场。 原文链接:AI 小老六 Agent 真正难用的地方,往往不是它不会调用工具,而是它记不住工作现场。 你刚给它讲完项目背景、编码偏好、部署…...
收藏!小白程序员必看:读懂AI岗位JD,精准投递不陪跑
本文针对AI岗位认知模糊、JD理解困难等问题,为读者提供六步解析法,包括明确岗位性质、了解公司类型、评估薪资水平、硬性条件筛选、分析岗位职责和技能匹配。通过这些步骤,帮助读者精准定位适合自己的AI岗位,避免盲目投递。同时&a…...
红米K60澎湃OS解锁进阶:Delta面具Root实战与BL解锁后系统深度定制指南
1. 红米K60澎湃OS解锁Root前的准备工作 拿到一台已经解锁Bootloader的红米K60,想要通过Delta面具获取Root权限,准备工作至关重要。我遇到过不少小伙伴因为前期准备不足,导致刷机过程中出现各种奇怪问题。下面这些步骤都是我实测有效的方案&am…...
构建多模型智能客服时如何借助 Taotoken 实现灵活路由与降级
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 构建多模型智能客服时如何借助 Taotoken 实现灵活路由与降级 在构建企业级智能客服系统时,服务的稳定性和响应能力至关…...
