Product.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. namespace app\api\model\product;
  3. use app\common\model\product\Product as ProductModel;
  4. use app\common\service\product\BaseProductService;
  5. use app\common\library\helper;
  6. /**
  7. * 商品模型
  8. */
  9. class Product extends ProductModel
  10. {
  11. /**
  12. * 隐藏字段
  13. */
  14. protected $hidden = [
  15. 'spec_rel',
  16. 'delivery',
  17. 'sales_initial',
  18. 'sales_actual',
  19. 'is_delete',
  20. 'app_id',
  21. 'create_time',
  22. 'update_time'
  23. ];
  24. /**
  25. * 商品详情:HTML实体转换回普通字符
  26. */
  27. public function getContentAttr($value)
  28. {
  29. return htmlspecialchars_decode($value);
  30. }
  31. /**
  32. * 获取商品列表
  33. */
  34. public function getList($param, $userInfo = false)
  35. {
  36. // 获取商品列表
  37. $data = parent::getList($param);
  38. // 隐藏api属性
  39. !$data->isEmpty() && $data->hidden(['category', 'content', 'image', 'sku']);
  40. return$this->setProductListData($data, true);
  41. // 整理列表数据并返回
  42. // return $this->setProductListDataFromApi($data, true, ['userInfo' => $userInfo]);
  43. }
  44. /**
  45. * 商品详情
  46. */
  47. public static function detail($product_id)
  48. {
  49. // 商品详情
  50. $detail = parent::detail($product_id);
  51. // 多规格商品sku信息
  52. $detail['product_multi_spec'] = BaseProductService::getSpecData($detail);
  53. return $detail;
  54. }
  55. /**
  56. * 获取商品详情页面
  57. */
  58. public function getDetails($productId, $userInfo = false)
  59. {
  60. // 获取商品详情
  61. $detail = $this->with([
  62. 'category',
  63. 'image' => ['file'],
  64. 'contentImage' => ['file'],
  65. 'sku' => ['image'],
  66. 'spec_rel' => ['spec'],
  67. 'delivery' => ['rule'],
  68. 'commentData' => function ($query) {
  69. $query->with('user')->where(['is_delete' => 0, 'status' => 1])->limit(2);
  70. },
  71. 'video',
  72. 'poster'
  73. ])->withCount(['commentData' => function ($query) {
  74. $query->where(['is_delete' => 0, 'status' => 1]);
  75. }])
  76. ->where('product_id', '=', $productId)
  77. ->find();
  78. // 判断商品的状态
  79. if (empty($detail) || $detail['is_delete'] || $detail['product_status']['value'] != 10) {
  80. $this->error = '很抱歉,商品信息不存在或已下架';
  81. return false;
  82. }
  83. // 更新访问数据
  84. $this->where('product_id', '=', $detail['product_id'])->inc('view_times')->update();
  85. // 设置商品展示的数据
  86. $detail = $this->setProductListDataFromApi($detail, false, ['userInfo' =>null]);
  87. // 多规格商品sku信息
  88. $detail['product_multi_spec'] = BaseProductService::getSpecData($detail);
  89. return $detail;
  90. }
  91. /**
  92. * 根据商品id集获取商品列表
  93. */
  94. public function getListByIdsFromApi($productIds, $userInfo = false)
  95. {
  96. // 获取商品列表
  97. $data = parent::getListByIds($productIds, 10);
  98. // 整理列表数据并返回
  99. return $this->setProductListDataFromApi($data, true, ['userInfo' => $userInfo]);
  100. }
  101. /**
  102. * 根据商品id集获取商品列表
  103. */
  104. public function getListByCatIdsFromApi($categoryIds, $userInfo = false)
  105. {
  106. $category_ids = [];
  107. // 查找1级分类下的二级分类
  108. if(!empty($categoryIds['first'])){
  109. $categorys = (new Category())->where('parent_id', 'in', $categoryIds['first'])->select();
  110. foreach ($categorys as $item){
  111. array_push($category_ids, $item['category_id']);
  112. }
  113. }
  114. foreach ($categoryIds['second'] as $item){
  115. array_push($category_ids, $item);
  116. }
  117. // 获取商品列表
  118. $data = parent::getListByCatIds($category_ids, 10);
  119. // 整理列表数据并返回
  120. return $this->setProductListDataFromApi($data, true, ['userInfo' => $userInfo]);
  121. }
  122. /**
  123. * 设置商品展示的数据 api模块
  124. */
  125. private function setProductListDataFromApi($data, $isMultiple, $param)
  126. {
  127. return parent::setProductListData($data, $isMultiple, function ($product) use ($param) {
  128. // 计算并设置商品会员价
  129. $this->setProductGradeMoney($param['userInfo'], $product);
  130. });
  131. }
  132. /**
  133. * 设置商品的会员价
  134. */
  135. public function setProductGradeMoney($user, &$product)
  136. {
  137. // 会员等级状态
  138. $gradeStatus = (!empty($user) && $user['grade_id'] > 0 && !empty($user['grade']))
  139. && (!$user['grade']['is_delete']);
  140. // 判断商品是否参与会员折扣
  141. if (!$gradeStatus || !$product['is_enable_grade']) {
  142. $product['is_user_grade'] = false;
  143. return;
  144. }
  145. $alone_grade_type = 10;
  146. // 商品单独设置了会员折扣
  147. if ($product['is_alone_grade'] && isset($product['alone_grade_equity'][$user['grade_id']])) {
  148. if($product['alone_grade_type'] == 10){
  149. // 折扣比例
  150. $discountRatio = helper::bcdiv($product['alone_grade_equity'][$user['grade_id']], 100);
  151. }else{
  152. $alone_grade_type = 20;
  153. $discountRatio = helper::bcdiv($product['alone_grade_equity'][$user['grade_id']], $product['product_price'], 2);
  154. }
  155. } else {
  156. // 折扣比例
  157. $discountRatio = helper::bcdiv($user['grade']['equity'], 100);
  158. }
  159. if ($discountRatio < 1) {
  160. // 标记参与会员折扣
  161. $product['is_user_grade'] = true;
  162. // 会员折扣后的商品总金额
  163. if($alone_grade_type == 20){
  164. $product['product_price'] = $product['alone_grade_equity'][$user['grade_id']];
  165. }else{
  166. $product['product_price'] = helper::number2(helper::bcmul($product['product_price'], $discountRatio), true);
  167. }
  168. // 会员折扣价
  169. foreach ($product['sku'] as &$skuItem) {
  170. if($alone_grade_type == 20){
  171. $skuItem['product_price'] = $product['alone_grade_equity'][$user['grade_id']];
  172. }else{
  173. $skuItem['product_price'] = helper::number2(helper::bcmul($skuItem['product_price'], $discountRatio), true);
  174. }
  175. }
  176. }else{
  177. $product['is_user_grade'] = false;
  178. }
  179. }
  180. /**
  181. * 为你推荐
  182. */
  183. public function getRecommendProduct($params)
  184. {
  185. $model = $this;
  186. // 手动
  187. if ($params['choice'] == 1) {
  188. $product_id = array_column($params['product'], 'product_id');
  189. $model = $model->where('product_id', 'IN', $product_id);
  190. $list = $model->with(['category', 'image.file'])
  191. ->where('product_status', '=', 10)
  192. ->where('is_delete', '=', 0)
  193. ->select();
  194. // 整理列表数据并返回
  195. return $this->setProductListData($list, true);
  196. }else {
  197. if($params['type'] == 10){
  198. $sort = ['sales_actual' => 'desc'];
  199. }else if($params['type'] == 20){
  200. $sort = ['create_time' => 'desc'];
  201. } else if($params['type'] == 30){
  202. $sort = ['view_times' => 'desc'];
  203. }
  204. $list = $model->field(['*', '(sales_initial + sales_actual) as product_sales'])->with(['category', 'image.file'])
  205. ->where('product_status', '=', 10)
  206. ->where('is_delete', '=', 0)
  207. ->limit($params['num'])
  208. ->order($sort)
  209. ->select();
  210. return $this->setProductListData($list, true);
  211. }
  212. }
  213. /**
  214. * 查询指定商品
  215. * @param $value
  216. */
  217. public function getProduct($value)
  218. {
  219. $list = $this->where('product_id', 'in', $value)->with(['image.file','sku','spec_rel' => ['spec']])->select();
  220. foreach ($list as $key => &$value) {
  221. // 多规格商品sku信息
  222. $value['product_multi_spec'] = BaseProductService::getSpecData($value);
  223. }
  224. return $list;
  225. }
  226. /**
  227. * 查询指定商品
  228. * @param $value
  229. */
  230. public function getProductList($value)
  231. {
  232. $product = json_decode($value,true);
  233. $product_id = array_column($product, 'product_id');
  234. $list = $this->where('product_id', 'in', $product_id)->with(['image.file','sku','spec_rel' => ['spec']])->select();
  235. foreach ($list as $key => &$value) {
  236. $product_sku_id = 0;
  237. foreach ($product as $kk => $vv) {
  238. if($vv['product_id']==$value['product_id']){
  239. $product_sku_id = $vv['product_sku_id'];
  240. }
  241. }
  242. // 商品sku信息
  243. $value['product_sku'] = ProductModel::getProductSku($value, $product_sku_id);
  244. }
  245. return $list;
  246. }
  247. }