This commit is contained in:
Your Name
2026-04-16 11:32:03 +08:00
parent a60bcd9f87
commit 0fff995302
2 changed files with 287 additions and 0 deletions
+259
View File
@@ -0,0 +1,259 @@
# 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!