# Diagnosis Image URL Prefix Fix (诊断图片URL前缀修复) ## Issue Image URLs in the diagnosis detail (tongue_images and report_files) were stored as relative paths without the domain prefix, causing issues when accessing them from external sources or different domains. ## Solution Added logic to automatically prepend the current domain to image URLs that don't already have an `http://` or `https://` prefix. ## Changes Made ### File: `server/app/adminapi/logic/tcm/DiagnosisLogic.php` #### 1. Updated tongue_images Processing Added domain prefix logic after parsing the images array: ```php if (!empty($diagnosis['tongue_images'])) { // 先尝试 JSON 解析(兼容旧数据) $files = json_decode($diagnosis['tongue_images'], true); if (is_array($files)) { $diagnosis['tongue_images'] = $files; } else { // JSON 解析失败则按逗号分割 $diagnosis['tongue_images'] = array_filter(explode(',', $diagnosis['tongue_images'])) ?: []; } // 为没有 http 前缀的图片添加域名 $domain = request()->domain(); $diagnosis['tongue_images'] = array_map(function($url) use ($domain) { if (empty($url)) { return $url; } // 如果已经包含 http:// 或 https://,则跳过 if (stripos($url, 'http://') === 0 || stripos($url, 'https://') === 0) { return $url; } // 添加域名前缀 return $domain . $url; }, $diagnosis['tongue_images']); } else { $diagnosis['tongue_images'] = []; } ``` #### 2. Updated report_files Processing Applied the same logic to report files: ```php if (!empty($diagnosis['report_files'])) { // 先尝试 JSON 解析(兼容旧数据) $files = json_decode($diagnosis['report_files'], true); if (is_array($files)) { $diagnosis['report_files'] = $files; } else { // JSON 解析失败则按逗号分割 $diagnosis['report_files'] = array_filter(explode(',', $diagnosis['report_files'])) ?: []; } // 为没有 http 前缀的文件添加域名 $domain = request()->domain(); $diagnosis['report_files'] = array_map(function($url) use ($domain) { if (empty($url)) { return $url; } // 如果已经包含 http:// 或 https://,则跳过 if (stripos($url, 'http://') === 0 || stripos($url, 'https://') === 0) { return $url; } // 添加域名前缀 return $domain . $url; }, $diagnosis['report_files']); } else { $diagnosis['report_files'] = []; } ``` ## Logic Flow ### URL Processing Logic: 1. Parse the images/files array (JSON or comma-separated) 2. Get current domain using `request()->domain()` 3. For each URL in the array: - Check if URL is empty → skip - Check if URL starts with `http://` or `https://` → skip (already has protocol) - Otherwise → prepend domain to the URL ### Examples: #### Relative Path (Needs Domain): ```php Input: "/uploads/images/tongue/2024/01/image.jpg" Domain: "https://admin.zhenyangtang.com.cn" Output: "https://admin.zhenyangtang.com.cn/uploads/images/tongue/2024/01/image.jpg" ``` #### Absolute URL (Skip): ```php Input: "https://cdn.example.com/images/tongue.jpg" Output: "https://cdn.example.com/images/tongue.jpg" ``` #### HTTP URL (Skip): ```php Input: "http://example.com/image.jpg" Output: "http://example.com/image.jpg" ``` #### Empty URL (Skip): ```php Input: "" Output: "" ``` ## Benefits ### 1. Cross-Domain Compatibility Images can now be accessed from different domains or external applications without path issues. ### 2. API Response Consistency API responses always return complete, accessible URLs regardless of how they were stored. ### 3. Backward Compatibility - Existing relative paths are automatically converted - Existing absolute URLs are preserved - No database migration required ### 4. Flexible Storage - Database can store either relative or absolute paths - System handles both formats transparently - Future-proof for CDN integration ## Use Cases ### 1. Mobile App Access Mobile apps can directly use the returned URLs without needing to construct them. ### 2. Third-Party Integration External systems can access images using the complete URLs from API responses. ### 3. CDN Migration When migrating to CDN, images with absolute CDN URLs will work alongside local relative paths. ### 4. Multi-Domain Setup System works correctly across different domains (dev, staging, production). ## Testing Steps ### 1. Test Relative Path URLs 1. Create a diagnosis with tongue images stored as relative paths: ``` /uploads/images/tongue/2024/01/image.jpg ``` 2. Fetch diagnosis detail via API 3. Verify response contains: ```json { "tongue_images": [ "https://admin.zhenyangtang.com.cn/uploads/images/tongue/2024/01/image.jpg" ] } ``` ### 2. Test Absolute URLs 1. Create a diagnosis with absolute URL: ``` https://cdn.example.com/images/tongue.jpg ``` 2. Fetch diagnosis detail 3. Verify URL is unchanged: ```json { "tongue_images": [ "https://cdn.example.com/images/tongue.jpg" ] } ``` ### 3. Test Mixed URLs 1. Create a diagnosis with both relative and absolute URLs: ``` [ "/uploads/local.jpg", "https://cdn.example.com/remote.jpg" ] ``` 2. Fetch diagnosis detail 3. Verify correct processing: ```json { "tongue_images": [ "https://admin.zhenyangtang.com.cn/uploads/local.jpg", "https://cdn.example.com/remote.jpg" ] } ``` ### 4. Test Empty/Null Values 1. Create a diagnosis with empty images 2. Fetch diagnosis detail 3. Verify empty array is returned: ```json { "tongue_images": [] } ``` ### 5. Test Report Files Repeat all tests above for `report_files` field. ## Technical Details ### Domain Detection Uses `request()->domain()` which returns the current request domain including protocol: - Development: `http://localhost:8000` - Production: `https://admin.zhenyangtang.com.cn` ### Case-Insensitive Protocol Check Uses `stripos()` for case-insensitive checking: - Matches: `http://`, `HTTP://`, `Http://` - Matches: `https://`, `HTTPS://`, `Https://` ### Array Processing Uses `array_map()` for efficient processing of all URLs in the array. ## Related Files ### Backend: - `server/app/adminapi/logic/tcm/DiagnosisLogic.php` - Updated `tongue_images` processing - Updated `report_files` processing ### Database: - `tcm_diagnosis` table - `tongue_images` column (stores JSON or comma-separated paths) - `report_files` column (stores JSON or comma-separated paths) ## Notes ### Storage Format The database continues to store paths as-is (relative or absolute). The conversion happens only when reading data for API responses. ### Performance The `array_map()` operation is efficient and adds minimal overhead. For typical diagnosis records with 1-5 images, the performance impact is negligible. ### Future Enhancements If needed, this logic could be extracted into a helper function for reuse across other file/image fields in the system. ## Summary ✅ Automatically adds domain prefix to relative image URLs ✅ Preserves absolute URLs (http/https) ✅ Handles both tongue_images and report_files ✅ Backward compatible with existing data ✅ Case-insensitive protocol detection ✅ Handles empty/null values gracefully ✅ No database migration required ✅ Works across different domains Image URLs in diagnosis details are now always complete and accessible, improving API usability and cross-domain compatibility!