# 图片上传完整使用指南
# 📋 概述
本指南涵盖了项目中图片上传的完整功能,包括:
- 图片上传组件
input_image_magnifier - 图片服务接口
image.php - 图片放大镜功能
image-magnifier.js - 完整的图片生命周期管理
# 🚀 快速开始
# 1. 基础图片上传组件
<!-- 最简单的用法 -->
<{input type="image_magnifier" name="image_field"}>
<!-- 完整参数示例 -->
<{input type="image_magnifier"
name="material_image"
target_type="material"
target_id="<{$material_info.bm_id}>"
display_width="150"
display_height="150"
magnifier="true"}>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 2. 控制器中的图片处理
// 在控制器中处理图片上传
if (isset($_FILES['material_image']) && !empty($_FILES['material_image']['name'])) {
$imageModel = app::get('image')->model('image');
$result = $imageModel->uploadAndAttach(
$_FILES['material_image']['tmp_name'],
'material',
$material_id,
$_FILES['material_image']['name']
);
if (isset($result['error'])) {
$this->end(false, '图片上传失败:' . $result['error']);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 🎯 核心组件
# input_image_magnifier 组件
# 参数说明
| 参数 | 类型 | 必需 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | ✅ | - | 表单字段名称 |
image_src | string | ❌ | - | 图片源URL(最高优先级) |
value | string | ❌ | - | 图片ID(第二优先级) |
target_type | string | ❌ | - | 目标对象类型(第三优先级) |
target_id | string | ❌ | - | 目标对象ID(第三优先级) |
display_width | int | ❌ | 50 | 显示宽度 |
display_height | int | ❌ | 50 | 显示高度 |
magnifier | bool | ❌ | true | 是否启用放大镜 |
# 图片获取优先级
- 第一优先级:
image_src- 直接使用传入的图片URL - 第二优先级:
value(image_id) - 通过image.php的dump方法获取 - 第三优先级:
target_type+target_id- 通过getAttachedImages方法获取
# 使用场景
<!-- 新增页面 -->
<{input type="image_magnifier"
name="material_image"
target_type="material"
display_width="150"
display_height="150"}>
<!-- 编辑页面 -->
<{input type="image_magnifier"
name="material_image"
target_type="material"
target_id="<{$material_info.bm_id}>"
display_width="150"
display_height="150"}>
<!-- 直接指定图片 -->
<{input type="image_magnifier"
name="material_image"
image_src="<{$image_url}>"}>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 🔧 图片服务接口
# 核心方法
# 1. uploadAndAttach() - 一站式上传
$imageModel = app::get('image')->model('image');
$result = $imageModel->uploadAndAttach(
$file, // 图片文件路径
$target_type, // 目标类型
$target_id, // 目标对象ID
$name, // 图片名称(可选)
$sizes, // 生成的尺寸数组(可选)
$watermark // 是否添加水印(可选)
);
// 返回:成功返回图片信息数组,失败返回 array('error' => '错误信息')
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 2. getAttachedImages() - 获取关联图片
$images = $imageModel->getAttachedImages(
'material', // 目标类型
$material_id, // 目标ID
'S' // 图片尺寸(可选:L/M/S)
);
1
2
3
4
5
2
3
4
5
# 3. detach() - 删除关联
$success = $imageModel->detach(
$image_id, // 图片ID
'material', // 目标类型
$target_id, // 目标ID
true // 是否同时删除文件
);
1
2
3
4
5
6
2
3
4
5
6
# 使用示例
# 物料图片管理
// 上传物料图片
if (isset($_FILES['material_image']) && !empty($_FILES['material_image']['name'])) {
$imageModel = app::get('image')->model('image');
$result = $imageModel->uploadAndAttach(
$_FILES['material_image']['tmp_name'],
'material',
$material_id,
$_FILES['material_image']['name']
);
if (isset($result['error'])) {
$this->end(false, '图片上传失败:' . $result['error']);
}
}
// 获取物料图片
$images = $imageModel->getAttachedImages('material', $material_id, 'M');
$mainImage = !empty($images) ? $images[0] : null;
// 删除物料图片
$imageModel->detach($image_id, 'material', $material_id, true);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 商品图片管理
// 上传商品图片(生成多尺寸)
$result = $imageModel->uploadAndAttach(
$file,
'goods',
$goods_id,
'product.jpg',
['L', 'M', 'S'], // 生成大、中、小三种尺寸
true // 添加水印
);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 🔍 图片放大镜功能
# 基本使用
图片放大镜功能已全局加载,无需额外引入。项目提供两种使用方式:
- 完整版 ImageMagnifier 类 - 功能强大,支持智能缩放、回调函数、动态配置
- 简化版全局函数 - 轻量级,可直接在HTML中使用
# HTML设置
<!-- 使用ref属性指定放大镜图片源(推荐) -->
<img src="thumb.jpg" ref="full-size.jpg" class="img-magnifier" />
<!-- 或者使用rel属性 -->
<img src="thumb.jpg" rel="full-size.jpg" class="img-magnifier" />
<!-- 使用data-src属性 -->
<img src="thumb.jpg" data-src="full-size.jpg" class="img-magnifier" />
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# JavaScript调用
# 简化版全局函数(推荐用于简单场景)
// 为图片添加放大镜功能
showImageMagnifier(event, element);
// 更新放大镜位置
updateImageMagnifierPosition(event);
// 隐藏放大镜
hideImageMagnifier();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 完整版 ImageMagnifier 类(推荐用于复杂场景)
// 单个元素
var magnifier = new ImageMagnifier('img.zoomable', {
maxWidth: 800,
maxHeight: 600,
maxScale: 3
});
// 批量应用
var magnifiers = ImageMagnifier.applyToElements('.gallery img', {
maxWidth: 600,
maxHeight: 600
});
// 动态更新配置
magnifier.updateOptions({
maxWidth: 800,
maxHeight: 800
});
// 销毁实例
magnifier.destroy();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 配置选项
# 简化版配置
- 最大尺寸:800x600px
- 最大倍数:3倍放大
- 智能缩放:自动计算最佳显示比例
- 位置偏移:可调整显示位置
# 完整版配置
var options = {
maxWidth: 800, // 最大显示宽度
maxHeight: 600, // 最大显示高度
maxScale: 3, // 最大放大倍数
offset: {x: 30, y: -20}, // 位置偏移
className: 'magnifier-tip', // 自定义CSS类
showDelay: 0, // 显示延迟(ms)
hideDelay: 0, // 隐藏延迟(ms)
fixed: false, // 是否固定位置
fade: true, // 是否使用淡入淡出
onShow: function(tip, element) {
// 显示回调
console.log('放大镜显示', element);
},
onHide: function(tip, element) {
// 隐藏回调
console.log('放大镜隐藏', element);
},
onLoad: function(img, size) {
// 图片加载完成回调
console.log('图片加载完成', size);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 使用场景示例
# 产品图片展示
<div class="product-images">
<img src="product-thumb-1.jpg" rel="product-full-1.jpg" class="product-img" />
<img src="product-thumb-2.jpg" rel="product-full-2.jpg" class="product-img" />
</div>
<script>
// 为所有产品图片添加放大镜
ImageMagnifier.applyToElements('.product-img', {
maxWidth: 500,
maxHeight: 500,
offset: {x: 20, y: -10}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 图片上传预览
<div id="image-preview">
<img id="uploaded-image" src="" style="display: none;" />
</div>
<script>
function previewImage(file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = $('uploaded-image');
img.set('src', e.target.result);
img.setStyle('display', 'block');
// 添加放大镜
new ImageMagnifier(img, {
maxWidth: 600,
maxHeight: 600
});
};
reader.readAsDataURL(file);
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 📝 完整实现示例
# 1. 前端模板
<!-- app/material/view/admin/material/basic/edit.html -->
<{input type="image_magnifier"
name="material_image"
target_type="material"
target_id="<{$material_info.bm_id|default:''}>"
display_width="150"
display_height="150"}>
1
2
3
4
5
6
7
2
3
4
5
6
7
# 2. 后端控制器
// app/material/controller/admin/material/basic.php
public function toEdit() {
// ... 其他逻辑 ...
// 处理图片上传
$submittedImageId = !empty($_POST['current_image_id']) ? $_POST['current_image_id'] : null;
$originalImageId = null;
if ($filter['bm_id']) {
$imageModel = app::get('image')->model('image');
$attachedImages = $imageModel->getAttachedImages('material', $filter['bm_id']);
if ($attachedImages) {
$originalImageId = $attachedImages[0]['image_id'];
}
}
// 比较图片ID是否发生变化
if ($submittedImageId !== $originalImageId) {
// 删除原图片
if ($originalImageId) {
$imageModel->detach($originalImageId, 'material', $filter['bm_id'], true);
}
// 上传新图片
if (isset($_FILES['material_image']) && !empty($_FILES['material_image']['name'])) {
$result = $imageModel->uploadAndAttach(
$_FILES['material_image']['tmp_name'],
'material',
$filter['bm_id'],
$_FILES['material_image']['name']
);
if (isset($result['error'])) {
$this->end(false, '图片上传失败:' . $result['error']);
}
}
}
// ... 其他逻辑 ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 3. 图片模型
// app/image/model/image.php
class image_mdl_image extends base_db_model {
/**
* 上传并关联图片
*/
public function uploadAndAttach($file, $target_type, $target_id, $name = null, $sizes = null, $watermark = false) {
// 验证文件
if (!$this->validateUploadedFile($file)) {
return array('error' => '文件验证失败');
}
// 处理图片
$imageInfo = $this->processImage($file, $name, $sizes, $watermark);
if (!$imageInfo) {
return array('error' => '图片处理失败');
}
// 建立关联
$attachId = $this->attach($imageInfo['image_id'], $target_type, $target_id);
if (!$attachId) {
return array('error' => '关联建立失败');
}
return $imageInfo;
}
/**
* 验证上传文件
*/
private function validateUploadedFile($file) {
// 检查文件大小(最大2MB)
if ($file['size'] > 2 * 1024 * 1024) {
return false;
}
// 检查文件类型
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($file['type'], $allowedTypes)) {
return false;
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# ⚠️ 注意事项
# 1. 文件大小限制
- 最大上传文件大小:2MB
- 支持格式:JPEG、PNG、GIF
# 2. 错误处理
- 所有图片操作都返回具体的错误信息
- 控制器需要检查
error键并返回给用户
# 3. 图片ID比较逻辑
- 通过比较提交的
current_image_id和数据库中的图片ID - 如果不一致,说明图片发生了变化,需要处理
# 4. 组件样式
- 所有样式都统一在
input_image_magnifier.html中管理 - 使用该组件的页面无需重复定义样式
# 🔄 更新日志
# v2.0.0 (2024-12-XX)
- ✅ 重构图片上传逻辑,使用ID比较方式
- ✅ 简化前端删除标记机制
- ✅ 统一图片验证和错误处理
- ✅ 优化图片放大镜功能
- ✅ 完善组件化设计
# v1.0.0 (2024-01-XX)
- ✅ 初始版本发布
- ✅ 基础图片上传功能
- ✅ 图片放大镜组件
- ✅ 图片服务接口
# 🏗️ 技术架构
# 文件结构
app/
├── desktop/
│ ├── statics/
│ │ ├── js/
│ │ │ └── image-magnifier.js # 完整版放大镜组件
│ │ └── js_mini/
│ │ └── image-magnifier.js # 压缩版放大镜组件
│ └── view/
│ └── input_image_magnifier.html # 图片上传组件模板
├── image/
│ └── model/
│ └── image.php # 图片服务模型
└── material/
├── controller/
│ └── admin/
│ └── material/
│ └── basic.php # 物料控制器
└── view/
└── admin/
└── material/
└── basic/
├── add.html # 新增页面
└── edit.html # 编辑页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 核心组件关系
- 前端组件:
input_image_magnifier提供统一的图片上传界面 - 放大镜功能:
image-magnifier.js提供图片预览放大功能 - 后端服务:
image.php模型处理图片上传、存储、关联等逻辑 - 业务集成:各业务控制器调用图片服务,实现业务逻辑
# 数据流程
用户操作 → 前端组件 → 表单提交 → 控制器验证 → 图片服务处理 → 数据库存储 → 返回结果
1
# 🔧 故障排除
# 常见问题
# 1. 图片不显示
- 检查图片路径是否正确
- 确认
ref、rel或data-src属性设置正确 - 查看浏览器控制台错误信息
# 2. 放大镜位置不正确
- 调整
offset配置 - 检查页面CSS是否影响定位
- 确认父容器的
position设置
# 3. 图片上传失败
- 检查文件大小是否超过2MB限制
- 确认文件格式是否支持(JPEG、PNG、GIF)
- 验证服务器权限和存储空间
# 4. 组件样式异常
- 确认
input_image_magnifier.html模板正确加载 - 检查CSS冲突和覆盖问题
- 验证MooTools依赖是否正确加载
# 调试技巧
// 在浏览器控制台中调试放大镜
console.log('ImageMagnifier:', typeof ImageMagnifier);
// 检查全局函数
console.log('showImageMagnifier:', typeof showImageMagnifier);
// 调试图片元素
var img = $('your-image-id');
console.log('Image element:', img);
console.log('Image attributes:', {
src: img.get('src'),
ref: img.get('ref'),
rel: img.get('rel')
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
最后更新:2024年12月
版本:v2.0.0
状态:✅ 可用于生产环境
← 平台对接标准模板 定时任务创建速查手册 →