isAbsolute($path)) { return $path; } return rtrim((string) config('app.url'), '/') . '/' . ltrim($path, '/'); } /** * 入库:本站域名下的地址存成相对路径,避免换域名后历史数据全指向旧域名; * 第三方 OSS 地址保持原样 */ public function toStorage(?string $url): string { $url = trim((string) $url); if ($url === '') { return ''; } $appUrl = rtrim((string) config('app.url'), '/'); if ($appUrl !== '' && str_starts_with($url, $appUrl)) { return substr($url, strlen($appUrl)) ?: ''; } return $url; } /** * 批量出库,给 list 用 */ public function publicEach(array &$rows, array $fields): void { foreach ($rows as &$row) { foreach ($fields as $field) { if (array_key_exists($field, $row)) { $row[$field] = $this->toPublic($row[$field]); } } } unset($row); } /** * 前端图片上传组件回传的是数组,取第一个;已是字符串则原样 */ public function firstOf(mixed $value): string { if (is_array($value)) { $value = $value[0] ?? ''; } return $this->toStorage(is_string($value) ? $value : ''); } /** * 去掉 OSS 处理参数(?imageView2/... 或 ?watermark/...),用于素材库按 path 做引用匹配 */ public function stripProcessParams(?string $url): string { $url = trim((string) $url); if ($url === '') { return ''; } $pos = strpos($url, '?'); return $pos === false ? $url : substr($url, 0, $pos); } private function isAbsolute(string $path): bool { return (bool) preg_match('#^(https?:)?//#i', $path); } }