Преглед на файлове

退货管理录入上传图片,并校验录入商品的质量状态

haozi преди 4 години
родител
ревизия
c930ce50e6

+ 8 - 1
app/Http/Controllers/RejectedBillItemController.php

@@ -8,6 +8,7 @@ use App\Events\InformWMSReceivedEvent;
 use App\Owner;
 use App\RejectedBill;
 use App\RejectedBillItem;
+use App\Services\RejectedBillItemService;
 use App\UploadFile;
 use App\WMSReflectReceive;
 use App\WMSReflectReceiveSku;
@@ -32,6 +33,8 @@ class RejectedBillItemController extends Controller
         if(!empty($errorFields)){
             return ['success'=>'false','error_fields'=>$errorFields,'failure_info'=>'fileds error'];
         }
+        /** @var RejectedBillItemService $service */
+        $service=app('RejectedBillItemService');
         $rejectedBillItem=RejectedBillItem::where('barcode_goods',$request->input('barcode_goods'))
             ->where('id_quality_label',$request->input('id_quality_label'))
             ->where('id_rejected_bill',$request->input('id_rejected_bill'))->first();
@@ -46,6 +49,8 @@ class RejectedBillItemController extends Controller
             $rejectedBillItem->save();
         }
 
+        $packageImage=$service->uploadImages($request->packageImages??[],$rejectedBillItem->id,'外箱');
+        $commodityImages=$service->uploadImages($request->commodityImages??[],$rejectedBillItem->id,'产品');
         if (!$rejectedBillItem->rejectedBill || !$rejectedBillItem->rejectedBill->owner)return ['success'=>'false','failure_info'=>'退货单或货主不存在'];
 
 //        /** @var CommodityService $commodityService */
@@ -320,7 +325,8 @@ class RejectedBillItemController extends Controller
         if(!$request->input('id_rejected_bill')){
             return ['success'=>'false','failure_info'=>'表头id不能为空'];
         }
-        $rejectedBillItems = RejectedBillItem::query()->with(['uploadFiles'])->where('id_rejected_bill',$request->input('id_rejected_bill'))->get();
+        $rejectedBillItems = RejectedBillItem::query()->with(['uploadFiles','packageImages','commodityImages'])
+            ->where('id_rejected_bill',$request->input('id_rejected_bill'))->get();
         return ['success'=>'true','items'=>$rejectedBillItems];
     }
     public function apiDelete(Request $request)
@@ -377,6 +383,7 @@ class RejectedBillItemController extends Controller
                     "table_id"=>$id,
                     "url"=>'/files/'.$fileName,
                     "type"=>$fileExtension,
+                    "file_name"=>$request->type??'',
                 ]);
                 if ($uploadFile->save())
                     app('LogService')->log(__CLASS__,'退货详情图片上传',json_encode($request),Auth::user()['id']);

+ 20 - 0
app/Http/Controllers/TestController.php

@@ -703,4 +703,24 @@ sql;
             $workOrder->save();
         }
     }
+
+    public function testLabor()
+    {
+//        $datas=['22668','22669','22673','22675','22676','22677','22678','22679','22682','22684','22686','22688','22691','22693','22695','22698'];//嘉权
+        $datas=['22680','22687','22690','22692','22697','22700',];//金旋
+        foreach ($datas as $data){
+//            LaborReportStatus::query()->create([
+//                'labor_report_id'=>$data,
+//                'created_at'=>'2021-11-22 18:10:00',
+//                'status'=>'已退场'
+//            ]);
+
+            LaborReport::query()->where('id',$data)->update([
+                'check_in_at'=>'2021-11-23 09:00:00',
+                'verify_at'=>'2021-11-23 09:00:00',
+                'group_user_id'=>84,
+                'user_workgroup_id'=>4,
+            ]);
+        }
+    }
 }

+ 13 - 1
app/RejectedBillItem.php

@@ -35,8 +35,20 @@ class RejectedBillItem extends Model
     public function quality(){
         return $this->belongsTo(QualityLabel::class, 'id_quality_label', 'id');
     }
