cqp 3 月之前
父节点
当前提交
2be0daa727

+ 24 - 0
app/Http/Controllers/Api/DataSyncToU8Controller.php

@@ -45,4 +45,28 @@ class DataSyncToU8Controller extends BaseController
             return $this->json_return(201,$data);
         }
     }
+
+    public function getSnForWarranty(Request $request)
+    {
+        $service = new DataSyncToU8Service();
+        list($status,$data) = $service->getSnForWarranty($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function hasWarrantyInfo(Request $request)
+    {
+        $service = new DataSyncToU8Service();
+        list($status,$data) = $service->hasWarrantyInfo($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
 }

+ 138 - 0
app/Http/Controllers/Api/TSpaceController.php

@@ -45,4 +45,142 @@ class TSpaceController extends BaseController
             return $this->json_return(201,$data);
         }
     }
+
+    public function tSpaceList(Request $request)
+    {
+        $service = new TSpaceService();
+        list($status,$data) = $service->tSpaceList($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyGetProduct(Request $request)
+    {
+        $service = new TSpaceService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->warrantyGetProduct($request->all(),$userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyAdd(Request $request)
+    {
+        $service = new TSpaceService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->warrantyAdd($request->all(),$userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function saveWarrantyByMyself(Request $request)
+    {
+        $service = new TSpaceService();
+        list($status,$data) = $service->saveWarrantyByMyself($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function getWarrantyNotActiveList(Request $request)
+    {
+        $service = new TSpaceService();
+        list($status,$data) = $service->getWarrantyNotActiveList($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyActivationCustomer(Request $request)
+    {
+        $service = new TSpaceService();
+        list($status,$data) = $service->warrantyActivationCustomer($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyList(Request $request)
+    {
+        $service = new TSpaceService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->warrantyList($request->all(),$userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyActivation(Request $request)
+    {
+        $service = new TSpaceService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->warrantyActivation($request->all(), $userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyEditAndActivation(Request $request)
+    {
+        $service = new TSpaceService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->warrantyEditAndActivation($request->all(), $userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function warrantyDel(Request $request)
+    {
+        $service = new TSpaceService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->warrantyDel($request->all(), $userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+
+    public function searchWarranty(Request $request)
+    {
+        $service = new TSpaceService();
+        list($status,$data) = $service->searchWarranty($request->all());
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
 }

+ 2 - 0
app/Model/ProductSnInfo.php

@@ -11,8 +11,10 @@ class ProductSnInfo extends UseScopeBaseModel
     const range_function = '';
     const type_one = 1;
     const type_two = 2;
+    const type_three = 3;
     public static $type_name = [
         self::type_one => '施工单',
         self::type_two => '合同',
+        self::type_three => '用户主动创建质保',
     ];
 }

+ 1 - 0
app/Model/RoleMenuButton.php

@@ -20,4 +20,5 @@ class RoleMenuButton extends Model
     const special_seven = -7;
     const special_eight = -8;
     const special_nine = -9;
+    const special_ten = -10;
 }

+ 2 - 0
app/Model/TSpaceSet.php

@@ -16,11 +16,13 @@ class TSpaceSet extends Model
     const Model_type_three = 3;
     const Model_type_four = 4;
     const Model_type_five = 5;
+    const Model_type_six = 6;
     public static $model_type_title = [
         self::Model_type_one => '顶部位置',
         self::Model_type_two => '图片位置',
         self::Model_type_three => '视频位置',
         self::Model_type_four => '精选二手车',
         self::Model_type_five => '精选商品',
+        self::Model_type_six => '我的',
     ];
 }

+ 22 - 0
app/Model/Warranty.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Warranty extends Model
+{
+    protected $guarded = [];
+    protected $table = "warranty"; //指定表
+    const CREATED_AT = 'crt_time';
+    const UPDATED_AT = 'upd_time';
+    protected $dateFormat = 'U';
+    //激活
+    const type_zero = 0;
+    const type_one = 1;
+
+    const STATUS = [
+        self::type_zero => '未激活',
+        self::type_one => '已激活'
+    ];
+}

+ 61 - 4
app/Service/ConstructionService.php

@@ -21,6 +21,7 @@ use App\Model\OaSubReportEmployee;
 use App\Model\OaSubRule;
 use App\Model\Product;
 use App\Model\ProductInventorySet;
+use App\Model\ProductSnInfo;
 use App\Model\ReturnExchangeOrder;
 use App\Model\ReturnExchangeOrderProductInfo;
 use App\Model\SalesOrder;
@@ -42,6 +43,41 @@ use Barryvdh\DomPDF\PDF;
  */
 class ConstructionService extends Service
 {
+    //补录sn码信息
+    public function constructionEditSn($data,$user){
+        list($status,$msg) = $this->constructionEditSnRule($data, $user);
+        if(!$status) return [$status, $msg];
+
+        try {
+            DB::beginTransaction();
+
+            //sn码
+            (new DataSyncToU8Service())->saveSn($data, ProductSnInfo::type_one, time());
+
+            DB::commit();
+        }catch (\Exception $exception){
+            DB::rollBack();
+            return [false,$exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    public function constructionEditSnRule($data, $user){
+        if(empty($data['id'])) return [false,'ID不能为空'];
+        $bool = Construction::where('del_time',0)
+            ->where('id',$data['id'])
+            ->exists();
+        if(! $bool) return [false, '施工单不存在或已被删除'];
+        if(empty($data['product'])) return [false, '产品不能为空'];
+
+        //校验sn码
+        list($status, $msg) = (new DataSyncToU8Service())->checkSnConstructionRule($data);
+        if(! $status) return [false, $msg];
+
+        return [true, ''];
+    }
+
     //小程序端编辑车架号 备注
     public function constructionEditOther($data,$user){
         list($status,$msg) = $this->constructionEditOtherRule($data, $user);
@@ -225,6 +261,9 @@ class ConstructionService extends Service
                 ConstructionFile::insert($insert);
             }
 
+            //sn码
+            (new DataSyncToU8Service())->saveSn($data, ProductSnInfo::type_one, $time);
+
             DB::commit();
         }catch (\Exception $exception){
             DB::rollBack();
@@ -289,6 +328,7 @@ class ConstructionService extends Service
             $model->vin_no = $data['vin_no'] ?? "";
             $model->save();
             $time = time();
+            $data['id'] = $model->id;
 
             if(! empty($data['construction_contact'])){
                 $insert = [];
@@ -362,6 +402,9 @@ class ConstructionService extends Service
             //单据创建时是否校验库存
             (new CheckService())->orderInventoryInsert(['order_number' => $data['order_number'], 'is_check_stock' => $data['is_check_stock']]);
 
+            //sn码
+            (new DataSyncToU8Service())->saveSn($data, ProductSnInfo::type_one, $time);
+
             DB::commit();
         }catch (\Exception $exception){
             DB::rollBack();
@@ -401,12 +444,13 @@ class ConstructionService extends Service
         try {
             DB::beginTransaction();
 
+            $time = time();
             Construction::where('id',$data['id'])->update([
-                'del_time'=> time()
+                'del_time'=> $time
             ]);
             ConstructionInfo::where('del_time',0)
                 ->where('construction_id',$data['id'])
-                ->update(['del_time' => time()]);
+                ->update(['del_time' =>$time]);
             $old = ConstructionFile::where('del_time',0)
                 ->where('construction_id',$data['id'])
                 ->select('file')
@@ -415,15 +459,18 @@ class ConstructionService extends Service
 
             ConstructionFile::where('del_time',0)
                 ->where('construction_id',$data['id'])
-                ->update(['del_time' => time()]);
+                ->update(['del_time' => $time]);
             ConstructionProductInfo::where('del_time',0)
                 ->where('construction_id',$data['id'])
-                ->update(['del_time' => time()]);
+                ->update(['del_time' => $time]);
             (new RangeService())->RangeDelete($data['id'],SeeRange::type_two);
 
             //锁定库存释放
 //            if($construction['model_type'] == Construction::Model_type_one) ProductInventoryService::changeLockNumber($user,[],$product_save);
 
+            //sn码
+            (new DataSyncToU8Service())->saveSn($data, ProductSnInfo::type_one, $time);
+
             DB::commit();
         }catch (\Exception $exception){
             DB::rollBack();
@@ -586,6 +633,9 @@ class ConstructionService extends Service
             ->get()->toArray();
         $basic_price = BasicType::whereIn('id',array_unique(array_column($p_info,'basic_type_id')))->pluck('title','id')->toArray();
         $map = (new ProductService())->getProductDetail(array_column($p_info,'product_id'));
+
+        //sn码信息
+        $sn_map = (new DataSyncToU8Service())->getSn($data, ProductSnInfo::type_one);
         foreach ($p_info as $value){
             $tmp = $map[$value['product_id']] ?? [];
             $value['title'] = $tmp['title'] ?? "";
@@ -594,6 +644,9 @@ class ConstructionService extends Service
             $value['unit'] = $tmp['unit'] ?? "";
             $value['bar_code'] = $tmp['bar_code'] ?? "";
             $value['basic_type_title'] = $basic_price[$value['basic_type_id']] ?? "";
+            $s_t = $sn_map[$value['code']] ?? [];
+            $sn = array_column($s_t,'sn');
+            $value['product_sn_info'] = $sn;
             $construction['product'][] = $value;
         }
         $construction['crt_name'] = $emp_map[$construction['crt_id']] ?? '';
@@ -821,6 +874,10 @@ class ConstructionService extends Service
             $product_id[] = $value['product_id'];
         }
 
+        //校验sn码
+        list($status, $msg) = (new DataSyncToU8Service())->checkSnConstructionRule($data);
+        if(! $status) return [false, $msg];
+
         //剩余能施工
         $id = $data['id'] ?? 0;
         $s_product = $this->getSaveReturnCompareMessage($id, $data['sales_order_id']);

+ 79 - 12
app/Service/DataSyncToU8Service.php

@@ -3,11 +3,13 @@
 namespace App\Service;
 
 use App\Jobs\ProcessDataJob;
+use App\Model\Product;
 use App\Model\ProductCategory;
 use App\Model\ProductSnInfo;
 use App\Model\PurchaseOrder;
 use App\Model\Setting;
 use App\Model\U8Job;
+use App\Model\Warranty;
 
 class DataSyncToU8Service extends Service
 {
@@ -65,7 +67,7 @@ class DataSyncToU8Service extends Service
             //发货单 sn码
         }
 
-        return [true, 'sn_type' => $sn_type];
+        return [true, ['sn_type' => $sn_type]];
     }
 
     public function getSnFromU8($data, $user){
@@ -99,29 +101,31 @@ class DataSyncToU8Service extends Service
      * @param false $is_edit 是否补录
      * @return array|string
      */
-    public function checkSnConstructionRule($data, $is_edit = false){
+    public function checkSnConstructionRule($data){
         //产品字典
         $map = (new ProductService())->getProductDetail(array_column($data['product'],'product_id'));
 
+        $data_id = $data['id'] ?? 0;
         $sn_map = [];
-        if($is_edit) $sn_map = $this->getSn($data, ProductSnInfo::type_one);
+        if($data_id) $sn_map = $this->getSn($data, ProductSnInfo::type_one);
 
         $code = $sn = [];
         foreach ($data['product'] as $value){
             if(empty($value['code'])) return [false, '产品编码不能为空'];
             $code[] = $value['code'];
 
-            //补录校验
-            if($is_edit){
+            //校验是否有不需要剔除的sn
+            if($data_id){
                 $sn_tmp = $sn_map[$value['code']] ?? [];
                 foreach ($sn_tmp as $val){
-                    if(! empty($val['warranty_id']) && ! in_array($val['sn'], $value['product_sn_info'])) return [false,  "产品编码:" . $value['code'] . "选择的sn码". $val['sn'] . "已生成质保,不允许删除"];
+                    if(! empty($val['warranty_id']) && ! in_array($val['sn'], $value['product_sn_info'])) return [false,  "产品编码:" . $value['code'] . "选择的sn码". $val['sn'] . "已生成质保信息,不允许删除"];
                 }
             }
 
             //没有sn码信息直接跳过
             if(empty($value['product_sn_info'])) continue;
             $tmp = $map[$value['product_id']] ?? [];
+            if(empty($tmp['warranty_time'])) return [false, "产品编码:" . $value['code'] . "质保时长(月)暂未设置"];
             $category = json_decode($tmp['product_category'],true);
             //非车窗膜需校验sn码
             if(! in_array(ProductCategory::Special_for_sn, $category)){
@@ -153,7 +157,7 @@ class DataSyncToU8Service extends Service
             foreach ($value['product_sn_info'] as $sn_val){
                 $key = $value['code'] . $sn_val;
                 $submit_info[] = $key;
-                if(! isset($sn_map[$key])) return [false, "产品编码:" . $value['code'] . "的sn序列码:" . $sn_val . "在用友中不存在"];
+                if(! isset($sn_map[$key])) return [false, "产品编码:" . $value['code'] . "的产品序列码:" . $sn_val . "在用友中不存在"];
             }
         }
 
@@ -215,7 +219,7 @@ class DataSyncToU8Service extends Service
         return $map;
     }
 
-    //获取在库的sn码信息
+    //获取在库的sn码信息通过sn码和产品编码
     private function getSnForMap($code, $sn){
         $header = ['Content-Type:application/json'];
         $post = [
@@ -230,26 +234,89 @@ class DataSyncToU8Service extends Service
         return [true, $msg];
     }
 
+    //获取在库的sn码信息通过sn码 客户手动创建质保
+    public function getSnForWarranty($data){
+        if(empty($data['sn'])) return [false, "产品序列码不能为空"];
+        list($status, $msg) = $this->snForWarranty($data);
+        if(! $status) return [false, $msg];
+        $return = $msg;
+
+        $product = Product::where('del_time',0)
+            ->where('code', $return['code'])
+            ->select('id','title','code','warranty_time')
+            ->first();
+        if(empty($product)) return [false, '根据产品序列码查找到的产品编码:' . $return['code'] . '在门店系统中未找到该产品'];
+        $product = $product->toArray();
+        $product['sn'] = $data['sn'];
+
+        return [true, $product];
+    }
+
+    public function snForWarranty($data){
+        $header = ['Content-Type:application/json'];
+        $post = [
+            'urlFromT9' => 'getSnForWarranty',
+            'sn' => $data['sn'],
+        ];
+        $post = json_encode($post);
+        list($status, $msg) = $this->post_helper("https://workapi.qingyaokeji.com/api/getSnForWarranty", $post, $header);
+        if($msg['code'] != 200) return [false, $msg['msg']];
+        $return = $msg['data'] ?? [];
+        if(empty($return)) return [false, '产品序列码不存在'];
+
+        return [true, $return];
+    }
+
+    public function hasWarrantyInfo($data){
+        if(empty($data['customer_contact'])) return [false, "手机号码不能为空"];
+        $bool = Warranty::where('del_time',0)
+            ->where('customer_contact', $data['customer_contact'])
+            ->exists();
+
+        return [true, ['hasWarrantyInfo' => $bool]];
+    }
+
     //校验sn是否被占用
-    private function snForCheck($code = [], $sn = [], $submit_info = [], $data){
+    public function snForCheck($code = [], $sn = [], $submit_info = [], $data = []){
         $save = ProductSnInfo::where('del_time',0)
             ->whereIn("code", $code)
             ->whereIn('sn', $sn)
-            ->select('code','sn','data_id','type')
+            ->select('code','sn','data_id','type','product_id')
             ->get()->toArray();
 
+        $category_map = Product::whereIn('id',array_unique(array_column($save,'product_id')))
+            ->pluck('product_category','id')
+            ->toArray();
+
         $data_id = $data['id'] ?? 0;
+        $data_type = $data['data_type'] ?? ProductSnInfo::type_one;
         foreach ($save as $value){
+            //车窗膜不管sn使用次数
+            $category = $category_map[$value['product_id']] ?? "";
+            $category = json_decode($category,true);
+            if(in_array(ProductCategory::Special_for_sn, $category)) continue;
+
             $key = $value['code'] . $value['sn'];
             if(in_array($key, $submit_info)) {
                 if(! $data_id){
-                    return [false, '产品编码:' . $value['code'] . '的sn码已被' .ProductSnInfo::$type_name[$value['type']]] . '使用';
+                    return [false, '产品编码:' . $value['code'] . '的sn码已在(' .ProductSnInfo::$type_name[$value['type']]] . ')中使用';
                 }else{
-                    if($value['data_id'] != $data_id || $value['type'] != ProductSnInfo::type_one) return [false, '产品编码:' . $value['code'] . '的sn码已被' .ProductSnInfo::$type_name[$value['type']]] . '使用';
+                    if($value['data_id'] != $data_id || $value['type'] != $data_type) return [false, '产品编码:' . $value['code'] . '的sn码已被' .ProductSnInfo::$type_name[$data_type]] . '使用';
                 }
             }
         }
 
         return [true, ''];
     }
+
+    public function updateByVinNo($data){
+        if(empty($data['vin_no']) || empty($data['customer_name']) || empty($data['customer_contact'])) return;
+        $vin_no = $data['vin_no'];
+        $customer_name = $data['customer_name'];
+        $customer_contact = $data['customer_contact'];
+
+        Warranty::where('del_time',0)
+            ->where('vin_no',$vin_no)
+            ->update(["customer_name" => $customer_name, 'customer_contact' => $customer_contact]);
+    }
 }

+ 78 - 0
app/Service/SalesOrderService.php

@@ -16,6 +16,8 @@ use App\Model\OutBoundOrderInfo;
 use App\Model\PaymentReceipt;
 use App\Model\PaymentReceiptInfo;
 use App\Model\Product;
+use App\Model\ProductCategory;
+use App\Model\ProductSnInfo;
 use App\Model\PurchaseOrder;
 use App\Model\ReturnExchangeOrder;
 use App\Model\ReturnExchangeOrderProductInfo;
@@ -1154,6 +1156,7 @@ class SalesOrderService extends Service
                 if(! empty($value['sports_bag_id']) && ! in_array($value['sports_bag_id'], $sports_bag_id)) $sports_bag_id[] = $value['sports_bag_id'];
             }
         }
+        if(! empty($sports_bag_id)) return [false, '销售订单活动包暂未开放'];
 
         if(! empty($data['contract_fee'])){
             $res = $this->checkNumber($data['contract_fee']);
@@ -2465,4 +2468,79 @@ class SalesOrderService extends Service
 
         return $return;
     }
+
+    public function getSalesProductForWarranty($sales_id = 0){
+        if(empty($sales_id)) return [];
+
+        //销售订单对应产品总数
+        $product = SalesOrderProductInfo::from('sales_order_product_info as a')
+            ->join('product as b','a.product_id','b.id')
+            ->where('a.del_time',0)
+            ->where('a.sales_order_id', $sales_id)
+            ->where('b.warranty_time', '>', 0)
+            ->select('a.number','a.product_id','b.code','b.product_category','b.title','b.warranty_time')
+            ->get()->toArray();
+        if(empty($product)) return [];
+        $product_id = array_column($product,'product_id');
+
+        //合同质保产品
+        $sn_product = ProductSnInfo::where("del_time",0)
+            ->where('data_id', $sales_id)
+            ->where('type',ProductSnInfo::type_two)
+            ->whereIn('product_id',$product_id)
+            ->select('product_id')
+            ->get()->toArray();
+        $product_map1 = [];
+        foreach ($sn_product as $value){
+            $key = $value['product_id'];
+            if(isset($product_map1[$key])){
+                $number = bcadd(1, $product_map1[$key],2);
+                $product_map1[$key] = $number;
+            }else{
+                $product_map1[$key] = 1;
+            }
+        }
+
+        //合同退货产品
+        $product_map2 = [];
+        $return_id = ReturnExchangeOrder::where('del_time',0)
+            ->where('type', ReturnExchangeOrder::Order_type)
+            ->where('model_type', ReturnExchangeOrder::Model_type_one)
+            ->where('data_id', $sales_id)
+            ->select('id')
+            ->get()->toArray();
+        $save2 = ReturnExchangeOrderProductInfo::where('del_time',0)
+            ->whereIn('return_exchange_id', array_column($return_id,'id'))
+            ->where('return_or_exchange',ReturnExchangeOrderProductInfo::type_one)
+            ->select('number', 'return_exchange_id','product_id')
+            ->get()->toArray();
+        foreach ($save2 as $value){
+            $key = $value['product_id'];
+            if(isset($product_map2[$key])){
+                $number = bcadd($value['number'], $product_map2[$key],2);
+                $product_map2[$key] = $number;
+            }else{
+                $product_map2[$key] = $value['number'];
+            }
+        }
+
+        $return = [];
+        foreach ($product as $key => $value){
+            $category = json_decode($value['product_category'],true);
+            //车窗膜不管数量算一个
+            if(in_array(ProductCategory::Special_for_sn, $category)) $value['number'] = 1;
+
+            $sn_tmp = $product_map1[$value['product_id']] ?? 0;
+            $return_tmp = $product_map2[$value['product_id']] ?? 0;
+
+            $number = bcsub($value['number'], $sn_tmp,2);
+            $number = bcsub($number, $return_tmp,2);
+            if($number <= 0) unset($product[$key]);
+
+            $return[$value['product_id']] = $value;
+            $return[$value['product_id']]['number'] = $number;
+        }
+
+        return $return;
+    }
 }

+ 71 - 0
app/Service/ScheduleService.php

@@ -9,6 +9,7 @@ use App\Model\Employee;
 use App\Model\Product;
 use App\Model\ProductActivity;
 use App\Model\ProductActivityPrice;
+use App\Model\ProductSnInfo;
 use App\Model\RoleMenuButton;
 use App\Model\SalesOrder;
 use App\Model\Schedule;
@@ -646,6 +647,8 @@ class ScheduleService extends Service
 
         //可见范围
         $employee = (new RangeService())->RangeConstructionEmpDetail($order_id);
+        //激活按钮
+        $warranty_button_map = $this->getWarrantyInfo($construction, $product);
         foreach ($construction as $value){
             $str = "";
             if(! empty($value['start_time']) && ! empty($value['end_time'])) $str = date('Y-m-d H:i',$value['start_time']) . '-' . date("Y-m-d H:i",$value['end_time']);
@@ -658,6 +661,9 @@ class ScheduleService extends Service
             }elseif($value['state'] == Construction::STATE_THREE){
                 //待确认 分配/调配
                 $button = $this->fillFpButton($special_button,$special_button_map, $emp_tmp, 1);
+            }elseif($value['state'] == Construction::STATE_FOUR){
+                $t = $warranty_button_map[$value['id']] ?? "";
+                $button = $this->fillWjButton($special_button,$special_button_map,$t);
             }
             $button = array_filter($button);
 
@@ -718,4 +724,69 @@ class ScheduleService extends Service
 
         return $button;
     }
+
+    public function fillWjButton($special_button,$special_button_map,$t){
+        $button = [];
+        $button_tmp = $special_button_map[RoleMenuButton::special_ten] ?? [];
+        $button_tmp['title'] = $t;
+        if(in_array(RoleMenuButton::special_ten,$special_button)){
+            $button_tmp['is_button'] = 1;
+        }else{
+            $button_tmp['is_button'] = 0;
+        }
+        $button[] = $button_tmp;
+
+        return $button;
+    }
+
+    public function getWarrantyInfo($construction, $product){
+        if(empty($construction) || empty($product)) return [];
+
+        $construction_id = [];
+        foreach ($construction as $value){
+            if($value['state'] == Construction::STATE_FOUR) $construction_id[] = $value['id'];
+        }
+        if(empty($construction_id)) return [];
+
+        $sn_info = ProductSnInfo::where('del_time',0)
+            ->whereIn('data_id', $construction_id)
+            ->where('type', ProductSnInfo::type_one)
+            ->select('data_id', 'product_id')
+            ->get()->toArray();
+        $sn_map = [];
+        foreach ($sn_info as $value){
+            if(isset($sn_map[$value['data_id']])){
+                if(! in_array($value['product_id'], $sn_map[$value['data_id']])) $sn_map[$value['data_id']][] = $value['product_id'];
+            }else{
+                $sn_map[$value['data_id']][] = $value['product_id'];
+            }
+        }
+
+        $product_map = [];
+        foreach ($product as $value){
+            if(! in_array($value['construction_id'],$construction_id)) continue;
+            if(isset($product_map[$value['construction_id']])){
+                if(! in_array($value['product_id'], $product_map[$value['construction_id']])) $product_map[$value['construction_id']][] = $value['product_id'];
+            }else{
+                $product_map[$value['construction_id']][] = $value['product_id'];
+            }
+        }
+
+        $return = [];
+        foreach ($product_map as $construction_id => $value){
+            if(isset($sn_map[$construction_id])){
+                $count = count($sn_map[$construction_id]);
+                $count_v = count($value);
+                if($count_v > $count) {
+                    $return[$construction_id] = "已生成";
+                }else{
+                    $return[$construction_id] = "部分生成";
+                }
+            }else{
+                $return[$construction_id] = "生成质保";
+            }
+        }
+
+        return $return;
+    }
 }

+ 36 - 0
app/Service/Service.php

@@ -648,4 +648,40 @@ class Service
 
         return [true, json_decode($r, true)];
     }
+
+    function isValidMobile($mobile) {
+        // 匹配以1开头,第二位为3/4/5/7/8/9,总共11位的手机号
+        return preg_match('/^1[345789]\d{9}$/', $mobile);
+    }
+
+    function isValidVin($vin) {
+        $vin = strtoupper(trim($vin));
+
+        // 检查是否为17位
+        if (strlen($vin) !== 17) {
+            return false;
+        }
+
+        return true;
+        // 计算校验位
+        $weights = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
+        $sum = 0;
+        for ($i = 0; $i < 17; $i++) {
+            $char = $vin[$i];
+            if (is_numeric($char)) {
+                $value = intval($char);
+            } elseif (ctype_alpha($char)) {
+                $value = ord(strtoupper($char)) - 55; // 'A' starts at 10, so subtract 55 ('A' is ASCII 65)
+            } else {
+                return false;
+            }
+            $sum += $value * $weights[$i];
+        }
+
+        $remainder = $sum % 11;
+        $checkDigit = $remainder == 10 ? 'X' : strval($remainder);
+
+        // 比较计算出的校验位与第9位是否匹配
+        return $checkDigit === $vin[8];
+    }
 }

+ 772 - 2
app/Service/TSpaceService.php

@@ -2,7 +2,20 @@
 
 namespace App\Service;
 
+use App\Model\BasicType;
+use App\Model\Construction;
+use App\Model\ConstructionProductInfo;
+use App\Model\Customer;
+use App\Model\CustomerInfo;
+use App\Model\Product;
+use App\Model\ProductCategory;
+use App\Model\ProductSnInfo;
+use App\Model\ReturnExchangeOrder;
+use App\Model\ReturnExchangeOrderProductInfo;
+use App\Model\SalesOrder;
+use App\Model\SalesOrderProductInfo;
 use App\Model\TSpaceSet;
+use App\Model\Warranty;
 use Illuminate\Support\Facades\DB;
 
 class TSpaceService extends Service
@@ -27,12 +40,11 @@ class TSpaceService extends Service
             $insert = $update = $new = $old = $id = [];
             foreach ($data['data'] as $value){
                 $text = "";
-                if(! empty($value['text'])) $text = json_encode($data['text']);
+                if(! empty($value['text'])) $text = json_encode($value['text']);
                 if(! empty($value['id'])){
                     $file = $set_map[$value['id']] ?? "";
                     if($value['file'] != $file){
                         $old[] = $file;
-                    }else{
                         $new[] = $value['file'];
                     }
                     $update[] = [
@@ -100,10 +112,768 @@ class TSpaceService extends Service
             ->where('type', $data['type'])
             ->select('file', 'id', 'text')
             ->get()->toArray();
+        $fileUploadService = new FileUploadService();
         foreach ($set as $key => $value){
             if(! empty($value['text'])) $set[$key]['text'] = json_decode($value['text'], true);
+            $url = "";
+            if(! empty($value['file'])) $url = $fileUploadService->getFileShow($value['file']);
+            $set[$key]['file_url'] = $url;
         }
 
         return [true, $set];
     }
+
+    public function tSpacelist($data){
+        if(empty($data['type'])){
+            $type = [];
+        }else{
+            if(! is_array($data['type'])){
+                $type = [$data['type']];
+            }else{
+                $type = $data['type'];
+            }
+        }
+        $set = TSpaceSet::where('del_time',0)
+            ->when(! empty($type), function ($query) use ($type) {
+                return $query->whereIn('type',$type);
+            })
+            ->select('file', 'id', 'text', 'type')
+            ->get()->toArray();
+        $fileUploadService = new FileUploadService();
+        foreach ($set as $key => $value){
+            if(! empty($value['text'])) $set[$key]['text'] = json_decode($value['text'], true);
+            $url = "";
+            if(! empty($value['file'])) $url = $fileUploadService->getFileShow($value['file']);
+            $set[$key]['file_url'] = $url;
+        }
+
+        return [true, $set];
+    }
+
+    public function warrantyGetProduct($data, $user){
+        if(empty($data['sale_order_id'])) return [false, '合同ID不能为空'];
+        $return = $this->warrantyGetProductList($data, $user);
+
+        return [true, $return];
+    }
+
+    public function warrantyGetProductList($data, $user){
+        $return = [];
+        $data_id = $data['sale_order_id'];
+
+        //销售订单对应产品总数
+        $product = SalesOrderProductInfo::from('sales_order_product_info as a')
+            ->join('product as b','a.product_id','b.id')
+            ->where('a.del_time',0)
+            ->where('a.sales_order_id', $data_id)
+            ->where('b.warranty_time', '>', 0)
+            ->select('a.number','a.product_id','b.product_category')
+            ->get()->toArray();
+        if(empty($product)) return $return;
+        $product_id = array_column($product,'product_id');
+        $map = (new ProductService())->getProductDetail($product_id);
+
+        //合同质保产品
+        $sn_product = ProductSnInfo::where("del_time",0)
+            ->where('data_id', $data_id)
+            ->where('type',ProductSnInfo::type_two)
+            ->whereIn('product_id',$product_id)
+            ->select('product_id')
+            ->get()->toArray();
+        $product_map1 = [];
+        foreach ($sn_product as $value){
+            $key = $value['product_id'];
+
+            if(isset($product_map1[$key])){
+                $number = bcadd(1, $product_map1[$key],2);
+                $product_map1[$key] = $number;
+            }else{
+                $product_map1[$key] = 1;
+            }
+        }
+
+        //合同退货产品
+        $product_map2 = [];
+        $return_id = ReturnExchangeOrder::where('del_time',0)
+            ->where('type', ReturnExchangeOrder::Order_type)
+            ->where('model_type', ReturnExchangeOrder::Model_type_one)
+            ->where('data_id', $data_id)
+            ->select('id')
+            ->get()->toArray();
+        $save2 = ReturnExchangeOrderProductInfo::where('del_time',0)
+            ->whereIn('return_exchange_id', array_column($return_id,'id'))
+            ->where('return_or_exchange',ReturnExchangeOrderProductInfo::type_one)
+            ->select('number', 'return_exchange_id','product_id')
+            ->get()->toArray();
+        foreach ($save2 as $value){
+            $key = $value['product_id'];
+            if(isset($product_map2[$key])){
+                $number = bcadd($value['number'], $product_map2[$key],2);
+                $product_map2[$key] = $number;
+            }else{
+                $product_map2[$key] = $value['number'];
+            }
+        }
+
+        foreach ($product as $value){
+            $category = json_decode($value['product_category'],true);
+            //车窗膜不管数量算一个
+            if(in_array(ProductCategory::Special_for_sn, $category)) $value['number'] = 1;
+
+            //合同质保产品
+            $p1 = $product_map1[$value['product_id']] ?? 0;
+            //合同退货产品
+            $p2 = $product_map2[$value['product_id']] ?? 0;
+            $number = bcsub($value['number'], $p1,2);
+            $number = bcsub($number, $p2,2);
+            if($number <= 0) continue;
+            $tmp = $map[$value['product_id']] ?? [];
+
+            $return[] = [
+                'number' => $number, //可出数量
+                'product_id' => $value['product_id'],
+                'title' => $tmp['title'] ?? "",
+                'code' => $tmp['code'] ?? "",
+                'size' => $tmp['size'] ?? "",
+                'unit' => $tmp['unit'] ?? "",
+            ];
+        }
+
+        return $return;
+    }
+
+    public function warrantyAdd($data, $user){
+        list($status, $msg) = $this->warrantyAddRule($data,$user);
+        if(! $status) return [false, $msg];
+
+        list($warranty, $sn) = $msg;
+        try {
+            DB::beginTransaction();
+
+            Warranty::insert($warranty);
+
+            if(! empty($sn)){
+                $warranty_list = Warranty::where('del_time',0)
+                    ->whereIn("sn",$sn)
+                    ->select('id','sn')
+                    ->get()->toArray();
+                foreach ($warranty_list as $value){
+                    ProductSnInfo::where('del_time',0)
+                        ->where('sn', $value['sn'])
+                        ->update(['warranty_id' => $value['id']]);
+                }
+            }
+
+//            if($data['type'] == ProductSnInfo::type_two){
+//                //同一个合同,多次填写的客户基本信息按最后一次更新为主
+//                Warranty::where('del_time',0)
+//                    ->where('data_id',$data['data_id'])
+//                    ->where('type', $data['type'])
+//                    ->update(['customer_name' => $data['customer_name'], 'customer_contact' => $data['customer_contact']]);
+//            }
+
+            DB::commit();
+        }catch (\Throwable $exception){
+            DB::rollBack();
+            return [false, $exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    private function warrantyAddRule($data, $user){
+        if(empty($data['type'])) return [false, 'type不能为空'];
+        if(! isset(ProductSnInfo::$type_name[$data['type']])) return [false,'type不存在'];
+        if(empty($data['data_id'])) return [false, 'data_id不能为空'];
+
+        $time = time();
+        $warranty = $sn_update = [];
+        if($data['type'] == ProductSnInfo::type_one){
+            $order = Construction::where('del_time',0)->where('id',$data['data_id'])->first();
+            if(empty($order)) return [false, '施工单不存在或已被删除'];
+            $order = $order->toArray();
+            if($order['state'] != Construction::STATE_FOUR) return [false, '施工单暂未完结,生成质保信息失败'];
+            if(empty($order['vin_no'])) return [false, '车架号不能为空'];
+            $bool = $this->isValidVin($order['vin_no']);
+            if(! $bool) return [false, '车架号错误,请查看原施工单车架号,编辑输入完整车架号'];
+            if(empty($order['customer_id'])) return [false, '客户信息不存在'];
+            $customer = Customer::where('del_time', 0)->where('id',$order['customer_id'])->first();
+            if(empty($customer)) return [false, '客户不存在或已被删除'];
+            $customer = $customer->toArray();
+            $info = CustomerInfo::where('del_time',0)
+                ->where('type',CustomerInfo::type_one)
+                ->where('customer_id', $customer['id'])
+                ->where('contact_info', "<>", "")
+                ->select('contact_info')
+                ->first();
+            if(empty($info)) return [false, "客户的联系方式不能为空"];
+            $info = $info->toArray();
+            $customer_info = $info['contact_info'];
+
+            $product_sn = ProductSnInfo::from('product_sn_info as a')
+                ->leftJoin('product as b','b.id','a.product_id')
+                ->select('a.*','b.title','b.warranty_time')
+                ->where('a.del_time',0)
+                ->where('a.data_id',$data['data_id'])
+                ->where('a.type', ProductSnInfo::type_one)
+                ->where('a.warranty_id', 0)
+                ->get()->toArray();
+            if(empty($product_sn)) return [false, '施工单暂无未生成质保信息的sn码'];
+
+            $construction_site = BasicType::where('id',$order['install_position'])->value('title') ?? "";
+            //质保单数据 需要更新的sn码信息
+            foreach ($product_sn as $value){
+                $warranty[] = [
+                    'data_id' => $order['id'],
+                    'data_title' => $order['order_number'],
+                    'type' => ProductSnInfo::type_one,
+                    'product_id' => $value['product_id'],
+                    'code' => $value['code'],
+                    'title' => $value['title'],
+                    'sn' => $value['sn'],
+                    'customer_id' => $order['customer_id'],
+                    'customer_name' => $customer['title'],
+                    'customer_contact' => $customer_info,
+                    'vin_no' => $order['vin_no'],
+                    'warranty_time' => $value['warranty_time'],
+                    'construction_site_title' => $construction_site,
+                    'start_time' => $order['end_time'],
+                    'crt_time' => $time,
+                    'crt_id' => $user['id'],
+                ];
+                $sn_update[] = $value['sn'];
+            }
+        }elseif($data['type'] == ProductSnInfo::type_two){
+            $order = SalesOrder::where('del_time',0)->where('id',$data['data_id'])->first();
+            if(empty($order)) return [false, '合同不存在或已被删除'];
+            $order = $order->toArray();
+            if(empty($order['customer_id'])) return [false, '客户不能为空'];
+            $customer_name = Customer::where('id', $order['customer_id'])->value('title');
+            if(empty($order['customer_contact'])) return [false, '客户联系方式不能为空'];
+            $product = (new SalesOrderService())->getSalesProductForWarranty($data['data_id']);
+            if(empty($product)) return [false, '合同已全部或暂无可生成质保信息的产品'];
+            foreach ($product as $value){
+                for($i = 0 ;$i < $value['number']; $i++){
+                    $warranty[] = [
+                        'data_id' => $order['id'],
+                        'data_title' => $order['order_number'],
+                        'type' => ProductSnInfo::type_two,
+                        'product_id' => $value['product_id'],
+                        'code' => $value['code'],
+                        'title' => $value['title'],
+                        'sn' => "",
+                        'customer_id' => $order['customer_id'],
+                        'customer_name' => $customer_name,
+                        'customer_contact' => $order['customer_contact'],
+                        'vin_no' => "",
+                        'warranty_time' => $value['warranty_time'],
+                        'construction_site_title' => "",
+                        'start_time' => $time,
+                        'crt_time' => $time,
+                        'crt_id' => $user['id'],
+                    ];
+                }
+            }
+        }else{
+            return [false, '质保生成类型错误'];
+        }
+
+        return [true, [$warranty, $sn_update]];
+    }
+
+    public function ori()
+    {//生成质保 合同原来的代码
+        $order = SalesOrder::where('del_time', 0)->where('id', $data['data_id'])->first();
+        if (empty($order)) return [false, '合同不存在或已被删除'];
+        $order = $order->toArray();
+        if (empty($data['customer_name'])) return [false, '客户名称不能为空'];
+        if (empty($data['customer_contact'])) return [false, '客户联系方式不能为空'];
+        $bool = $this->isValidMobile($data['customer_contact']);
+        if (!$bool) return [false, '手机号错误,请输入完整的手机号'];
+        $vin_no = "";
+        if (!empty($data['vin_no'])) {
+            $bool = $this->isValidVin($data['vin_no']);
+            if (!$bool) return [false, '车架号错误,请填写完整车架号'];
+            $vin_no = $data['vin_no'];
+        }
+
+        if (empty($data['product'])) return [false, '合同无生成质保的产品信息'];
+        $product = (new SalesOrderService())->getSalesProductForWarranty($data['data_id']);
+        if (empty($product)) return [false, '合同暂无能生成质保信息的产品'];
+        foreach ($data['product'] as $value) {
+            $tmp = $product[$value['product_id']] ?? [];
+            if (empty($tmp)) return [false, '存在不能生成质保的产品'];
+            if ($tmp['number'] > $value['number']) return [false, '产品编码:' . $tmp['code'] . '本次可生成质保信息的产品最多' . $tmp['number']];
+
+            $warranty[] = [
+                'data_id' => $order['id'],
+                'data_title' => $order['order_number'],
+                'type' => ProductSnInfo::type_two,
+                'product_id' => $tmp['product_id'],
+                'code' => $tmp['code'],
+                'title' => $tmp['title'],
+                'sn' => "",
+                'customer_id' => $order['customer_id'],
+                'customer_name' => $data['customer_name'],
+                'customer_contact' => $data['customer_contact'],
+                'vin_no' => $vin_no,
+                'warranty_time' => $tmp['warranty_time'],
+                'construction_site_title' => "",
+                'start_time' => $time,
+                'crt_time' => $time,
+                'crt_id' => $user['id'],
+            ];
+        }
+    }
+
+    public function saveWarrantyByMyself($data){
+        list($status, $msg) = $this->saveWarrantyByMyselfRule($data);
+        if(! $status) return [false, $msg];
+
+        list($warranty, $sn) = $msg;
+        try {
+            DB::beginTransaction();
+
+            $warranty_id = DB::table('warranty')->insertGetId($warranty);
+            $sn['warranty_id'] = $warranty_id;
+            ProductSnInfo::insert($sn);
+
+            (new DataSyncToU8Service())->updateByVinNo($data);
+
+            DB::commit();
+        }catch (\Throwable $exception){
+            DB::rollBack();
+            return [false, $exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    private function saveWarrantyByMyselfRule($data){
+        if(empty($data['product_id'])) return [false, '产品ID不能为空'];
+        $product = Product::where('del_time',0)
+            ->where('id',$data['product_id'])
+            ->first();
+        if(empty($product)) return [false, '产品不存在或已被删除'];
+        $product = $product->toArray();
+        if(empty($data['start_time'])) return [false, '施工日期不能为空'];
+        if(empty($product['warranty_time'])) return [false, '质保时长不能为空'];
+        if(empty($data['sn'])) return [false, '产品序列号不能为空'];
+        list($status, $msg) = (new DataSyncToU8Service())->snForWarranty($data);
+        if(! $status) return [false, $msg];
+        //校验sn是否被占用
+        $submit_info[] = $product['code'] . $data['sn'];
+        list($status, $msg) = (new DataSyncToU8Service())->snForCheck([$product['code']], [$data['sn']], $submit_info);
+        if(! $status) return [false, "产品序列号:" . $data['sn'] . "已存在于门店系统"];
+
+        if(empty($data['customer_name'])) return [false, '客户名称不能为空'];
+        if(empty($data['customer_contact'])) return [false, '客户联系方式不能为空'];
+        $bool = $this->isValidMobile($data['customer_contact']);
+        if(! $bool) return [false, '手机号错误,请填写完整的11位手机号'];
+        if(empty($data['vin_no'])) return [false, '车架号不能为空'];
+        $bool = $this->isValidVin($data['vin_no']);
+        if(! $bool) return [false, '车架号错误,请填写完整的17位车架号'];
+
+        $time = time();
+        //质保单数据 sn码数据
+        $warranty = [
+            'data_id' => 0,
+            'data_title' => '',
+            'type' => ProductSnInfo::type_three,
+            'product_id' => $product['id'],
+            'code' => $product['code'],
+            'title' => $product['title'],
+            'sn' => $data['sn'],
+            'customer_id' => 0,
+            'customer_name' => $data['customer_name'],
+            'customer_contact' => $data['customer_contact'],
+            'vin_no' => $data['vin_no'],
+            'warranty_time' => $product['warranty_time'],
+            'construction_site_title' => $data['construction_site_title'] ?? "",
+            'start_time' => $data['start_time'],
+            'crt_time' => $time,
+            'crt_id' => 0,
+            'is_active' => Warranty::type_one,
+        ];
+        $sn_update = [
+            'data_id' => 0,
+            'type' => ProductSnInfo::type_three,
+            'product_id' => $product['id'],
+            'code' => $product['code'],
+            'sn' => $data['sn'],
+            'crt_time' => $time,
+            'warranty_id' => 0,
+        ];
+
+        return [true, [$warranty, $sn_update]];
+    }
+
+    //获取未激活列表
+    public function getWarrantyNotActiveList($data){
+        if(empty($data['customer_contact'])) return [false, '手机号不能为空'];
+
+        $model = Warranty::where('del_time',0)
+            ->where('customer_contact',$data['customer_contact'])
+            ->where('is_active',Warranty::type_zero)
+            ->whereIn('type',[ProductSnInfo::type_one, ProductSnInfo::type_two])
+            ->select('id','data_id','data_title','type','product_id','title','sn','customer_name','customer_contact','vin_no','warranty_time','construction_site_title','start_time');
+
+        $list = $this->limit($model,'', $data);
+        $list = $this->fillGetWarrantyNotActiveList($list);
+
+        return [true, $list];
+    }
+
+    public function fillGetWarrantyNotActiveList($data){
+        if(empty($data['data'])) return $data;
+
+        foreach ($data['data'] as $key => $value){
+            $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
+        }
+
+        return $data;
+    }
+
+    //质保激活
+    public function warrantyActivationCustomer($data){
+        list($status, $msg) = $this->warrantyActivationCustomerRule($data);
+        if(! $status) return [false, $msg];
+
+        $order = $msg;
+        try {
+            DB::beginTransaction();
+            if($order['type'] == ProductSnInfo::type_two){
+                $update = [
+                    'sn' => $data['sn'] ?? '',
+                    'construction_site_title' => $data['construction_site_title'] ?? '',
+                    'vin_no' => $data['vin_no'],
+                    'is_active' => Warranty::type_one
+                ];
+                Warranty::where('id',$data['id'])->update($update);
+
+                if(! empty($data['sn'])){
+                    $order = Warranty::where('id',$data['id'])->first()->toArray();
+
+                    $sn_update = [
+                        'data_id' => $order['data_id'],
+                        'type' => $order['type'],
+                        'product_id' => $order['product_id'],
+                        'code' => $order['code'],
+                        'sn' => $order['sn'],
+                        'crt_time' => time(),
+                        'warranty_id' => $order['id'],
+                    ];
+                    ProductSnInfo::insert($sn_update);
+                }
+            }
+
+            (new DataSyncToU8Service())->updateByVinNo($data);
+
+            DB::commit();
+        }catch (\Throwable $exception){
+            DB::rollBack();
+            return [false, $exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    public function warrantyActivationCustomerRule($data){
+        if(empty($data['id'])) return [false, '质保ID不能为空'];
+        $order = Warranty::where('del_time',0)
+            ->where('id', $data['id'])
+            ->first();
+        if(empty($order)) return [false, '质保卡不存在或已被删除'];
+        $order = $order->toArray();
+        if($order['is_active'] > Warranty::type_zero) return [false, '质保卡已激活,请勿重复操作'];
+
+        if(empty($data['customer_name'])) return [false, '车主姓名不能为空'];
+        if(empty($data['customer_contact'])) return [false, '联系方式不能为空'];
+        if(empty($data['vin_no'])) return [false, '车架号不能为空'];
+        if($order['type'] == ProductSnInfo::type_one){
+        }else{
+            if(! empty($data['sn'])){
+                list($status, $msg) = (new DataSyncToU8Service())->snForWarranty($data);
+                if(! $status) return [false, $msg];
+                $submit_info[] = $order['code'] . $data['sn'];
+                list($status, $msg) = (new DataSyncToU8Service())->snForCheck([$order['code']], [$data['sn']], $submit_info);
+                if(! $status) return [false, "产品序列号:" . $data['sn'] . "已存在于门店系统"];
+            }
+
+            $bool = $this->isValidVin($data['vin_no']);
+            if(! $bool) return [false, '车架号错误,请填写完整车架号'];
+        }
+
+        return [true, $order];
+    }
+
+    //后台列表
+    public function warrantyList($data,$user){
+        $model = Warranty::where('del_time',0)
+            ->select('id','data_id','data_title','code','type','product_id','title','sn','customer_name','customer_contact','vin_no','warranty_time','construction_site_title','start_time','crt_id','is_active','active_id')
+            ->orderBy('id','desc');
+
+        if(! empty($data['type'])) $model->where('type', $data['type']);
+        if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
+        if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
+        if(! empty($data['data_title'])) $model->where('data_title', 'LIKE', '%'.$data['data_title'].'%');
+        if(! empty($data['sn'])) $model->where('sn', 'LIKE', '%'.$data['sn'].'%');
+        if(! empty($data['customer_name'])) $model->where('customer_name', 'LIKE', '%'.$data['customer_name'].'%');
+        if(! empty($data['customer_contact'])) $model->where('customer_contact', 'LIKE', '%'.$data['customer_contact'].'%');
+        if(! empty($data['vin_no'])) $model->where('vin_no', 'LIKE', '%'.$data['vin_no'].'%');
+        if(! empty($data['construction_site_title'])) $model->where('construction_site_title', 'LIKE', '%'.$data['construction_site_title'].'%');
+        if(! empty($data['warranty_time'])) $model->where('warranty_time', $data['warranty_time']);
+        if(isset($data['is_active'])) $model->where('is_active', $data['is_active']);
+        if(! empty($data['crt_id'])) $model->where('crt_id', $data['crt_id']);
+        if(! empty($data['id'])) $model->where('id', $data['id']);
+
+        $list = $this->limit($model,'', $data);
+        $list = $this->fillWarrantyList($list);
+
+        return [true, $list];
+    }
+
+    public function fillWarrantyList($data){
+        if(empty($data['data'])) return $data;
+
+        foreach ($data['data'] as $key => $value){
+            $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
+            $data['data'][$key]['type_title'] = ProductSnInfo::$type_name[$value['type']] ?? "";
+        }
+
+        return $data;
+    }
+
+    //后台质保编辑以及激活
+    public function warrantyEditAndActivation($data,$user){
+        list($status, $msg) = $this->warrantyEditAndActivationRule($data);
+        if(! $status) return [false, $msg];
+
+        $order = $msg;
+        try {
+            DB::beginTransaction();
+
+            $time = time();
+            $sn = $data['sn'] ?? "";
+            $order_sn = $order['sn'];
+            if(! empty($order_sn) && ! empty($sn) && $order_sn != $sn){
+                ProductSnInfo::where('del_time',0)
+                    ->where('data_id', $order['data_id'])
+                    ->where('type', $order['type'])
+                    ->where('sn', $order_sn)
+                    ->update(['del_time' => $time]);
+                $sn_update = [
+                    'data_id' => $order['data_id'],
+                    'type' => $order['type'],
+                    'product_id' => $order['product_id'],
+                    'code' => $order['code'],
+                    'sn' => $order['sn'],
+                    'crt_time' => time(),
+                    'warranty_id' => $order['id'],
+                ];
+                ProductSnInfo::insert($sn_update);
+            }
+            $update = [
+                'sn' => $sn,
+                'construction_site_title' => $data['construction_site_title'] ?? '',
+                'vin_no' => $data['vin_no'],
+                'start_time' => $data['start_time'],
+                'customer_name' => $data['customer_name'],
+                'customer_contact' => $data['customer_contact'],
+                'warranty_time' => $data['warranty_time'],
+            ];
+            if(empty($data['is_active'])) {
+                $update['is_active'] = Warranty::type_one;
+                $update['active_id'] = $user['id'];
+            }
+            Warranty::where('id',$data['id'])->update($update);
+
+            (new DataSyncToU8Service())->updateByVinNo($data);
+
+            DB::commit();
+        }catch (\Throwable $exception){
+            DB::rollBack();
+            return [false, $exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    public function warrantyEditAndActivationRule(&$data){
+        if(empty($data['id'])) return [false, '质保ID不能为空'];
+        $order = Warranty::where('del_time',0)
+            ->where('id', $data['id'])
+            ->first();
+        if(empty($order)) return [false, '质保卡不存在或已被删除'];
+        $order = $order->toArray();
+//        if(! empty($data['is_active']) && $order['is_active'] > Warranty::type_zero) return [false, '质保卡已激活,请勿重复操作'];
+
+        if(empty($data['start_time'])) return [false, '请填写施工日期/生效日期'];
+        $data['start_time'] = $this->changeDateToDateMin($data['start_time']);
+        if(empty($data['customer_name'])) return [false, '车主姓名不能为空'];
+        if(empty($data['customer_contact'])) return [false, '联系方式不能为空'];
+        if(empty($data['warranty_time'])) return [false, '质保时长(月)不能为空'];
+        if(empty($data['vin_no'])) return [false, '车架号不能为空'];
+        $bool = $this->isValidVin($data['vin_no']);
+        if(! $bool) return [false, '车架号错误,请填写完整车架号'];
+        if(! empty($data['sn'])){
+            list($status, $msg) = (new DataSyncToU8Service())->snForWarranty($data);
+            if(! $status) return [false, $msg];
+            $submit_info[] = $order['code'] . $data['sn'];
+            $message = [
+                'id' => $order['data_id'],
+                'data_type' => $order['type']
+            ];
+            list($status, $msg) = (new DataSyncToU8Service())->snForCheck([$order['code']], [$data['sn']], $submit_info, $message);
+            if(! $status) return [false, "产品序列号:" . $data['sn'] . "已存在于门店系统"];
+        }
+
+        return [true, $order];
+    }
+
+    //后台质保激活
+    public function warrantyActivation($data,$user){
+        list($status, $msg) = $this->warrantyActivationRule($data);
+        if(! $status) return [false, $msg];
+
+        $order = $msg;
+        try {
+            DB::beginTransaction();
+
+            $update['is_active'] = Warranty::type_one;
+            $update['active_id'] = $user['id'];
+            Warranty::where('id', $data['id'])->update($update);
+
+            (new DataSyncToU8Service())->updateByVinNo($order);
+
+            DB::commit();
+        }catch (\Throwable $exception){
+            DB::rollBack();
+            return [false, $exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    public function warrantyActivationRule($data){
+        if(empty($data['id'])) return [false, '质保ID不能为空'];
+        $order = Warranty::where('del_time',0)
+            ->where('id', $data['id'])
+            ->first();
+        if(empty($order)) return [false, '质保卡不存在或已被删除'];
+        $order = $order->toArray();
+        if(! empty($data['is_active']) && $order['is_active'] > Warranty::type_zero) return [false, '质保卡已激活,请勿重复操作'];
+
+        if(empty($order['start_time'])) return [false, '施工日期/生效日期不能为空'];
+        if(empty($order['customer_name'])) return [false, '车主姓名不能为空'];
+        if(empty($order['customer_contact'])) return [false, '联系方式不能为空'];
+        if(empty($order['warranty_time'])) return [false, '质保时长(月)不能为空'];
+        if(empty($order['vin_no'])) return [false, '车架号不能为空'];
+        $bool = $this->isValidVin($order['vin_no']);
+        if(! $bool) return [false, '车架号错误,请填写完整车架号'];
+
+        return [true, $order];
+    }
+
+    //质保卡作废
+    public function warrantyDel($data,$user){
+        list($status, $msg) = $this->warrantyDelRule($data);
+        if(! $status) return [false, $msg];
+
+        $order = $msg;
+        $time = time();
+        try {
+            DB::beginTransaction();
+
+            Warranty::where('id', $data['id'])->update(['del_time' => $time]);
+
+            if(! empty($order['sn'])) ProductSnInfo::where('del_time',0)->where('sn', $order['sn'])->update(['del_time' => $time]);
+
+            DB::commit();
+        }catch (\Throwable $exception){
+            DB::rollBack();
+            return [false, $exception->getMessage()];
+        }
+
+        return [true, ''];
+    }
+
+    public function warrantyDelRule($data){
+        if(empty($data['id'])) return [false, '质保ID不能为空'];
+        $order = Warranty::where('del_time',0)
+            ->where('id', $data['id'])
+            ->first();
+        if(empty($order)) return [false, '质保卡不存在或已被删除'];
+        $order = $order->toArray();
+
+        return [true, $order];
+    }
+
+    public function searchWarranty($data){
+        list($status, $msg) = $this->searchWarrantyRule($data);
+        if(! $status) return [false, $msg];
+        list($search_field, $search) = $msg;
+
+        $order_list = Warranty::where('del_time',0)
+            ->when($search_field == 1, function ($query) use ($search) {
+                return $query->where("customer_contact", $search);
+            })
+            ->when($search_field == 2, function ($query) use ($search) {
+                return $query->where("vin_no", $search);
+            })
+            ->orderBy('id','desc')
+            ->get()->toArray();
+        if(empty($order_list)) return [true , []];
+        $first = $order_list[0];
+        $order['main'] = [
+            'customer_name' => $first['customer_name'],
+            'customer_contact' => $first['customer_contact'],
+            'vin_no' => $first['vin_no'],
+        ];
+        foreach ($order_list as $key => $value){
+            $order_list[$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
+        }
+        $order['list'] = $order_list;
+
+        return [true, $order];
+    }
+
+    public function searchWarrantyRule($data){
+        if(empty($data['from'])) return [false, '查询来源不能为空'];
+        $search = $data['customer_contact_or_vin_no'];
+        if($data['from'] == 1){
+            if(empty($data['customer_contact_or_vin_no'])) return [false, '手机号不能为空'];
+            $length = strlen($data['customer_contact_or_vin_no']);
+            if($length != 11) return [false, '请输入完整的11位手机号'];
+            list($status,$msg) = $this->searchWarrantyCommon($data['customer_contact_or_vin_no']);
+            if(! $status) return [false, $msg];
+            $search_field = 1;
+        }elseif($data['from'] == 2){
+            if(empty($data['customer_contact_or_vin_no'])) return [false, '手机号或车架号不能为空'];
+            $length = strlen($data['customer_contact_or_vin_no']);
+            if($length != 11 && $length != 17) return [false, '请输入完整的11位手机号或完整的17位车架号'];
+            if($length == 11){
+                list($status,$msg) = $this->searchWarrantyCommon($data['customer_contact_or_vin_no']);
+                if(! $status) return [false, $msg];
+                $search_field = 1;
+            }else{
+                $search_field = 2;
+            }
+        }else{
+            return [false, '查询来源错误'];
+        }
+
+        return [true, [$search_field, $search]];
+    }
+
+    public function searchWarrantyCommon($customer_contact){
+        $vinCount = Warranty::where('del_time', 0)
+            ->where('customer_contact', $customer_contact)
+            ->whereNotNull('vin_no')
+            ->distinct()
+            ->count('vin_no');
+        if($vinCount > 1) return [false, '手机号:' . $customer_contact . '下有个多个车架号,请去质保查询功能按需查询质保信息'];
+
+        return [true, ''];
+    }
 }

+ 49 - 0
config/header/59.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * '菜单ID' => [
+ *     '字段英文名' =》 '字段中文名'
+ * ]
+ */
+
+return [
+    [
+        'key' => 'title',
+        'value' => '产品名称',
+    ],
+    [
+        'key' => 'code',
+        'value' => '产品编码',
+    ],
+    [
+        'key' => 'data_title',
+        'value' => '来源单据编号',
+    ],
+    [
+        'key' => 'sn',
+        'value' => '产品唯一序列号',
+    ],
+    [
+        'key' => 'customer_name',
+        'value' => '车主姓名',
+    ],
+    [
+        'key' => 'customer_contact',
+        'value' => '联系方式',
+    ],
+    [
+        'key' => 'vin_no',
+        'value' => '车架号',
+    ],
+    [
+        'key' => 'construction_site_title',
+        'value' => '施工地点',
+    ],
+    [
+        'key' => 'start_time',
+        'value' => '施工日期/生效日期',
+    ],
+    [
+        'key' => 'warranty_time',
+        'value' => '质保时长(月)',
+    ],
+];

+ 7 - 0
config/specialButton.php

@@ -72,5 +72,12 @@ return [
         "func" => "special_show_customer_from",
         "menu_id" => 16,
     ],
+    [
+        "id" => \App\Model\RoleMenuButton::special_ten,
+        "title" => "生成质保",
+        "sort" => -10,
+        "func" => "special_warranty_activation",
+        "menu_id" => 34,
+    ],
 ];
 

+ 13 - 1
routes/api.php

@@ -26,6 +26,13 @@ Route::any('uploadFiles/{file_name}', 'Api\FileUploadController@getFile');
 Route::any('getExport/{file_name}','Api\SysMenuController@getExport');
 Route::any('show','Api\ConstructionController@show');
 
+Route::any('tSpaceList','Api\TSpaceController@tSpaceList');//获取自定义页面设置
+Route::any('hasWarrantyInfo','Api\DataSyncToU8Controller@hasWarrantyInfo');//判断页面呈现 我的质保卡点击以后
+Route::any('getSnForWarranty','Api\DataSyncToU8Controller@getSnForWarranty');//输入sn码 获取产品
+Route::any('saveWarrantyByMyself','Api\TSpaceController@saveWarrantyByMyself');//客户自己创建质保并激活
+Route::any('getWarrantyNotActiveList','Api\TSpaceController@getWarrantyNotActiveList');//待激活列表
+Route::any('warrantyActivationCustomer','Api\TSpaceController@warrantyActivationCustomer');//客户主动激活
+Route::any('searchWarranty','Api\TSpaceController@searchWarranty');//质保查询
 Route::group(['middleware'=> ['checkLogin']],function ($route){
     //oa
     $route->any('oaGetData', 'Api\OaController@oaGetData');
@@ -377,7 +384,12 @@ Route::group(['middleware'=> ['checkLogin']],function ($route){
     $route->any('tSpaceDetail', 'Api\TSpaceController@detail');
 
     //生成质保信息
-    $route->any('warrantyAdd', 'Api\TSpaceController@warrantyAdd');
+    $route->any('warrantyGetProduct', 'Api\TSpaceController@warrantyGetProduct'); //合同获取能生成质保的产品
+    $route->any('warrantyAdd', 'Api\TSpaceController@warrantyAdd'); //生成质保
+    $route->any('warrantyList', 'Api\TSpaceController@warrantyList'); //质保列表
+    $route->any('warrantyEditAndActivation', 'Api\TSpaceController@warrantyEditAndActivation'); //后台人工编辑或激活质保
+    $route->any('warrantyActivation', 'Api\TSpaceController@warrantyActivation'); //后台人工激活质保
+    $route->any('warrantyDel', 'Api\TSpaceController@warrantyDel'); //质保卡作废
 
     //获取下载模板
     $route->any('getTableTitleXls','Api\ImportController@getTableTitleXls');

+ 8 - 0
routes/wx.php

@@ -139,4 +139,12 @@ Route::group(['middleware'=> ['checkWx']],function ($route){
 
     $route->any('productGroupByList', 'Api\ProductController@productGroupByList');//选择列表页
     $route->any('productGroupByListDetail', 'Api\ProductController@productGroupByListDetail');//选择列表页详情
+
+    //u8获取sn码
+    $route->any('snListAccording','Api\DataSyncToU8Controller@snListAccording');
+    $route->any('getSnFromU8','Api\DataSyncToU8Controller@getSnFromU8');
+    //补录
+    $route->any('constructionEditSn', 'Api\ConstructionController@constructionEditSn');
+    //生成质保
+    $route->any('warrantyAdd', 'Api\TSpaceController@warrantyAdd'); //生成质保
 });