488 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			488 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php | |||
|  | 
 | |||
|  | namespace app\controller\manager\mall; | |||
|  | 
 | |||
|  | use app\controller\manager\Base; | |||
|  | use app\exception\RepositoryException; | |||
|  | use app\model\Config; | |||
|  | use app\model\Log; | |||
|  | use app\model\mall\SpuCategoryPivot; | |||
|  | use app\model\Sku; | |||
|  | use app\model\Spu as SpuModel; | |||
|  | use app\repository\SpuRepository; | |||
|  | use app\service\Math; | |||
|  | use Exception; | |||
|  | use think\db\exception\DataNotFoundException; | |||
|  | use think\db\exception\DbException; | |||
|  | use think\db\exception\ModelNotFoundException; | |||
|  | use think\exception\ValidateException; | |||
|  | use think\facade\Db; | |||
|  | use think\response\Json; | |||
|  | use think\response\View; | |||
|  | 
 | |||
|  | class Spu extends Base | |||
|  | { | |||
|  |     protected $noNeedRight = ['getSpuList', 'getSkuList', 'checkActivity', 'getSpu']; | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws ModelNotFoundException | |||
|  |      * @throws DbException | |||
|  |      * @throws DataNotFoundException | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function index() | |||
|  |     { | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $params = input(); | |||
|  | 
 | |||
|  |             $res = SpuRepository::getInstance()->list($params); | |||
|  | 
 | |||
|  |             $res['list'] = $res['list']->each(function ($item) { | |||
|  |                 $text = $item->saleable ? '已上架' : '已下架'; | |||
|  |                 if ($item->is_activity > 0) { | |||
|  |                     $activityText = SpuModel::activityTextList()[$item->activity_type]; | |||
|  |                     $text         = '<span style="color: red;">'.$text.' '.$activityText.'中</span>'; | |||
|  |                 } | |||
|  | 
 | |||
|  |                 $item->saleable_text = $text; | |||
|  |             }); | |||
|  | 
 | |||
|  |             return $this->json(0, 'success', $res); | |||
|  |         } | |||
|  | 
 | |||
|  |         $this->data['mpPath'] = Config::MINI_PATH_SPU_INFO;; | |||
|  |         $this->data['statusList']  = SpuModel::statusTextList(); | |||
|  |         $this->data['spuTypeList'] = SpuModel::spuTypeTextList(); | |||
|  | 
 | |||
|  |         return $this->view(); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws ModelNotFoundException | |||
|  |      * @throws DbException | |||
|  |      * @throws DataNotFoundException | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function score() | |||
|  |     { | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $params         = input(); | |||
|  |             $params['type'] = SpuModel::TYPE_SCORE; | |||
|  | 
 | |||
|  |             $res = SpuRepository::getInstance()->list($params); | |||
|  | 
 | |||
|  |             $res['list'] = $res['list']->each(function ($item) { | |||
|  |                 $text                = $item->saleable ? '已上架' : '已下架'; | |||
|  |                 $item->saleable_text = $text; | |||
|  |             }); | |||
|  |             return $this->json(0, 'success', $res); | |||
|  |         } | |||
|  | 
 | |||
|  |         $this->data['mpPath'] = Config::MINI_PATH_SPU_INFO;; | |||
|  | 
 | |||
|  |         $this->data['statusList']  = SpuModel::statusTextList(); | |||
|  |         $this->data['spuTypeList'] = SpuModel::spuTypeTextList(); | |||
|  |         $this->data['url']         = '/manager/mall/spu/score'; | |||
|  |         $this->data['type']        = SpuModel::TYPE_SCORE; | |||
|  | 
 | |||
|  |         return $this->view('manager/mall/spu/index'); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 添加 | |||
|  |      * | |||
|  |      * @return Json|View | |||
|  |      * @throws DataNotFoundException | |||
|  |      * @throws DbException | |||
|  |      * @throws ModelNotFoundException | |||
|  |      */ | |||
|  |     public function add() | |||
|  |     { | |||
|  |         $repo = SpuRepository::getInstance(); | |||
|  |         $type = input('type', SpuModel::TYPE_NORMAL); | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $item = $this->request->param('item/a', []); | |||
|  | 
 | |||
|  |             $item['is_score']      = $type == SpuModel::TYPE_SCORE; | |||
|  |             $item['is_activity']   = in_array($type, SpuModel::activityList()); | |||
|  |             $item['activity_type'] = $type; | |||
|  | 
 | |||
|  |             $multiSpec           = input('post.is_attribute');// 是否多规格 0否 1是
 | |||
|  |             $skus                = input('post.skus');//规格数据
 | |||
|  |             $item['spu_type_id'] = input('post.product_type');//商品类型ID
 | |||
|  |             $item['multi_spec']  = $multiSpec; | |||
|  | 
 | |||
|  |             if ($multiSpec == SpuModel::COMMON_OFF) { | |||
|  |                 $skus = [$skus]; | |||
|  |             } | |||
|  |             try { | |||
|  |                 $this->checkData($item, $skus); | |||
|  | 
 | |||
|  |                 $repo->addSpu($item, $skus); | |||
|  |             } catch (RepositoryException $e) { | |||
|  |                 return $this->json(4002, $e->getMessage()); | |||
|  |             } catch (Exception $e) { | |||
|  |             } | |||
|  | 
 | |||
|  |             return $this->json(); | |||
|  |         } | |||
|  | 
 | |||
|  |         $categoryList = $repo->categoryXmSelect([], [], true); | |||
|  | 
 | |||
|  |         $this->data['statusList']   = SpuModel::statusTextList(); | |||
|  |         $this->data['spuTypeList']  = SpuModel::spuTypeTextList(); | |||
|  |         $this->data['limitList']    = SpuModel::limitList(); | |||
|  |         $this->data['categoryJson'] = json_encode($categoryList, JSON_UNESCAPED_UNICODE); | |||
|  |         $this->data['type']         = $type; | |||
|  |         $this->data['isScore']      = $type === SpuModel::TYPE_SCORE; | |||
|  | 
 | |||
|  |         return $this->view(); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 检测商品是否处于活动 | |||
|  |      * | |||
|  |      * @return Json | |||
|  |      * @throws RepositoryException | |||
|  |      */ | |||
|  |     public function checkActivity(): Json | |||
|  |     { | |||
|  |         $repo = SpuRepository::getInstance(); | |||
|  |         $id   = $this->request->param('id/d', 0); | |||
|  |         $spu  = $repo->findById($id); | |||
|  |         if (empty($spu)) { | |||
|  |             return $this->json(4000, '没有相关的商品记录!'); | |||
|  |         } | |||
|  | 
 | |||
|  |         if ($spu->is_activity > 0) { | |||
|  |             $activityText = SpuModel::activityTextList()[$spu['activity_type']] ?? ''; | |||
|  |             $msg          = '该商品正在参与'.$activityText.'活动 无法进行此操作!'; | |||
|  |             return $this->json(4000, $msg); | |||
|  |         } | |||
|  | 
 | |||
|  |         return $this->json(); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws DataNotFoundException | |||
|  |      * @throws ModelNotFoundException | |||
|  |      * @throws DbException|RepositoryException | |||
|  |      */ | |||
|  |     public function edit() | |||
|  |     { | |||
|  |         $repo = SpuRepository::getInstance(); | |||
|  |         $id   = $this->request->param('id/d', 0); | |||
|  |         $spu  = $repo->findById($id); | |||
|  |         if (empty($spu)) { | |||
|  |             return $this->json(4000, '没有相关的商品记录!'); | |||
|  |         } | |||
|  | 
 | |||
|  |         if ($spu->is_activity > 0) { | |||
|  |             $activityText = SpuModel::activityTextList()[$spu['activity_type']] ?? ''; | |||
|  |             $msg          = '该商品正在参与'.$activityText.'活动 无法进行此操作!'; | |||
|  |             if ($this->request->isPost()) { | |||
|  |                 return $this->json(4000, $msg); | |||
|  |             } else { | |||
|  |                 return $this->error($msg); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         $skuList = Sku::where('spu_id', $id) | |||
|  |             ->where('spu_activity_id', 0) | |||
|  |             ->where('enable', Sku::COMMON_ON) | |||
|  |             ->order('sort', 'asc') | |||
|  |             ->order('id', 'asc')->select()->toArray(); | |||
|  | 
 | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $item                = $this->request->param('item/a', []); | |||
|  |             $multiSpec           = input('post.is_attribute');// 是否多规格 0否 1是
 | |||
|  |             $skus                = input('post.skus');//规格数据
 | |||
|  |             $item['spu_type_id'] = input('post.product_type');//商品类型ID
 | |||
|  |             $item['multi_spec']  = $multiSpec; | |||
|  | 
 | |||
|  |             if ($multiSpec == SpuModel::COMMON_OFF) { | |||
|  |                 $skus = [$skus]; | |||
|  |             } | |||
|  | 
 | |||
|  |             try { | |||
|  |                 $this->checkData($item, $skus); | |||
|  | 
 | |||
|  |                 $repo->editSpu($id, $item, $skus, $skuList); | |||
|  |             } catch (RepositoryException $e) { | |||
|  |                 return $this->json(4002, $e->getMessage()); | |||
|  |             } catch (Exception $e) { | |||
|  |             } | |||
|  | 
 | |||
|  |             return $this->json(); | |||
|  |         } | |||
|  | 
 | |||
|  |         $hasCategories = SpuCategoryPivot::where('spu_id', $id)->column('category_id'); | |||
|  |         $categoryList  = $repo->categoryXmSelect($hasCategories, [], true); | |||
|  | 
 | |||
|  |         $this->data['statusList']   = SpuModel::statusTextList(); | |||
|  |         $this->data['spuTypeList']  = SpuModel::spuTypeTextList(); | |||
|  |         $this->data['limitList']    = SpuModel::limitList(); | |||
|  |         $this->data['categoryJson'] = json_encode($categoryList, JSON_UNESCAPED_UNICODE); | |||
|  |         $this->data['isScore']      = $spu->is_score; | |||
|  |         $this->data['item']         = $spu; | |||
|  |         $this->data['skuList']      = $skuList; | |||
|  |         $this->data['id']           = $id; | |||
|  |         return $this->view(); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 检查数据 | |||
|  |      * | |||
|  |      * @throws RepositoryException | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     protected function checkData(array $item, array $skus) | |||
|  |     { | |||
|  |         // 基础信息验证
 | |||
|  |         $validate = $this->validateByApi($item, [ | |||
|  |             'name|商品名称'         => 'require|max:250', | |||
|  |             'cover|商品封面'        => 'require|max:250', | |||
|  |             'saleable|商品状态'     => 'in:0,1', | |||
|  |             'published_at|发布日期' => 'requireIf:saleable,1|date', | |||
|  |             'subtitle|副标题'      => 'max:2000', | |||
|  |         ]); | |||
|  | 
 | |||
|  |         if ($validate !== true) { | |||
|  |             return $validate; | |||
|  |         } | |||
|  | 
 | |||
|  |         if (empty($skus)) { | |||
|  |             throw new RepositoryException('规格信息不能为空'); | |||
|  |         } | |||
|  | 
 | |||
|  |         foreach ($skus as $k) { | |||
|  |             if ($this->validateSku($k) !== true) { | |||
|  |                 return $validate; | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         return $validate; | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 获取验证结果 | |||
|  |      * | |||
|  |      * @param $sku | |||
|  |      * @return bool|Json | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     protected function validateSku($sku) | |||
|  |     { | |||
|  |         return $this->validateByApi($sku, [ | |||
|  |             'stock'          => 'require|number|gt:0', | |||
|  |             'original_price' => 'number', | |||
|  |             'price'          => 'number', | |||
|  |             'score'          => 'number', | |||
|  |             'is_default'     => 'require|in:0,1', | |||
|  |         ]); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws ModelNotFoundException | |||
|  |      * @throws DbException | |||
|  |      * @throws DataNotFoundException | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function modify() | |||
|  |     { | |||
|  |         if (!$this->request->isPost()) { | |||
|  |             return $this->json(4000, '非法请求'); | |||
|  |         } | |||
|  | 
 | |||
|  |         $item     = input('post.'); | |||
|  |         $validate = $this->validateByApi($item, [ | |||
|  |             'field' => 'require', | |||
|  |             'value' => 'require', | |||
|  |         ]); | |||
|  | 
 | |||
|  |         if ($validate !== true) { | |||
|  |             return $validate; | |||
|  |         } | |||
|  | 
 | |||
|  |         if (!$info = SpuModel::findById($item['id'])) { | |||
|  |             return $this->json(4001, '记录不存在'); | |||
|  |         } | |||
|  | 
 | |||
|  |         if ($item['field'] == 'home_display') { | |||
|  |             $v             = $item['value'] == 1 ? 'big' : 'normal'; | |||
|  |             $item['value'] = $v; | |||
|  |         } | |||
|  | 
 | |||
|  |         $update = [$item['field'] => $item['value']]; | |||
|  | 
 | |||
|  |         try { | |||
|  |             $info->save($update); | |||
|  |             return $this->json(); | |||
|  |         } catch (ValidateException $e) { | |||
|  |             return $this->json(4001, $e->getError()); | |||
|  |         } catch (Exception $e) { | |||
|  |             return $this->json(5000, '修改失败'); | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @return Json | |||
|  |      */ | |||
|  |     public function del(): Json | |||
|  |     { | |||
|  |         if (!$this->request->isPost()) { | |||
|  |             return $this->json(4000, '非法请求'); | |||
|  |         } | |||
|  | 
 | |||
|  |         $ids = $this->request->param('ids/a', []); | |||
|  |         if (empty($ids)) { | |||
|  |             $ids[] = $this->request->param('id/d', 0); | |||
|  |             $ids   = array_filter($ids); | |||
|  |         } | |||
|  | 
 | |||
|  |         try { | |||
|  |             if (count($ids)) { | |||
|  |                 $count = SpuModel::whereIn('id', $ids) | |||
|  |                     ->where('is_activity|saleable', SpuModel::COMMON_ON) | |||
|  |                     ->count(); | |||
|  |                 if ($count > 0) { | |||
|  |                     return $this->json(4002, '当前商品状态不可删除!'); | |||
|  |                 } | |||
|  | 
 | |||
|  |                 SpuRepository::getInstance()->deleteSpu($ids); | |||
|  |                 Log::write(get_class(), 'del', '删除了商品信息,涉及到的ID为:'.implode(',', $ids)); | |||
|  |             } | |||
|  |         } catch (RepositoryException $e) { | |||
|  |             return $this->json(4001, $e->getMessage()); | |||
|  |         } | |||
|  | 
 | |||
|  |         return $this->json(); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 商品详情 | |||
|  |      */ | |||
|  |     public function info() | |||
|  |     { | |||
|  |         $skuId = $this->request->param('id/d', 0); | |||
|  |         $repo  = SpuRepository::getInstance(); | |||
|  |         try { | |||
|  |             $sku = $repo->findById($skuId, []); | |||
|  |         } catch (RepositoryException $e) { | |||
|  |             $sku = null; | |||
|  |         } | |||
|  | 
 | |||
|  |         $this->data['item'] = $sku; | |||
|  |         return $this->view(); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 商品状态下拉选项 | |||
|  |      * | |||
|  |      * @param  array  $selected | |||
|  |      * @param  array  $disabled | |||
|  |      * @return false|string | |||
|  |      */ | |||
|  |     private function handleXmStatus(array $selected = [], array $disabled = []) | |||
|  |     { | |||
|  |         $items = SpuModel::statusTextList(); | |||
|  |         $list  = []; | |||
|  |         foreach ($items as $key => $val) { | |||
|  |             $list[] = [ | |||
|  |                 'name'     => $val, | |||
|  |                 'value'    => $key, | |||
|  |                 'selected' => in_array($key, $selected), | |||
|  |                 'disabled' => in_array($key, $disabled), | |||
|  |             ]; | |||
|  |         } | |||
|  |         return json_encode($list, JSON_UNESCAPED_UNICODE); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function getSpuList(): Json | |||
|  |     { | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $input = [ | |||
|  |                 'type'     => SpuModel::TYPE_NORMAL, | |||
|  |                 'saleable' => SpuModel::COMMON_ON, | |||
|  |                 'keyword'  => input('keyword/s', '') | |||
|  |             ]; | |||
|  |             $data  = SpuRepository::getInstance()->list($input); | |||
|  |             return $this->json(0, 'success', $data); | |||
|  |         } | |||
|  | 
 | |||
|  |         return $this->json(4000, '操作错误'); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function getSpu(): Json | |||
|  |     { | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $id   = input('id/d'); | |||
|  |             $data = SpuModel::findById($id, ['id', 'spu_type_id', 'multi_spec']); | |||
|  |             return $this->json(0, 'success', $data); | |||
|  |         } | |||
|  | 
 | |||
|  |         return $this->json(4000, '操作错误'); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function getSkuList(): Json | |||
|  |     { | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $spuId = input('id/d', 0); | |||
|  |             $data  = Sku::where('spu_id', $spuId)->select(); | |||
|  |             $data  = $data->each(function ($item) { | |||
|  |                 $item->original_price = Math::fen2Yuan($item->original_price); | |||
|  |                 $item->price          = Math::fen2Yuan($item->price); | |||
|  |             }); | |||
|  |             return $this->json(0, 'success', $data); | |||
|  |         } | |||
|  | 
 | |||
|  |         return $this->json(4000, '操作错误'); | |||
|  |     } | |||
|  | 
 | |||
|  |     /** | |||
|  |      * 批量审核 | |||
|  |      * | |||
|  |      * @return View|Json | |||
|  |      * @throws Exception | |||
|  |      */ | |||
|  |     public function check() | |||
|  |     { | |||
|  |         $id = input('id/s', ''); | |||
|  |         if ($this->request->isPost()) { | |||
|  |             $ids   = input('ids/s'); | |||
|  |             $check = input('is_check/d'); | |||
|  | 
 | |||
|  |             if (!in_array($check, [SpuModel::COMMON_ON, SpuModel::COMMON_OFF])) { | |||
|  | 
 | |||
|  |                 return $this->json(4001, '请选择是否展示'); | |||
|  |             } | |||
|  | 
 | |||
|  |             $ids = explode(',', $ids); | |||
|  | 
 | |||
|  |             Db::startTrans(); | |||
|  |             try { | |||
|  |                 (new SpuModel())->whereIn('id', $ids)->save(['is_check' => $check]); | |||
|  |                 Db::commit(); | |||
|  |                 return $this->json(0, '操作成功'); | |||
|  |             } catch (Exception $e) { | |||
|  |                 Db::rollback(); | |||
|  |                 Log::error('商品批量审核操作失败'.$e->getMessage()); | |||
|  |                 return $this->json(5001, '商品批量审核操作失败'); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         $this->data['id'] = $id; | |||
|  | 
 | |||
|  |         return $this->view(); | |||
|  |     } | |||
|  | 
 | |||
|  | } |