+    public function packageImages(){
+        return $this->hasMany(UploadFile::class,'table_id','id')
+            ->where('table_name','rejected_bill_items')
+            ->where('file_name','外箱');
+    }
+    public function commodityImages(){
+        return $this->hasMany(UploadFile::class,'table_id','id')
+            ->where('table_name','rejected_bill_items')
+            ->where('file_name','产品');
+    }
     public function uploadFiles(){
-        return $this->hasMany(UploadFile::class,'table_id','id')->where('table_name','rejected_bill_items');
+        return $this->hasMany(UploadFile::class,'table_id','id')
+            ->where('table_name','rejected_bill_items')
+            ->whereNull('file_name');
     }
     public function wmsReflectSku(){
         $bill=$this->rejectedBill()->first();

+ 37 - 0
app/Services/RejectedBillItemService.php

@@ -3,7 +3,12 @@
 namespace App\Services;
 
 use App\RejectedBillItem;
+use App\Traits\ModelLogChanging;
 use App\Traits\ServiceAppAop;
+use App\UploadFile;
+use Illuminate\Support\Facades\Auth;
+use Intervention\Image\Facades\Image;
+use Ramsey\Uuid\Uuid;
 
 
 class RejectedBillItemService
@@ -11,5 +16,37 @@ class RejectedBillItemService
     use ServiceAppAop;
     protected $modelClass=RejectedBillItem::class;
 
+    public function uploadImages($files,$id,$type): int
+    {
+        if (!$files) return 1; //无图片上传
+        foreach ($files as $file) {
+            if (!$file->isValid()) return 2;//找不到图片
+            $tmpFile = $file->getRealPath();
+            if (!is_uploaded_file($tmpFile)) return 3;//文件错误
+            $fileExtension = $file->getClientOriginalExtension();
+            $fileName = date('ymd') . '-' . Uuid::uuid1();//thumbnail common bulky
+            $thumbnailName = storage_path('app/public/files/' . $fileName . '-thumbnail.' . $fileExtension);
+            $commonName = storage_path('app/public/files/' . $fileName . '-common.' . $fileExtension);
+            $bulkyName = storage_path('app/public/files/' . $fileName . '-bulky.' . $fileExtension);
+            $result = move_uploaded_file($tmpFile, $bulkyName);
+            if ($result) {
+                $img = Image::make($bulkyName);
+                if ($img->height() > $img->width())
+                    $img->heighten(250)->save($commonName);
+                else $img->widen(250)->save($commonName);
+                $img->heighten(28)->save($thumbnailName);
+                /** @var UploadFile|\stdClass $uploadFile */
+                $uploadFile = new UploadFile([
+                    "table_name" => "rejected_bill_items",
+                    "table_id" => $id,
+                    "url" => '/files/' . $fileName,
+                    "type" => $fileExtension,
+                    "file_name" => $type,
+                ]);
+                if ($uploadFile->save()) return 0;//上传成功
+            }
+        }
+    }
+
 
 }

+ 2 - 1
app/Services/RejectedService.php

