488 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
			
		
		
	
	
			488 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
| <?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();
 | ||
|     }
 | ||
| 
 | ||
| } |