Files
zyt/DIAGNOSIS_IMAGE_URL_PREFIX_FIX.md
2026-04-16 11:32:03 +08:00

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:

  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):

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

  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:
    {
      "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:
    {
      "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:
    {
      "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:
    {
      "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.

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!