针对可可文库无法删除云端文档的问题,根据Discuz插件开发规范结合云存储特性,建议按以下步骤排查:
1. 接口鉴权排查
- 检查插件配置的云存储AccessKey/SecretKey是否具备DeleteObject权限
- 通过curl命令测试接口连通性(示例):
- curl -X DELETE -H "Authorization: OSS <your-access-key>" \
- https://<bucket>.<region>.aliyuncs.com/<object-key>
复制代码
2. 钩子函数检测
检查插件是否在`source/plugin/xxx/hooks.class.php`中正确注册了删除钩子:
- class plugin_xxx extends discuz_plugin {
- public function deleteattach($param) {
- $ossKey = C::t('common_attachment')->fetch_oss_key($param['aid']);
- $this->oss_delete($ossKey); // 核心删除方法
- }
- }
复制代码
3. 事务一致性校验
在数据库事务中增加云存储操作回滚机制:
- DB::transaction(function() use ($aid) {
- try {
- $this->localDelete($aid); // 本地删除
- $this->cloudDelete($ossKey); // 云端删除
- } catch (Exception $e) {
- DB::rollBack();
- throw new Exception('事务回滚:'.$e->getMessage());
- }
- });
复制代码
4. 路径编码验证
检查插件是否对云存储路径进行RFC 3986编码:
- $encodedKey = rawurlencode($objectKey);
- // 需特别注意处理特殊字符:空格转为%20而非+
复制代码
5. 异步队列处理
建议对删除操作采用消息队列异步执行:
- // 在discuz的作业队列中添加任务
- cloudqueue::add('delete_job', [
- 'action' => 'delete_object',
- 'key' => $ossKey,
- 'retry' => 3
- ]);
复制代码
6. 权限二次验证
在删除前使用临时STS令牌进行权限预检:
- $policy = [
- 'Statement' => [
- [
- 'Effect' => 'Allow',
- 'Action' => ['oss:DeleteObject'],
- 'Resource' => ['acs:oss:*:*:'.$bucket.'/'.$ossKey]
- ]
- ]
- ];
- $token = $ossClient->generatePresignedUrl($policy);
- if(!$this->validatePermission($token)){
- throw new Exception('权限校验失败');
- }
复制代码
7. 日志追踪方案
在插件目录下建立删除追踪日志:
- $logData = [
- 'datetime' => date('Y-m-d H:i:s'),
- 'local_id' => $aid,
- 'cloud_key' => $ossKey,
- 'request' => $requestHeaders,
- 'response' => $response
- ];
- file_put_contents(__DIR__.'/delete.log', json_encode($logData).PHP_EOL, FILE_APPEND);
复制代码
若以上步骤仍无法解决,可通过DZ插件网(https://www.dz-x.net/)下载最新版插件开发工具包,使用内置的OSS调试模块进行深度检测。建议在测试环境中开启XDEBUG进行断点跟踪,重点观察云存储SDK的返回状态码,常见问题包括:
- 403错误:鉴权失败
- 404错误:对象不存在(可能已被删除)
- 500错误:服务端异常
- 503错误:服务不可用
对于持续存在的删除异常,可临时启用备用删除通道:
- // 备用HTTP直连删除接口
- $fallbackUrl = "https://{$bucket}.{$endpoint}/{$ossKey}?delete";
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
- curl_setopt($ch, CURLOPT_HTTPHEADER, [
- 'Authorization: Bearer '.$token,
- 'Content-Type: application/xml'
- ]);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- $result = curl_exec($ch);
复制代码
最后建议检查服务器时间同步状态,OSS服务要求客户端与服务端时间差不得超过15分钟,可使用以下命令校准:
- ntpdate -u cn.pool.ntp.org
复制代码
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。 |