7.5 KiB
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:
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:
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:
- Parse the images/files array (JSON or comma-separated)
- Get current domain using
request()->domain() - For each URL in the array:
- Check if URL is empty → skip
- Check if URL starts with
http://orhttps://→ skip (already has protocol) - Otherwise → prepend domain to the URL
Examples:
Relative Path (Needs Domain):
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):
Input: "https://cdn.example.com/images/tongue.jpg"
Output: "https://cdn.example.com/images/tongue.jpg"
HTTP URL (Skip):
Input: "http://example.com/image.jpg"
Output: "http://example.com/image.jpg"
Empty URL (Skip):
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
- Create a diagnosis with tongue images stored as relative paths:
/uploads/images/tongue/2024/01/image.jpg - Fetch diagnosis detail via API
- Verify response contains:
{ "tongue_images": [ "https://admin.zhenyangtang.com.cn/uploads/images/tongue/2024/01/image.jpg" ] }
2. Test Absolute URLs
- Create a diagnosis with absolute URL:
https://cdn.example.com/images/tongue.jpg - Fetch diagnosis detail
- Verify URL is unchanged:
{ "tongue_images": [ "https://cdn.example.com/images/tongue.jpg" ] }
3. Test Mixed URLs
- Create a diagnosis with both relative and absolute URLs:
[ "/uploads/local.jpg", "https://cdn.example.com/remote.jpg" ] - Fetch diagnosis detail
- Verify correct processing:
{ "tongue_images": [ "https://admin.zhenyangtang.com.cn/uploads/local.jpg", "https://cdn.example.com/remote.jpg" ] }
4. Test Empty/Null Values
- Create a diagnosis with empty images
- Fetch diagnosis detail
- Verify empty array is returned:
{ "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_imagesprocessing - Updated
report_filesprocessing
- Updated
Database:
tcm_diagnosistabletongue_imagescolumn (stores JSON or comma-separated paths)report_filescolumn (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!