72 lines
2.2 KiB
PHP
72 lines
2.2 KiB
PHP
<?php
|
||
|
||
namespace Modules\EcommerceFinance\Services;
|
||
|
||
use Illuminate\Support\Facades\Cache;
|
||
use Illuminate\Support\Facades\Http;
|
||
|
||
/**
|
||
* 通过钉钉「下载审批附件」接口把审批表单里的附件(spaceId/fileId)换成
|
||
* 钉盘临时下载地址。应用凭证复用登录用的企业内部应用
|
||
* (config('dingtalk.client_id' / 'client_secret'))。
|
||
*/
|
||
class DingTalkApprovalAttachmentDownloader
|
||
{
|
||
private const GET_TOKEN_URL = 'https://oapi.dingtalk.com/gettoken';
|
||
|
||
private const GRANT_DOWNLOAD_URL = 'https://api.dingtalk.com/v1.0/workflow/processInstances/spaces/files/urls/download';
|
||
|
||
private const TOKEN_CACHE_KEY = 'dingtalk:app_access_token';
|
||
|
||
public function downloadUri(string $processInstanceId, string $fileId): ?string
|
||
{
|
||
$token = $this->accessToken();
|
||
|
||
if ($token === null) {
|
||
return null;
|
||
}
|
||
|
||
$response = Http::withHeaders(['x-acs-dingtalk-access-token' => $token])
|
||
->timeout(20)
|
||
->post(self::GRANT_DOWNLOAD_URL, [
|
||
'processInstanceId' => $processInstanceId,
|
||
'fileId' => $fileId,
|
||
]);
|
||
|
||
if (! $response->successful()) {
|
||
report(new \RuntimeException(
|
||
'dingtalk approval attachment grant failed: HTTP ' . $response->status()
|
||
));
|
||
|
||
return null;
|
||
}
|
||
|
||
$uri = (string) $response->json('result.downloadUri');
|
||
|
||
return $uri !== '' ? $uri : null;
|
||
}
|
||
|
||
private function accessToken(): ?string
|
||
{
|
||
$clientId = (string) config('dingtalk.client_id');
|
||
$secret = (string) config('dingtalk.client_secret');
|
||
|
||
if ($clientId === '' || $secret === '') {
|
||
return null;
|
||
}
|
||
|
||
$token = Cache::remember(self::TOKEN_CACHE_KEY, now()->addMinutes(100), function () use ($clientId, $secret): ?string {
|
||
$response = Http::timeout(15)->get(self::GET_TOKEN_URL, [
|
||
'appkey' => $clientId,
|
||
'appsecret' => $secret,
|
||
]);
|
||
|
||
$token = (string) $response->json('access_token');
|
||
|
||
return $token !== '' ? $token : null;
|
||
});
|
||
|
||
return is_string($token) && $token !== '' ? $token : null;
|
||
}
|
||
}
|