上传多张图片,重点在于处理图片的整个的过程逻辑,在添加商品的时候,同时上传多张图片。
首先分析问题,上传商品,需要一个商品表product,存商品的详细信息;上传图片,需要一个图片
表img,来存图片的路径等详细信息;如果只上传一张图片,那么可以在商品表上加一个图片的img_id
字段来找到商品图片,但是这里是一个商品对应多张图片,就需要再建立一个中间表product_img来
关联商品和图片,这个表最简单的就是三个字段,id主键,product_id商品外键id,img_id图片外键id,
这就是数据库的准备。
我实现添加商品的整个过程是:用户先可以输入其他文字信息,当上传图片的时候,选好图片上
传,后台接受图片并将图片信息存到img表里,成功的话会返回图片在img表里的id和url路径,前端接受
到这个,就将图片的id存到一个imgID数组里,新添加一个
会将图片id传到后台把img表里的数据删除,将服务器下的图片资源删除,成功后返回前端,前端会将
imgID数组里对应的id数据删除。接着其他数据都填好后,点击提交,就将商品的基本信息和图片数组
imgID一起传给后台,后台处理时,先将商品的基本信息存到数据库里,成功后可以得到商品的id,再将
商品的id和imgID存到product_img表里,这样就完成了添加商品的同时上传多张图片。
前端代码(本人用的是layer框架搭建的,读者可自由修改格式):
js部分:
//主图片数组
mainImgIds = new Array();
//上传主图片函数
function upload_fun() {
//假设我上传了一张图片,触发change事件后
var $this = $('#upload');
var file = $this[0]; //获得dom对象
var formFile = new FormData(); //FormData是异步上传的前提
formFile.append('image', file.files[0]);//把文件存到FormData中
$.ajax({
url: "/", //请求路径
type: "POST", //请求方式
data: formFile, //传递参数
contentType: false,
processData: false,
dataType: 'json', //
success: function (data) {
mainImgIds.push(data.imgId); //将图片id存到数组里
layer.alert('上传成功');
//将图片返给用户
$('.main').children('.list').removeClass('hide')
.append('
},
error: function (error) {
layer.alert('上传失败');
}
})
}
//删除主图片,只需要删除image里的表
function delMainImg(imgId){
$.ajax({
url:'/product/delMainImgA',
data:{'imgId':imgId},
tokenFlag:true,
type:'post',
sCallback:function(res) {
for (var i = 0; i < mainImgIds.length; i++) {
if (mainImgIds[i] == imgId){
//删除数组中的id
mainImgIds.splice(i,1);
}
}
layer.alert("删除成功");
$("#m"+imgId).remove();
},
eCallback:function(res){
layer.alert('删除失败');
}
})
}
后端代码:
//增加商品
public function addProduct(){
$mainImgIds = request()->post('mainImgIds');
//product表增加数据
$name = request()->post('name');
$price = request()->post('price');
$uid = TokenService::getCurrentUid();
$pro = new ProductModel();
$pro->data([
'name' => $name,
'price' => $price,
]);
$pro->save();
if($pro->id){
//往主图片表中添加数据
$mImg = new ProductMainImage();
//传过来是字符串,转为数组,没有图片id是传过来的是空数组,过滤掉这种情况
if($mainImgIds != ''){
$mainImgs = explode(",",$mainImgIds);
foreach($mainImgs as $p){
$mImg->insert(['img_id'=>$p,'product_id'=>$pro->id]);
}
return $pro->id;
}else{
return null;
}
}
//添加商品时删除图片,只需要删除image表里的数据
public function delMainImgA(){
$imgId = input('post.imgId');
//找到图片
$img = Image::where('id',$imgId)
->find();
//config('setting.img_prefix')是我图片的前缀域名,例如http://z.cn/,不用管
$url = str_replace(config('setting.img_prefix'),'',$img->url);
//将反斜杠都换一致
$s=str_replace('\\', '/', '../public/images');
//删除图片资源
$r = unlink($s.$url);
//删除表信息
if($r){
$img->delete();
}
return $r;
}
//添加图片到img表
public function addImg($url){
$img= new ImageModel();
$img->save(['url'=>$url]);
return $img->id;
}
//添加商品图返回图片id和存储路径
public function getImgIdUrl(){
$file = request()->file('image');//获取上传图片
// 移动到框架应用根目录/public/images/ 目录下
if ($file) {
try{
$info = $file->move(ROOT_PATH . 'public' . DS . 'images');
}catch (Exception $e){
echo "错误:".$e->getMessage();
}
if ($info) {
$getSaveName=str_replace("\\","/",$info->getSaveName());
$img = $getSaveName;//获取名称
$imgpath ='/'. $img;
$imgId = $this->addImg($imgpath);
$path = 'images'. $imgpath;//数据库存储路径
return [
'status' => 1,
'path' => $path,
'imgId'=>$imgId
];
} else {
$message = '图片上传失败';
return ['status' => 0, 'message' => $message];
}
} else {
$message = '图片上传失败';
return ['status' => 0, 'message' => $message];
}
}