mirror of
https://github.com/ctwj/urldb.git
synced 2025-11-25 03:15:04 +08:00
update: 自动转存
This commit is contained in:
@@ -344,36 +344,37 @@ func (x *XunleiPanService) Transfer(shareID string) (*TransferResult, error) {
|
||||
if err != nil {
|
||||
return ErrorResult(fmt.Sprintf("获取分享详情失败: %v", err)), nil
|
||||
}
|
||||
if shareDetail["share_status"].(string) != "OK" {
|
||||
return ErrorResult(fmt.Sprintf("获取分享详情失败: %v", "分享状态异常")), nil
|
||||
}
|
||||
if shareDetail["file_num"].(string) == "0" {
|
||||
return ErrorResult(fmt.Sprintf("获取分享详情失败: %v", "文件列表为空")), nil
|
||||
}
|
||||
|
||||
parent_id := "" // 默认存储路径
|
||||
|
||||
// 检查是否为检验模式
|
||||
if config.IsType == 1 {
|
||||
// 检验模式:直接获取分享信息
|
||||
urls := map[string]interface{}{
|
||||
"title": "",
|
||||
"title": shareDetail["title"],
|
||||
"share_url": config.URL,
|
||||
"stoken": "",
|
||||
}
|
||||
return SuccessResult("检验成功", urls), nil
|
||||
}
|
||||
files := shareDetail["files"].([]interface{})
|
||||
|
||||
// 转存到网盘
|
||||
parent_id := "0" // 默认存储路径
|
||||
if config.ExpiredType == 2 {
|
||||
parent_id = "指定路径" // 这里可能需要从配置获取
|
||||
}
|
||||
// files := shareDetail["files"].([]interface{})
|
||||
// fileIDs := make([]string, 0)
|
||||
// for _, file := range files {
|
||||
// fileMap := file.(map[string]interface{})
|
||||
// if fid, ok := fileMap["id"].(string); ok {
|
||||
// fileIDs = append(fileIDs, fid)
|
||||
// }
|
||||
// }
|
||||
|
||||
fileIDs := make([]string, 0)
|
||||
for _, file := range files {
|
||||
fileMap := file.(map[string]interface{})
|
||||
if fid, ok := fileMap["id"].(string); ok {
|
||||
fileIDs = append(fileIDs, fid)
|
||||
}
|
||||
}
|
||||
|
||||
if len(fileIDs) == 0 {
|
||||
return ErrorResult("分享中没有可转存的文件"), nil
|
||||
}
|
||||
// 处理广告过滤(这里简化处理)
|
||||
// TODO: 添加广告文件过滤逻辑
|
||||
|
||||
// 转存资源
|
||||
restoreResult, err := x.getRestore(shareID, shareDetail, accessToken, captchaToken, parent_id)
|
||||
@@ -381,30 +382,18 @@ func (x *XunleiPanService) Transfer(shareID string) (*TransferResult, error) {
|
||||
return ErrorResult(fmt.Sprintf("转存失败: %v", err)), nil
|
||||
}
|
||||
|
||||
if restoreResult["code"].(int) != 200 {
|
||||
return ErrorResult("转存失败"), nil
|
||||
}
|
||||
|
||||
// 获取转存任务信息
|
||||
restoreData := restoreResult["data"].(map[string]interface{})
|
||||
taskID := restoreData["restore_task_id"].(string)
|
||||
taskID := restoreResult["restore_task_id"].(string)
|
||||
|
||||
// 等待转存完成
|
||||
_, err = x.waitForTask(taskID, accessToken, captchaToken)
|
||||
taskResp, err := x.waitForTask(taskID, accessToken, captchaToken)
|
||||
if err != nil {
|
||||
return ErrorResult(fmt.Sprintf("等待转存完成失败: %v", err)), nil
|
||||
}
|
||||
|
||||
// 获取任务结果并解析文件ID
|
||||
// 获取任务结果以获取文件ID
|
||||
existingFileIds := make([]string, 0)
|
||||
taskResp, err := x.getTasks(taskID, accessToken, captchaToken)
|
||||
if err != nil {
|
||||
return ErrorResult(fmt.Sprintf("获取任务结果失败: %v", err)), nil
|
||||
}
|
||||
|
||||
if taskData, ok := taskResp["data"].(map[string]interface{}); ok {
|
||||
if params, ok2 := taskData["params"].(map[string]interface{}); ok2 {
|
||||
if params, ok2 := taskResp["params"].(map[string]interface{}); ok2 {
|
||||
if traceIds, ok3 := params["trace_file_ids"].(string); ok3 {
|
||||
traceData := make(map[string]interface{})
|
||||
json.Unmarshal([]byte(traceIds), &traceData)
|
||||
@@ -413,10 +402,6 @@ func (x *XunleiPanService) Transfer(shareID string) (*TransferResult, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理广告过滤(这里简化处理)
|
||||
// TODO: 添加广告文件过滤逻辑
|
||||
|
||||
// 创建分享链接
|
||||
expirationDays := "-1"
|
||||
@@ -425,36 +410,30 @@ func (x *XunleiPanService) Transfer(shareID string) (*TransferResult, error) {
|
||||
}
|
||||
|
||||
// 根据share_id获取到分享链接
|
||||
passwordResult, err := x.getSharePassword(existingFileIds, accessToken, captchaToken, expirationDays)
|
||||
shareResult, err := x.getSharePassword(existingFileIds, accessToken, captchaToken, expirationDays)
|
||||
if err != nil {
|
||||
return ErrorResult(fmt.Sprintf("创建分享链接失败: %v", err)), nil
|
||||
}
|
||||
|
||||
if passwordResult["code"].(int) != 200 {
|
||||
return ErrorResult("创建分享链接失败"), nil
|
||||
}
|
||||
|
||||
passwordData := passwordResult["data"].(map[string]interface{})
|
||||
shareTitle := ""
|
||||
if len(files) > 0 {
|
||||
file0 := files[0].(map[string]interface{})
|
||||
if name, ok := file0["name"].(string); ok {
|
||||
shareTitle = name
|
||||
}
|
||||
var fid string
|
||||
if len(existingFileIds) > 1 {
|
||||
fid = strings.Join(existingFileIds, ",")
|
||||
} else {
|
||||
fid = existingFileIds[0]
|
||||
}
|
||||
|
||||
result := map[string]interface{}{
|
||||
"title": shareTitle,
|
||||
"share_url": passwordData["share_url"].(string) + "?pwd=" + passwordData["pass_code"].(string),
|
||||
"code": passwordData["pass_code"].(string),
|
||||
"fid": existingFileIds,
|
||||
"title": "",
|
||||
"shareUrl": shareResult["share_url"].(string) + "?pwd=" + shareResult["pass_code"].(string),
|
||||
"code": shareResult["pass_code"].(string),
|
||||
"fid": fid,
|
||||
}
|
||||
|
||||
return SuccessResult("转存成功", result), nil
|
||||
}
|
||||
|
||||
// waitForTask 等待任务完成 - 使用 HTTPGet 方法
|
||||
func (x *XunleiPanService) waitForTask(taskID string, accessToken, captchaToken string) (*XLTaskResult, error) {
|
||||
func (x *XunleiPanService) waitForTask(taskID string, accessToken, captchaToken string) (map[string]interface{}, error) {
|
||||
maxRetries := 50
|
||||
retryDelay := 2 * time.Second
|
||||
|
||||
@@ -464,7 +443,7 @@ func (x *XunleiPanService) waitForTask(taskID string, accessToken, captchaToken
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if result.Status == 2 { // 任务完成
|
||||
if int64(result["progress"].(float64)) == 100 { // 任务完成
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -475,12 +454,9 @@ func (x *XunleiPanService) waitForTask(taskID string, accessToken, captchaToken
|
||||
}
|
||||
|
||||
// getTaskStatus 获取任务状态 - 使用 HTTPGet 方法
|
||||
func (x *XunleiPanService) getTaskStatus(taskID string, retryIndex int, accessToken, captchaToken string) (*XLTaskResult, error) {
|
||||
apiURL := x.apiHost("") + "/drive/v1/task"
|
||||
queryParams := map[string]string{
|
||||
"task_id": taskID,
|
||||
"retry_index": fmt.Sprintf("%d", retryIndex),
|
||||
}
|
||||
func (x *XunleiPanService) getTaskStatus(taskID string, retryIndex int, accessToken, captchaToken string) (map[string]interface{}, error) {
|
||||
apiURL := x.apiHost("") + "/drive/v1/tasks/" + taskID
|
||||
queryParams := map[string]string{}
|
||||
|
||||
// 设置 request 所需的 headers
|
||||
headers := map[string]string{
|
||||
@@ -492,17 +468,7 @@ func (x *XunleiPanService) getTaskStatus(taskID string, retryIndex int, accessTo
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if code, ok := resp["code"].(float64); ok && code != 200 {
|
||||
return nil, fmt.Errorf("获取任务状态失败")
|
||||
}
|
||||
|
||||
var data XLTaskResult
|
||||
resultBytes, _ := json.Marshal(resp)
|
||||
if err := json.Unmarshal(resultBytes, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &data, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetUserInfoByEntity 根据 entity.Cks 获取用户信息(待实现)
|
||||
|
||||
@@ -1,449 +0,0 @@
|
||||
<?php
|
||||
namespace netdisk\pan;
|
||||
|
||||
class QuarkPan extends BasePan
|
||||
{
|
||||
public function __construct($config = [])
|
||||
{
|
||||
parent::__construct($config);
|
||||
$this->urlHeader = [
|
||||
'Accept: application/json, text/plain, */*',
|
||||
'Accept-Language: zh-CN,zh;q=0.9',
|
||||
'content-type: application/json;charset=UTF-8',
|
||||
'sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
|
||||
'sec-ch-ua-mobile: ?0',
|
||||
'sec-ch-ua-platform: "Windows"',
|
||||
'sec-fetch-dest: empty',
|
||||
'sec-fetch-mode: cors',
|
||||
'sec-fetch-site: same-site',
|
||||
'Referer: https://pan.quark.cn/',
|
||||
'Referrer-Policy: strict-origin-when-cross-origin',
|
||||
'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'cookie: ' . Config('qfshop.quark_cookie')
|
||||
];
|
||||
}
|
||||
|
||||
public function getFiles($pdir_fid=0)
|
||||
{
|
||||
// 原 getFiles 方法内容
|
||||
$urlData = [];
|
||||
$queryParams = [
|
||||
'pr' => 'ucpro',
|
||||
'fr' => 'pc',
|
||||
'uc_param_str' => '',
|
||||
'pdir_fid' => $pdir_fid,
|
||||
'_page' => 1,
|
||||
'_size' => 50,
|
||||
'_fetch_total' => 1,
|
||||
'_fetch_sub_dirs' => 0,
|
||||
'_sort' => 'file_type:asc,updated_at:desc',
|
||||
];
|
||||
|
||||
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/file/sort", "GET", json_encode($urlData), $this->urlHeader,$queryParams)['body'];
|
||||
$res = json_decode($res, true);
|
||||
if($res['status'] !== 200){
|
||||
return jerr2($res['message']=='require login [guest]'?'夸克未登录,请检查cookie':$res['message']);
|
||||
}
|
||||
|
||||
return jok2('获取成功',$res['data']['list']);
|
||||
}
|
||||
|
||||
public function transfer($pwd_id)
|
||||
{
|
||||
if(empty($this->stoken)){
|
||||
//获取要转存夸克资源的stoken
|
||||
$res = $this->getStoken($pwd_id);
|
||||
if($res['status'] !== 200) return jerr2($res['message']);
|
||||
$infoData = $res['data'];
|
||||
|
||||
if($this->isType == 1){
|
||||
$urls['title'] = $infoData['title'];
|
||||
$urls['share_url'] = $this->url;
|
||||
$urls['stoken'] = $infoData['stoken'];
|
||||
return jok2('检验成功', $urls);
|
||||
}
|
||||
$stoken = $infoData['stoken'];
|
||||
$stoken = str_replace(' ', '+', $stoken);
|
||||
}else{
|
||||
$stoken = str_replace(' ', '+', $this->stoken);
|
||||
}
|
||||
|
||||
//获取要转存夸克资源的详细内容
|
||||
$res = $this->getShare($pwd_id,$stoken);
|
||||
if($res['status']!== 200) return jerr2($res['message']);
|
||||
$detail = $res['data'];
|
||||
|
||||
$fid_list = [];
|
||||
$fid_token_list = [];
|
||||
$title = $detail['share']['title']; //资源名称
|
||||
foreach ($detail['list'] as $key => $value) {
|
||||
$fid_list[] = $value['fid'];
|
||||
$fid_token_list[] = $value['share_fid_token'];
|
||||
}
|
||||
|
||||
//转存资源到指定文件夹
|
||||
$res = $this->getShareSave($pwd_id,$stoken,$fid_list,$fid_token_list);
|
||||
if($res['status']!== 200) return jerr2($res['message']);
|
||||
$task_id = $res['data']['task_id'];
|
||||
|
||||
//转存后根据task_id获取转存到自己网盘后的信息
|
||||
$retry_index = 0;
|
||||
$myData = '';
|
||||
while ($myData=='' || $myData['status'] != 2) {
|
||||
$res = $this->getShareTask($task_id, $retry_index);
|
||||
if($res['message']== 'capacity limit[{0}]'){
|
||||
return jerr2('容量不足');
|
||||
}
|
||||
if($res['status']!== 200) {
|
||||
return jerr2($res['message']);
|
||||
}
|
||||
$myData = $res['data'];
|
||||
$retry_index++;
|
||||
// 可以添加一个最大重试次数的限制,防止无限循环
|
||||
if ($retry_index > 50) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
//删除转存后可能有的广告
|
||||
$banned = Config('qfshop.quark_banned')??''; //如果出现这些字样就删除
|
||||
if(!empty($banned)){
|
||||
$bannedList = explode(',', $banned);
|
||||
$pdir_fid = $myData['save_as']['save_as_top_fids'][0];
|
||||
$dellist = [];
|
||||
$plist = $this->getPdirFid($pdir_fid);
|
||||
if(!empty($plist)){
|
||||
foreach ($plist as $key => $value) {
|
||||
// 检查$value['file_name']是否包含$bannedList中的任何一项
|
||||
$contains = false;
|
||||
foreach ($bannedList as $item) {
|
||||
if (strpos($value['file_name'], $item) !== false) {
|
||||
$contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($contains) {
|
||||
$dellist[] = $value['fid'];
|
||||
}
|
||||
}
|
||||
if(count($plist) === count($dellist)){
|
||||
//要删除的资源数如果和原数据资源数一样 就全部删除并终止下面的分享
|
||||
$this->deletepdirFid([$pdir_fid]);
|
||||
return jerr2("资源内容为空");
|
||||
}else{
|
||||
if (!empty($dellist)) {
|
||||
$this->deletepdirFid($dellist);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
$shareFid = $myData['save_as']['save_as_top_fids'];
|
||||
//分享资源并拿到更新后的task_id
|
||||
$res = $this->getShareBtn($myData['save_as']['save_as_top_fids'],$title);
|
||||
if($res['status']!== 200) return jerr2($res['message']);
|
||||
$task_id = $res['data']['task_id'];
|
||||
|
||||
//根据task_id拿到share_id
|
||||
$retry_index = 0;
|
||||
$myData = '';
|
||||
while ($myData=='' || $myData['status'] != 2) {
|
||||
$res = $this->getShareTask($task_id, $retry_index);
|
||||
if($res['status']!== 200) continue;
|
||||
$myData = $res['data'];
|
||||
$retry_index++;
|
||||
// 可以添加一个最大重试次数的限制,防止无限循环
|
||||
if ($retry_index > 50) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//根据share_id 获取到分享链接
|
||||
$res = $this->getSharePassword($myData['share_id']);
|
||||
if($res['status']!== 200) return jerr2($res['message']);
|
||||
$share = $res['data'];
|
||||
// $share['fid'] = $share['first_file']['fid'];
|
||||
$share['fid'] = (is_array($shareFid) && count($shareFid) > 1) ? $shareFid : $share['first_file']['fid'];
|
||||
|
||||
return jok2('转存成功', $share);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取要转存资源的stoken
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getStoken($pwd_id)
|
||||
{
|
||||
$urlData = array(
|
||||
'passcode' => '',
|
||||
'pwd_id' => $pwd_id,
|
||||
);
|
||||
$queryParams = [
|
||||
'pr' => 'ucpro',
|
||||
'fr' => 'pc',
|
||||
'uc_param_str' => '',
|
||||
];
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/token",
|
||||
"POST",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取要转存资源的详细内容
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getShare($pwd_id,$stoken)
|
||||
{
|
||||
$urlData = array();
|
||||
$queryParams = [
|
||||
"pr" => "ucpro",
|
||||
"fr" => "pc",
|
||||
"uc_param_str" => "",
|
||||
"pwd_id" => $pwd_id,
|
||||
"stoken" => $stoken,
|
||||
"pdir_fid" => "0",
|
||||
"force" => "0",
|
||||
"_page" => "1",
|
||||
"_size" => "100",
|
||||
"_fetch_banner" => "1",
|
||||
"_fetch_share" => "1",
|
||||
"_fetch_total" => "1",
|
||||
"_sort" => "file_type:asc,updated_at:desc"
|
||||
];
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/detail",
|
||||
"GET",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转存资源到指定文件夹
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getShareSave($pwd_id,$stoken,$fid_list,$fid_token_list)
|
||||
{
|
||||
if(!empty($this->to_pdir_fid)){
|
||||
$to_pdir_fid = $this->to_pdir_fid;
|
||||
}else{
|
||||
$to_pdir_fid = Config('qfshop.quark_file'); //默认存储路径
|
||||
if($this->expired_type == 2){
|
||||
$to_pdir_fid = Config('qfshop.quark_file_time'); //临时资源路径
|
||||
}
|
||||
}
|
||||
|
||||
$urlData = array(
|
||||
'fid_list' => $fid_list,
|
||||
'fid_token_list' => $fid_token_list,
|
||||
'to_pdir_fid' => $to_pdir_fid,
|
||||
'pwd_id' => $pwd_id,
|
||||
'stoken' => $stoken,
|
||||
'pdir_fid' => "0",
|
||||
'scene' => "link",
|
||||
);
|
||||
$queryParams = [
|
||||
"entry" => "update_share",
|
||||
"pr" => "ucpro",
|
||||
"fr" => "pc",
|
||||
"uc_param_str" => ""
|
||||
];
|
||||
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/save",
|
||||
"POST",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享资源拿到task_id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getShareBtn($fid_list,$title)
|
||||
{
|
||||
if(!empty($this->ad_fid)){
|
||||
$fid_list[] = $this->ad_fid;
|
||||
}
|
||||
$urlData = array(
|
||||
'fid_list' => $fid_list,
|
||||
'expired_type' => $this->expired_type,
|
||||
'title' => $title,
|
||||
'url_type' => 1,
|
||||
);
|
||||
$queryParams = [
|
||||
"pr" => "ucpro",
|
||||
"fr" => "pc",
|
||||
"uc_param_str" => ""
|
||||
];
|
||||
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/share",
|
||||
"POST",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据task_id拿到自己的资源信息
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getShareTask($task_id,$retry_index)
|
||||
{
|
||||
$urlData = array();
|
||||
$queryParams = [
|
||||
"pr" => "ucpro",
|
||||
"fr" => "pc",
|
||||
"uc_param_str" => "",
|
||||
"task_id" => $task_id,
|
||||
"retry_index" => $retry_index
|
||||
];
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/task",
|
||||
"GET",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据share_id 获取到分享链接
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getSharePassword($share_id)
|
||||
{
|
||||
$urlData = array(
|
||||
'share_id' => $share_id,
|
||||
);
|
||||
$queryParams = [
|
||||
"pr" => "ucpro",
|
||||
"fr" => "pc",
|
||||
"uc_param_str" => ""
|
||||
];
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/share/password",
|
||||
"POST",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除指定资源
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deletepdirFid($filelist)
|
||||
{
|
||||
$urlData = array(
|
||||
'action_type' => 2,
|
||||
'exclude_fids' => [],
|
||||
'filelist' => $filelist,
|
||||
);
|
||||
$queryParams = [
|
||||
"pr" => "ucpro",
|
||||
"fr" => "pc",
|
||||
"uc_param_str" => ""
|
||||
];
|
||||
return $this->executeApiRequest(
|
||||
"https://drive-pc.quark.cn/1/clouddrive/file/delete",
|
||||
"POST",
|
||||
$urlData,
|
||||
$queryParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取夸克网盘指定文件夹内容
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getPdirFid($pdir_fid)
|
||||
{
|
||||
$urlData = [];
|
||||
$queryParams = [
|
||||
'pr' => 'ucpro',
|
||||
'fr' => 'pc',
|
||||
'uc_param_str' => '',
|
||||
'pdir_fid' => $pdir_fid,
|
||||
'_page' => 1,
|
||||
'_size' => 200,
|
||||
'_fetch_total' => 1,
|
||||
'_fetch_sub_dirs' => 0,
|
||||
'_sort' => 'file_type:asc,updated_at:desc',
|
||||
];
|
||||
try {
|
||||
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/file/sort", "GET", json_encode($urlData), $this->urlHeader,$queryParams)['body'];
|
||||
$res = json_decode($res, true);
|
||||
if($res['status'] !== 200){
|
||||
return [];
|
||||
}
|
||||
return $res['data']['list'];
|
||||
} catch (\Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行API请求并处理重试逻辑
|
||||
*
|
||||
* @param string $url 请求URL
|
||||
* @param string $method 请求方法(GET/POST)
|
||||
* @param array $data 请求数据
|
||||
* @param array $queryParams 查询参数
|
||||
* @param int $maxRetries 最大重试次数
|
||||
* @param int $retryDelay 重试延迟(秒)
|
||||
* @return array 响应结果
|
||||
*/
|
||||
protected function executeApiRequest($url, $method, $data = [], $queryParams = [], $maxRetries = 3, $retryDelay = 2)
|
||||
{
|
||||
$attempt = 0;
|
||||
while ($attempt < $maxRetries) {
|
||||
$attempt++;
|
||||
try {
|
||||
$res = curlHelper($url, $method, json_encode($data), $this->urlHeader, $queryParams)['body'];
|
||||
return json_decode($res, true);
|
||||
} catch (\Throwable $e) {
|
||||
$this->logApiError($url, $attempt, $e->getMessage());
|
||||
if ($attempt < $maxRetries) {
|
||||
sleep($retryDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ['status' => 500, 'message' => '接口请求异常'];
|
||||
}
|
||||
/**
|
||||
* 记录API错误日志
|
||||
*
|
||||
* @param string $prefix 日志前缀
|
||||
* @param int $attempt 尝试次数
|
||||
* @param mixed $error 错误信息
|
||||
*/
|
||||
protected function logApiError($prefix, $attempt, $error)
|
||||
{
|
||||
$errorMsg = is_scalar($error) ? $error : json_encode($error);
|
||||
$logMessage = date('Y-m-d H:i:s') . ' ' . $prefix . '请求失败(尝试次数: ' . $attempt . ') 错误: ' . $errorMsg . "\n";
|
||||
file_put_contents('error.log', $logMessage, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
@@ -464,6 +464,7 @@ func GetResourceLink(c *gin.Context) {
|
||||
// TransferResult 转存结果
|
||||
type TransferResult struct {
|
||||
Success bool `json:"success"`
|
||||
Fid string `json:"fid"`
|
||||
SaveURL string `json:"save_url"`
|
||||
ErrorMsg string `json:"error_msg"`
|
||||
}
|
||||
@@ -525,6 +526,8 @@ func performAutoTransfer(resource *entity.Resource) TransferResult {
|
||||
if result.Success {
|
||||
// 更新资源的转存信息
|
||||
resource.SaveURL = result.SaveURL
|
||||
resource.Fid = result.Fid
|
||||
resource.CkID = &account.ID
|
||||
resource.ErrorMsg = ""
|
||||
if err := repoManager.ResourceRepository.Update(resource); err != nil {
|
||||
utils.Error("更新资源转存信息失败: %v", err)
|
||||
@@ -594,10 +597,15 @@ func transferSingleResource(resource *entity.Resource, account entity.Cks, facto
|
||||
|
||||
// 提取转存链接
|
||||
var saveURL string
|
||||
var fid string
|
||||
|
||||
if data, ok := transferResult.Data.(map[string]interface{}); ok {
|
||||
if v, ok := data["shareUrl"]; ok {
|
||||
saveURL, _ = v.(string)
|
||||
}
|
||||
if v, ok := data["fid"]; ok {
|
||||
fid, _ = v.(string)
|
||||
}
|
||||
}
|
||||
if saveURL == "" {
|
||||
saveURL = transferResult.ShareURL
|
||||
@@ -615,6 +623,7 @@ func transferSingleResource(resource *entity.Resource, account entity.Cks, facto
|
||||
return TransferResult{
|
||||
Success: true,
|
||||
SaveURL: saveURL,
|
||||
Fid: fid,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user