更新
This commit is contained in:
+277
@@ -0,0 +1,277 @@
|
||||
# 医生资质图片数据流转说明
|
||||
|
||||
## 完整数据流转过程
|
||||
|
||||
### 1. 添加/编辑医生(管理后台)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 前端(Vue3) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 用户上传图片 │
|
||||
│ ↓ │
|
||||
│ material-picker 组件 │
|
||||
│ ↓ │
|
||||
│ formData.qualification_images = [ │
|
||||
│ "https://www.d.com/uploads/images/20260317/image1.png", │
|
||||
│ "https://www.d.com/uploads/images/20260317/image2.png" │
|
||||
│ ] │
|
||||
│ ↓ │
|
||||
│ 提交表单(POST请求) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 后端接口(AdminController) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 接收参数: │
|
||||
│ $params['qualification_images'] = [ │
|
||||
│ "https://www.d.com/uploads/images/20260317/image1.png", │
|
||||
│ "https://www.d.com/uploads/images/20260317/image2.png" │
|
||||
│ ] │
|
||||
│ ↓ │
|
||||
│ 调用 AdminLogic::add() 或 AdminLogic::edit() │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 业务逻辑层(AdminLogic) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ // 数据转换处理 │
|
||||
│ if (is_array($params['qualification_images'])) { │
|
||||
│ $qualificationImages = json_encode( │
|
||||
│ $params['qualification_images'], │
|
||||
│ JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES │
|
||||
│ ); │
|
||||
│ } │
|
||||
│ ↓ │
|
||||
│ 转换后的数据: │
|
||||
│ $qualificationImages = '["https://www.d.com/uploads/images/ │
|
||||
│ 20260317/image1.png","https://www.d.com/uploads/images/ │
|
||||
│ 20260317/image2.png"]' │
|
||||
│ ↓ │
|
||||
│ 保存到数据库 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 数据库(MySQL) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ la_admin 表 │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ qualification_images (text) │ │
|
||||
│ ├──────────────────────────────────────────────────────────┤ │
|
||||
│ │ ["https://www.d.com/uploads/images/20260317/image1.png",│ │
|
||||
│ │ "https://www.d.com/uploads/images/20260317/image2.png"] │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2. 查看医生详情(管理后台)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 前端(Vue3) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 点击编辑按钮 │
|
||||
│ ↓ │
|
||||
│ 调用 adminDetail({ id: 1 }) │
|
||||
│ ↓ │
|
||||
│ GET /adminapi/auth.admin/detail?id=1 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 后端接口(AdminController) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 调用 AdminLogic::detail(['id' => 1]) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 业务逻辑层(AdminLogic) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ // 从数据库查询 │
|
||||
│ $admin = Admin::field([...])->find()->toArray(); │
|
||||
│ ↓ │
|
||||
│ 查询结果: │
|
||||
│ $admin['qualification_images'] = '["https://www.d.com/uploads/ │
|
||||
│ images/20260317/image1.png","https://www.d.com/uploads/images/ │
|
||||
│ 20260317/image2.png"]' │
|
||||
│ ↓ │
|
||||
│ // 转换为数组格式 │
|
||||
│ if (!empty($admin['qualification_images'])) { │
|
||||
│ $images = json_decode($admin['qualification_images'], true);│
|
||||
│ if (is_array($images)) { │
|
||||
│ $admin['qualification_images'] = $images; │
|
||||
│ } │
|
||||
│ } │
|
||||
│ ↓ │
|
||||
│ 转换后的数据: │
|
||||
│ $admin['qualification_images'] = [ │
|
||||
│ "https://www.d.com/uploads/images/20260317/image1.png", │
|
||||
│ "https://www.d.com/uploads/images/20260317/image2.png" │
|
||||
│ ] │
|
||||
│ ↓ │
|
||||
│ 返回给前端 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 前端(Vue3) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 接收响应数据: │
|
||||
│ formData.qualification_images = [ │
|
||||
│ "https://www.d.com/uploads/images/20260317/image1.png", │
|
||||
│ "https://www.d.com/uploads/images/20260317/image2.png" │
|
||||
│ ] │
|
||||
│ ↓ │
|
||||
│ material-picker 组件直接使用数组数据 │
|
||||
│ ↓ │
|
||||
│ 显示图片列表 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3. 小程序端查看医生详情
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 小程序前端(uni-app) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 进入医生详情页 │
|
||||
│ ↓ │
|
||||
│ GET /api/doctor/detail?id=1 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 后端接口(DoctorController) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 调用 DoctorLogic::getDoctorDetail($doctorId) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 业务逻辑层(DoctorLogic) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ // 从数据库查询 │
|
||||
│ $doctor = Admin::field([...])->find()->toArray(); │
|
||||
│ ↓ │
|
||||
│ 查询结果(保持JSON字符串格式): │
|
||||
│ $doctorData['qualification_images'] = '["https://www.d.com/ │
|
||||
│ uploads/images/20260317/image1.png","https://www.d.com/uploads/ │
|
||||
│ images/20260317/image2.png"]' │
|
||||
│ ↓ │
|
||||
│ 直接返回(不转换) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 小程序前端(uni-app) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 接收响应数据: │
|
||||
│ doctor.value.qualification_images = '["https://www.d.com/ │
|
||||
│ uploads/images/20260317/image1.png","https://www.d.com/uploads/ │
|
||||
│ images/20260317/image2.png"]' │
|
||||
│ ↓ │
|
||||
│ // 使用 computed 解析 │
|
||||
│ const qualificationImages = computed(() => { │
|
||||
│ if (!doctor.value?.qualification_images) return [] │
|
||||
│ try { │
|
||||
│ const images = typeof doctor.value.qualification_images │
|
||||
│ === 'string' │
|
||||
│ ? JSON.parse(doctor.value.qualification_images) │
|
||||
│ : doctor.value.qualification_images │
|
||||
│ return Array.isArray(images) ? images : [] │
|
||||
│ } catch (e) { │
|
||||
│ return [] │
|
||||
│ } │
|
||||
│ }) │
|
||||
│ ↓ │
|
||||
│ 解析后的数据: │
|
||||
│ qualificationImages.value = [ │
|
||||
│ "https://www.d.com/uploads/images/20260317/image1.png", │
|
||||
│ "https://www.d.com/uploads/images/20260317/image2.png" │
|
||||
│ ] │
|
||||
│ ↓ │
|
||||
│ 渲染图片网格 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 关键点总结
|
||||
|
||||
### 1. 数据格式转换时机
|
||||
|
||||
| 场景 | 输入格式 | 输出格式 | 转换位置 |
|
||||
|------|---------|---------|---------|
|
||||
| 添加医生 | 数组 | JSON字符串 | AdminLogic::add() |
|
||||
| 编辑医生 | 数组 | JSON字符串 | AdminLogic::edit() |
|
||||
| 管理后台查看 | JSON字符串 | 数组 | AdminLogic::detail() |
|
||||
| 小程序端查看 | JSON字符串 | JSON字符串 | 不转换,前端解析 |
|
||||
|
||||
### 2. 为什么管理后台要转换回数组?
|
||||
|
||||
因为 `material-picker` 组件需要数组格式的数据:
|
||||
```vue
|
||||
<material-picker v-model="formData.qualification_images" :limit="9" />
|
||||
```
|
||||
|
||||
如果传入JSON字符串,组件无法正确显示已上传的图片。
|
||||
|
||||
### 3. 为什么小程序端不转换?
|
||||
|
||||
1. 保持API返回数据的一致性
|
||||
2. 减少后端处理逻辑
|
||||
3. 前端有完善的解析和容错机制
|
||||
4. 便于缓存和传输
|
||||
|
||||
### 4. JSON编码参数说明
|
||||
|
||||
```php
|
||||
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
||||
```
|
||||
|
||||
- `JSON_UNESCAPED_UNICODE`: 不转义中文字符
|
||||
- `JSON_UNESCAPED_SLASHES`: 不转义URL中的斜杠 `/`
|
||||
|
||||
这样可以保证:
|
||||
- URL正确性:`https://` 不会变成 `https:\/\/`
|
||||
- 中文文件名正确显示
|
||||
- 减少字符串长度
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 验证数据转换是否正确
|
||||
|
||||
```php
|
||||
// 测试代码
|
||||
$testData = [
|
||||
"https://www.d.com/uploads/images/20260317/测试图片1.png",
|
||||
"https://www.d.com/uploads/images/20260317/测试图片2.png"
|
||||
];
|
||||
|
||||
// 编码
|
||||
$encoded = json_encode($testData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
echo "编码后: " . $encoded . "\n";
|
||||
// 输出: ["https://www.d.com/uploads/images/20260317/测试图片1.png","https://www.d.com/uploads/images/20260317/测试图片2.png"]
|
||||
|
||||
// 解码
|
||||
$decoded = json_decode($encoded, true);
|
||||
var_dump($decoded);
|
||||
// 输出: array(2) { [0]=> string(...) [1]=> string(...) }
|
||||
```
|
||||
Reference in New Issue
Block a user