@@ -24,7 +24,8 @@ class RejectedService
     private function  conditionQuery(array $param)
     {
         $owners = Auth::user() ? (app('UserService')->getPermittingOwnerIds(Auth::user()) ?? []) : [];
-        $rejectedBills = RejectedBill::query()->with('user','owner', 'logistic', 'items.quality', 'items.uploadFiles','orderIssueRejectedBill:logistic_number_return')
+        $rejectedBills = RejectedBill::query()->with('user','owner', 'logistic', 'items.quality',
+            'items.packageImages','items.commodityImages','items.uploadFiles','orderIssueRejectedBill:logistic_number_return')
             ->orderBy('rejected_bills.id', 'desc')
             ->whereIn('rejected_bills.id_owner', $owners);
         if (array_search("397",$owners)!==false){

+ 189 - 1
resources/views/rejected/create.blade.php

@@ -278,6 +278,8 @@
                                     <th class="text-center">效期</th>
                                     <th class="text-center">批次号</th>
                                     <th class="text-center">备注</th>
+                                    <th class="text-center">外箱图</th>
+                                    <th class="text-center">产品图</th>
                                     <th class="text-center">照片</th>
                                     @can('退货管理-删除')
                                         <th class="text-center">操作</th>@endcan
@@ -293,6 +295,30 @@
                                     <td>@{{item.validity_at}}</td>
                                     <td>@{{item.batch_number}}</td>
                                     <td>@{{item.remark}}</td>
+                                    <td>
+                                        <div align="center" @mouseleave="removeCommonImg('common_img_package'+item.id)" @mouseenter="commonImg('img_package'+item.id,item.package_images)">
+                                            <div>
+                                                <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(item.id,'外箱')" value="上传图片 "/>
+                                                <input multiple type="file" @change="submitImages($event,i)" :id="item.id"
+                                                       style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
+                                            </div>
+                                            <div :id="'img_package'+item.id">
+                                                <img v-for="uploadFile in item.package_images"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                                            </div>
+                                        </div>
+                                    </td>
+                                    <td>
+                                        <div align="center" @mouseleave="removeCommonImg('common_img_commodity'+item.id)" @mouseenter="commonImg('img_commodity'+item.id,item.commodity_images)">
+                                            <div>
+                                                <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(item.id,'产品')" value="上传图片 "/>
+                                                <input multiple type="file" @change="submitImages($event,i)" :id="item.id"
+                                                       style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
+                                            </div>
+                                            <div :id="'img_commodity'+item.id">
+                                                <img v-for="uploadFile in item.commodity_images"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                                            </div>
+                                        </div>
+                                    </td>
                                     <td>
                                         <div align="center" @mouseleave="removeCommonImg('common_img_'+item.id)" @mouseenter="commonImg('img_'+item.id,item.upload_files)">
                                             <button class="btn btn-outline-secondary btn-sm" @click="takePhoto(item.id,i)">拍照上传</button>
@@ -420,6 +446,48 @@
                                     </div>
                                 </td>
                             </tr>
+                            <tr v-if="!status.itemEditing">
+                                <td>
+                                    <div class="form-group mb-0">
+                                        <label for="package-image" class="col-form-label text-right">外箱图</label>
+                                        <div class="border border-secondary h-auto" id="package-image" style="min-height: 65px"
+                                             contenteditable="true"
+                                             @paste="pasteImage($event,itemInputting.packageImages)">
+                                            <div v-for="(image,i) in itemInputting.packageImages"
+                                                 class="d-inline-block col-4 position-relative card">
+                                                <div class="card-body">
+                                                    <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                                    <div class="float-right position-relative" >
+                                                        <button type="button" class="btn btn-sm btn-outline-danger"
+                                                                @click="spliceImage(i,itemInputting.packageImages)">取消
+                                                        </button>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </td>
+                                <td>
+                                    <div class="form-group mb-0">
+                                        <label for="commodity-image" class="col-form-label text-right">产品图</label>
+                                        <div class="border border-secondary h-auto" id="commodity-image" style="min-height: 65px"
+                                             contenteditable="true"
+                                             @paste="pasteImage($event,itemInputting.commodityImages)">
+                                            <div v-for="(image,i) in itemInputting.commodityImages"
+                                                 class="d-inline-block col-4 position-relative card">
+                                                <div class="card-body">
+                                                    <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                                    <div class="float-right position-relative">
+                                                        <button type="button" class="btn btn-sm btn-outline-danger"
+                                                                @click="spliceImage(i,itemInputting.commodityImages)">取消
+                                                        </button>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </td>
+                            </tr>
                             <tr>
                                 <td>
                                     <div class="form-group mb-0 align-items-center row">
@@ -578,6 +646,7 @@
                 itemInputting: {
                     barcode_goods: "", name_goods: "", amount: "1", id_quality_label: "",
                     batch_number: "", validity_at: "", remark: "", made_at: "",
+                    packageImages: [], commodityImages: [],
                 },
                 billInputting: {
                     id_owner: "", mobile_sender: "", sender: "", order_number: "", remark: "",
@@ -593,6 +662,7 @@
                     batch_number: "", validity_at: "", remark: "", made_at: "",
                 },
                 rejectedBills: {!! $rejectedBills??[] !!},
+                submitImageType:'',
                 items: [],
                 owners: [
                         @foreach($owners as $owner)
@@ -661,6 +731,43 @@
                     });
 
                 },
+                spliceImage(i, images) {
+                    if (!confirm('是否取消选择该图片')) return;
+                    images.splice(i, 1);
+                },
+                getImages(images) {
+                    return images.map((item) => {
+                        return item.file;
+                    })
+                },
+                pasteImage(event,imageArray){
+                    for (let i = 0; i < event.clipboardData.items.length; i++) {
+                        let item = event.clipboardData.items[i];
+                        if (item.kind === 'string') continue;
+                        if (item.type.indexOf('image') === -1) continue;
+                        if (item.kind === 'file'){
+                            let blob = item.getAsFile();
+                            let src = null;
+                            this.blobToBase64(blob).then(res => {
+                                src  = res;
+                                imageArray.push({src:res,file:blob});
+                            });
+                        }
+                    }
+                    event.preventDefault();
+                },
+                blobToBase64(blob) {
+                    return new Promise((resolve, reject) => {
+                        const fileReader = new FileReader();
+                        fileReader.onload = (e) => {
+                            resolve(e.target.result);
+                        };
+                        fileReader.readAsDataURL(blob);
+                        fileReader.onerror = () => {
+                            reject(new Error('blobToBase64 error'));
+                        };
+                    });
+                },
                 barcode_goodsChange: function (e) {
                     let _this = this;
                     let barcode = $(e.target).val();
@@ -875,8 +982,46 @@
                         alert('连接错误:' + response)
                     });
                 },
+                checkImageWhetherNeed(item){
+                    if (item.id_quality_label!=1){
+                        if (item.commodityImages.length===0){
+                            tempTip.setDuration(3000);
+                            tempTip.show('非正品,请上传外箱图及产品图!');
+                            return 1;
+                        }
+                    }
+                    return 0;
+                },
+                setFormDataImage(formData, prefix, images) {
+                    images.forEach((item) => {
+                        formData.append(`${prefix}[]`, item);
+                    });
+                },
+                getDamagedFormData(item){
+                    let _this=this;
+                    let formData = new FormData();
+                    if (item.packageImages.length>0){
+                        let packageImages = _this.getImages(item.packageImages);
+                        this.setFormDataImage(formData,'packageImages',packageImages);
+                    }
+                    if (item.commodityImages.length>0){
+                        let commodityImages = _this.getImages(item.commodityImages);
+                        this.setFormDataImage(formData,'commodityImages',commodityImages);
+                    }
+                    formData.append('barcode_goods',item.barcode_goods);
+                    formData.append('amount',item.amount);
+                    formData.append('name_goods',item.name_goods);
+                    formData.append('id_quality_label',item.id_quality_label);
+                    formData.append('batch_number',item.batch_number);
+                    formData.append('validity_at',item.validity_at);
+                    formData.append('made_at',item.made_at);
+                    formData.append('remark',item.remark);
+                    formData.append('id_rejected_bill',item.id_rejected_bill);
+                    return formData;
+                },
                 commitItem: function () {
                     let _this = this;
+                    if (_this.checkImageWhetherNeed(_this.itemInputting)===1)return;
                     let url = '{{url('apiLocal/rejectedBillItem/store')}}';
                     _this.itemInputting.id_rejected_bill = _this.status.editingBill.id;
                     if (_this.items.length < 1) {
@@ -888,7 +1033,9 @@
                             _this.isChangeOwner(_this.itemInputting.id_rejected_bill);
                         }
                     }
-                    axios.post(url, _this.itemInputting).then(function (response) {
+                    let formData = _this.getDamagedFormData(_this.itemInputting);
+
+                    axios.post(url, formData,{'Content-Type':'multipart/form-data'}).then(function (response) {
                         _this.cleanError();
                         if (response.data.success === 'true') {
                             tempTip.setDuration(1000);
@@ -1185,6 +1332,10 @@
                         return true;
                     });
                     if (itemTarget) {
+                        // itemTarget.packageImages = itemTarget.package_images;//package_images
+                        // itemTarget.commodityImages = itemTarget.commodity_images;//commodity_images
+                        // delete itemTarget.package_images;
+                        // delete itemTarget.commodity_images;
                         this.itemInputting = JSON.parse(JSON.stringify(itemTarget));
                         this.shiftToEditItem();
                         this.setEditingItem(itemTarget.id)
@@ -1325,6 +1476,34 @@
                         return "上传成功";
                     },false,true);
                 },
+                certiimg(id,type){
+                    this.submitImageType=type;
+                    $('#'+id).click();
+                },
+                submitImages(e,index){
+                    let type=this.submitImageType;
+                    let files=e.target.files;
+                    window.tempTip.setDuration(3000);
+                    if (files.length===0){window.tempTip.show("未选定图片!");return;}
+                    let formData=new FormData();
+                    for (let i=0;i<files.length;i++){
+                        if (files[i].size >=5242880){window.tempTip.show("图片大小不能超过5MB!");return;}
+                        formData.append("files[]",files[i]);
+                    }
+                    formData.append("id",this.items[index].id);
+                    formData.append("type",type);
+                    window.tempTip.postBasicRequest('{{url('apiLocal/rejectedBillItem/apiUpload')}}',formData,res=>{
+                       if (type==='外箱'){
+                           if (this.items[index].package_images.length===0) this.$set(this.items[index],'package_images',res);
+                           else this.$set(this.items[index],'package_images',this.items[index].package_images.concat(res));
+                       }
+                       if (type==='产品'){
+                           if (this.items[index].commodity_images.length===0) this.$set(this.items[index],'commodity_images',res);
+                           else this.$set(this.items[index],'commodity_images',this.items[index].commodity_images.concat(res));
+                       }
+                        return "上传成功";
+                    },false,true);
+                },
                 removeCommonImg(id){
                     $('#'+id).remove();
                 },
@@ -1350,6 +1529,7 @@
                     this.destroyImg(id,url);
                 },
                 destroyImg(id,url = null){
+                    id= id.replace(/[^0-9]/ig,"");//抽取数字部分
                     window.tempTip.postBasicRequest('{{url('apiLocal/rejectedBillItem/apiDeleteImg')}}',{id:id,url:url},()=>{
                         if (url){
                             this.items.some((item,i)=>{
@@ -1357,12 +1537,20 @@
                                     item.upload_files.some((file,j)=>{
                                         if (file.url === url){this.$delete(this.items[i].upload_files,j);return true;}
                                     });
+                                    item.package_images.some((file,j)=>{
+                                        if (file.url === url){this.$delete(this.items[i].package_images,j);return true;}
+                                    });
+                                    item.commodity_images.some((file,j)=>{
+                                        if (file.url === url){this.$delete(this.items[i].commodity_images,j);return true;}
+                                    });
                                     return true;
                                 }
                             });
                         }else{
                             this.items.forEach((item,i)=>{
                                 if (id.includes(item.id))this.$set(this.items[i],'upload_files',[]);
+                                if (id.includes(item.id))this.$set(this.items[i],'commodity_images',[]);
+                                if (id.includes(item.id))this.$set(this.items[i],'package_images',[]);
                             });
                         }
                         return "删除成功";

+ 185 - 2
resources/views/rejected/edit.blade.php

@@ -240,6 +240,8 @@
                                     <th class="text-center">效期</th>
                                     <th class="text-center">批次号</th>
                                     <th class="text-center">备注</th>
+                                    <th class="text-center">外箱图</th>
+                                    <th class="text-center">产品图</th>
                                     <th class="text-center">照片</th>
                                     @can('退货管理-删除')<th class="text-center">操作</th>@endcan
                                 </tr>
@@ -254,6 +256,30 @@
                                     <td>@{{item.validity_at}}</td>
                                     <td>@{{item.batch_number}}</td>
                                     <td>@{{item.remark}}</td>
+                                    <td>
+                                        <div align="center" @mouseleave="removeCommonImg('common_img_package'+item.id)" @mouseenter="commonImg('img_package'+item.id,item.package_images)">
+                                            <div>
+                                                <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(item.id,'外箱')" value="上传图片 "/>
+                                                <input multiple type="file" @change="submitImages($event,i)" :id="item.id"
+                                                       style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
+                                            </div>
+                                            <div :id="'img_package'+item.id">
+                                                <img v-for="uploadFile in item.package_images"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                                            </div>
+                                        </div>
+                                    </td>
+                                    <td>
+                                        <div align="center" @mouseleave="removeCommonImg('common_img_commodity'+item.id)" @mouseenter="commonImg('img_commodity'+item.id,item.commodity_images)">
+                                            <div>
+                                                <input class="btn  btn-sm btn-outline-secondary" type="button" @click="certiimg(item.id,'产品')" value="上传图片 "/>
+                                                <input multiple type="file" @change="submitImages($event,i)" :id="item.id"
+                                                       style="display: none" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"/>
+                                            </div>
+                                            <div :id="'img_commodity'+item.id">
+                                                <img v-for="uploadFile in item.commodity_images"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                                            </div>
+                                        </div>
+                                    </td>
                                     <td>
                                         <div align="center" @mouseleave="removeCommonImg('common_img_'+item.id)" @mouseenter="commonImg('img_'+item.id,item.upload_files)">
                                             <button class="btn btn-outline-secondary btn-sm" @click="takePhoto(item.id,i)">拍照上传</button>
@@ -362,6 +388,48 @@
                                     </div>
                                 </td>
                             </tr>
+                            <tr v-if="!status.itemEditing">
+                                <td>
+                                    <div class="form-group mb-0">
+                                        <label for="package-image" class="col-form-label text-right">外箱图</label>
+                                        <div class="border border-secondary h-auto" id="package-image" style="min-height: 65px"
+                                             contenteditable="true"
+                                             @paste="pasteImage($event,itemInputting.packageImages)">
+                                            <div v-for="(image,i) in itemInputting.packageImages"
+                                                 class="d-inline-block col-4 position-relative card">
+                                                <div class="card-body">
+                                                    <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                                    <div class="float-right position-relative" >
+                                                        <button type="button" class="btn btn-sm btn-outline-danger"
+                                                                @click="spliceImage(i,itemInputting.packageImages)">取消
+                                                        </button>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </td>
+                                <td>
+                                    <div class="form-group mb-0">
+                                        <label for="commodity-image" class="col-form-label text-right">产品图</label>
+                                        <div class="border border-secondary h-auto" id="commodity-image" style="min-height: 65px"
+                                             contenteditable="true"
+                                             @paste="pasteImage($event,itemInputting.commodityImages)">
+                                            <div v-for="(image,i) in itemInputting.commodityImages"
+                                                 class="d-inline-block col-4 position-relative card">
+                                                <div class="card-body">
+                                                    <img :src="image.src" class="card-img-top" :alt="image.file.name">
+                                                    <div class="float-right position-relative">
+                                                        <button type="button" class="btn btn-sm btn-outline-danger"
+                                                                @click="spliceImage(i,itemInputting.commodityImages)">取消
+                                                        </button>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </td>
+                            </tr>
                             <tr>
                                 <td>
                                     <div class="form-group mb-0 align-items-center row" >
@@ -495,6 +563,7 @@
                 stopRecordCallback:'',
                 // 用于存放是否开启了视频录制
                 videoEnabled:false,
+                submitImageType:'',
 
                 status: {billCreating:true,billEditing:false,itemCreating:true,itemEditing:false
                     ,editingBill:null,editingBillId:'',editingItem:null,editingItemId:''
@@ -502,7 +571,7 @@
                     existItemsBeforeAdd:0},
                 itemInputting:{
                     barcode_goods:"",name_goods:"",amount:"1",id_quality_label:"",
-                    batch_number:"",validity_at:"",remark:"",made_at:"",
+                    batch_number:"",validity_at:"",remark:"",made_at:"",packageImages:[],commodityImages:[],
                 },
                 billInputting:{
                     id_owner:"",mobile_sender:"",sender:"",order_number:"",remark:"",
@@ -756,11 +825,88 @@
                         alert('连接错误:'+response)
                     });
                 },
+                spliceImage(i, images) {
+                    if (!confirm('是否取消选择该图片')) return;
+                    images.splice(i, 1);
+                },
+                getImages(images) {
+                    return images.map((item) => {
+                        return item.file;
+                    })
+                },
+                pasteImage(event,imageArray){
+                    for (let i = 0; i < event.clipboardData.items.length; i++) {
+                        let item = event.clipboardData.items[i];
+                        if (item.kind === 'string') continue;
+                        if (item.type.indexOf('image') === -1) continue;
+                        if (item.kind === 'file'){
+                            let blob = item.getAsFile();
+                            let src = null;
+                            this.blobToBase64(blob).then(res => {
+                                src  = res;
+                                imageArray.push({src:res,file:blob});
+                            });
+                        }
+                    }
+                    event.preventDefault();
+                },
+                blobToBase64(blob) {
+                    return new Promise((resolve, reject) => {
+                        const fileReader = new FileReader();
+                        fileReader.onload = (e) => {
+                            resolve(e.target.result);
+                        };
+                        fileReader.readAsDataURL(blob);
+                        fileReader.onerror = () => {
+                            reject(new Error('blobToBase64 error'));
+                        };
+                    });
+                },
+                checkImageWhetherNeed(item){
+                    if (item.id_quality_label!=1){
+                        if (item.commodityImages.length===0){
+                            tempTip.setDuration(3000);
+                            tempTip.show('非正品,请上传外箱图及产品图!');
+                            return 1;
+                        }
+                    }
+                    return 0;
+                },
+                setFormDataImage(formData, prefix, images) {
+                    images.forEach((item) => {
+                        formData.append(`${prefix}[]`, item);
+                    });
+                },
+                getDamagedFormData(item){
+                    let _this=this;
+                    let formData = new FormData();
+                    if (item.packageImages.length>0){
+                        let packageImages = _this.getImages(item.packageImages);
+                        this.setFormDataImage(formData,'packageImages',packageImages);
+                    }
+                    if (item.commodityImages.length>0){
+                        let commodityImages = _this.getImages(item.commodityImages);
+                        this.setFormDataImage(formData,'commodityImages',commodityImages);
+                    }
+                    formData.append('barcode_goods',item.barcode_goods);
+                    formData.append('amount',item.amount);
+                    formData.append('name_goods',item.name_goods);
+                    formData.append('id_quality_label',item.id_quality_label);
+                    formData.append('batch_number',item.batch_number);
+                    formData.append('validity_at',item.validity_at);
+                    formData.append('made_at',item.made_at);
+                    formData.append('remark',item.remark);
+                    formData.append('id_rejected_bill',item.id_rejected_bill);
+                    return formData;
+                },
                 commitItem:function () {
                     let _this=this;
+                    if (_this.checkImageWhetherNeed(_this.itemInputting)===1)return;
                     let url='{{url('apiLocal/rejectedBillItem/store')}}';
                     _this.itemInputting.id_rejected_bill=_this.status.editingBill.id;
-                    axios.post(url,_this.itemInputting).then(function (response) {
+                    let formData = _this.getDamagedFormData(_this.itemInputting);
+
+                    axios.post(url,formData,{'Content-Type':'multipart/form-data'}).then(function (response) {
                         _this.cleanError();
                         if(response.data.success==='true'){
                             tempTip.setDuration(1000);
@@ -1085,6 +1231,34 @@
                 removeCommonImg(id){
                     $('#'+id).remove();
                 },
+                certiimg(id,type){
+                    this.submitImageType=type;
+                    $('#'+id).click();
+                },
+                submitImages(e,index){
+                    let type=this.submitImageType;
+                    let files=e.target.files;
+                    window.tempTip.setDuration(3000);
+                    if (files.length===0){window.tempTip.show("未选定图片!");return;}
+                    let formData=new FormData();
+                    for (let i=0;i<files.length;i++){
+                        if (files[i].size >=5242880){window.tempTip.show("图片大小不能超过5MB!");return;}
+                        formData.append("files[]",files[i]);
+                    }
+                    formData.append("id",this.items[index].id);
+                    formData.append("type",type);
+                    window.tempTip.postBasicRequest('{{url('apiLocal/rejectedBillItem/apiUpload')}}',formData,res=>{
+                        if (type==='外箱'){
+                            if (this.items[index].package_images.length===0) this.$set(this.items[index],'package_images',res);
+                            else this.$set(this.items[index],'package_images',this.items[index].package_images.concat(res));
+                        }
+                        if (type==='产品'){
+                            if (this.items[index].commodity_images.length===0) this.$set(this.items[index],'commodity_images',res);
+                            else this.$set(this.items[index],'commodity_images',this.items[index].commodity_images.concat(res));
+                        }
+                        return "上传成功";
+                    },false,true);
+                },
                 commonImg(id,uploadFiles){
                     let div = "";
                     let isBtn = '@can('运输管理-运单-图片删除') true @endcan ';
@@ -1107,6 +1281,7 @@
                     this.destroyImg(id,url);
                 },
                 destroyImg(id,url = null){
+                    id= id.replace(/[^0-9]/ig,"");//抽取数字部分
                     window.tempTip.postBasicRequest('{{url('apiLocal/rejectedBillItem/apiDeleteImg')}}',{id:id,url:url},()=>{
                         if (url){
                             this.items.some((item,i)=>{
@@ -1114,12 +1289,20 @@
                                     item.upload_files.some((file,j)=>{
                                         if (file.url === url){this.$delete(this.items[i].upload_files,j);return true;}
                                     });
+                                    item.package_images.some((file,j)=>{
+                                        if (file.url === url){this.$delete(this.items[i].package_images,j);return true;}
+                                    });
+                                    item.commodity_images.some((file,j)=>{
+                                        if (file.url === url){this.$delete(this.items[i].commodity_images,j);return true;}
+                                    });
                                     return true;
                                 }
                             });
                         }else{
                             this.items.forEach((item,i)=>{
                                 if (id.includes(item.id))this.$set(this.items[i],'upload_files',[]);
+                                if (id.includes(item.id))this.$set(this.items[i],'commodity_images',[]);
+                                if (id.includes(item.id))this.$set(this.items[i],'package_images',[]);
                             });
                         }
                         return "删除成功";

+ 23 - 7
resources/views/rejected/search/general.blade.php

@@ -89,13 +89,13 @@
                         @cannot('退货管理-客户不可见')<td class="text-muted">@{{rejectedBill.common_02}}</td>@endcannot
                         <td class="text-muted"><span>@{{rejectedBill.goods_amount}}</span></td>
                         <td style="min-width: 1500px">
-                            <div class="w-100 p-0" :class="rejectedBill.items.length>1 ? 'up' : ''" :id="'rejected-'+rejectedBill.id" >
-                                <div class="row m-0 p-0" v-for="(item,i) in rejectedBill.items">
+                            <div class="w-100" :class="rejectedBill.items.length>1 ? 'up' : ''" :id="'rejected-'+rejectedBill.id" >
+                                <div class="row m-0" v-for="(item,i) in rejectedBill.items">
                                     @if($ownerSign)
                                     <div class="col-1 border border-1" style="overflow-x: hidden">
                                         <div class="w-100 text-overflow-warp-200 warp-min-200">@{{ (item.barcode && item.barcode.commodity) ? item.barcode.commodity.sku : '' }}</div>
                                     </div>@endif
-                                        <div title="双击展开全部" @dblclick="barcodeGoodsLength(item)"  class="border border-1" :class="item.barcode_goods_show_long ? 'col-auto' : '@if($ownerSign)col-2 @else col-3 @endif'" style="overflow-x: hidden">
+                                        <div title="双击展开全部" @dblclick="barcodeGoodsLength(item)"  class="border border-1" :class="item.barcode_goods_show_long ? 'col-auto' : '@if($ownerSign)col-1 @else col-1 @endif'" style="overflow-x: hidden">
                                             <div class="w-100 text-overflow-warp-200 warp-min-200">@{{item.barcode_goods}}</div>
                                         </div>
                                     <div title="双击展开全部" @dblclick="goodsNameLength(item)"  class="border border-1" :class="item.name_goods_show_long ? 'col-auto' : 'col-1'" style="overflow-x: hidden">
@@ -106,6 +106,20 @@
                                     <div class="col-1 border border-1">@{{item.batch_number}}</div>
                                     <div class="col-1 border border-1">@{{item.made_at}}</div>
                                     <div class="col-1 border border-1">@{{item.validity_at}}</div>
+                                        <div class="col-1 border border-1">
+                                            <div align="center" @mouseleave="removeCommonImg('common_img_package'+item.id)" @mouseenter="commonImg('img_package'+item.id,item.package_images)">
+                                                <div :id="'img_package'+item.id">
+                                                    <img v-for="uploadFile in item.package_images"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="col-1 border border-1">
+                                            <div align="center" @mouseleave="removeCommonImg('common_img_commodity'+item.id)" @mouseenter="commonImg('img_commodity'+item.id,item.commodity_images)">
+                                                <div :id="'img_commodity'+item.id">
+                                                    <img v-for="uploadFile in item.commodity_images"  :src="imgPrefix+uploadFile.url+'-thumbnail.'+uploadFile.type">
+                                                </div>
+                                            </div>
+                                        </div>
                                     <div class="col-1 border border-1">
                                         <div align="center" @mouseleave="removeCommonImg('common_img_'+item.id)" @mouseenter="commonImg('img_'+item.id,item.upload_files)">
                                             <div :id="'img_'+item.id">
@@ -113,7 +127,7 @@
                                             </div>
                                         </div>
                                     </div>
-                                    <div class="col-2 border border-1">@{{item.remark}}</div>
+                                    <div class="col-1 border border-1">@{{item.remark}}</div>
                                 </div>
                             </div>
                             <div class="text-center cursor-pointer" v-if="rejectedBill.items.length>1" @click="unfold(rejectedBill.id)">
@@ -260,16 +274,18 @@
                         @cannot('退货管理-客户不可见'){name:'common_02',value: '重量'},@endcannot
                     {name:'goods_amount',value: '商品总数'},
                     {name:"goods",type:"multi",title:"商品信息",rows:[
-                            @if($ownerSign){value:"商品SKU",col:"1"},{value:"商品条码",col:"2"},
-                                @else{value:"商品条码",col:"3"},@endif
+                            @if($ownerSign){value:"商品SKU",col:"1"},{value:"商品条码",col:"1"},
+                                @else{value:"商品条码",col:"1"},@endif
                             {value:"商品名称",col:"1"},
                             {value:"数量",col:"1"},
                             {value:"质量",col:"1"},
                             {value:"批次号",col:"1"},
                             {value:"产期",col:"1"},
                             {value:"效期",col:"1"},
+                            {value:"外箱图",col:"1"},
+                            {value:"产品图",col:"1"},
                             {value:"照片",col:"1"},
-                            {value:"备注",col:"2"},
+                            {value:"备注",col:"1"},
                         ]},
                     {name:'remark',value: '退单备注'},
                     {name:'operator_name',value: '录入人'},