Goods.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\Enum\GoodsEnum;
  4. use app\common\model\Goods as GoodsModel;
  5. use app\common\model\Guarantee;
  6. use app\common\model\Collect;
  7. use app\common\model\Comment;
  8. use app\common\model\AttributeValue;
  9. // use app\common\model\Coupon;
  10. // use app\common\model\CouponCondition;
  11. // use app\common\model\UserCoupon;
  12. use fast\Http;
  13. use think\Log;
  14. use think\Db;
  15. use app\common\Service\SkuSpec as SkuSpecService;
  16. /**
  17. * 商品接口
  18. */
  19. class Goods extends Base
  20. {
  21. protected $noNeedLogin = [ 'detail', 'lists', 'getWxCode'];
  22. //详情
  23. public function detail()
  24. {
  25. $id = $this->request->param('id/d');
  26. if (!$id) {
  27. $this->error('参数错误');
  28. }
  29. $row = (new GoodsModel())->with([
  30. 'Sku',
  31. 'Comment' => function ($query) {
  32. $query->relation([
  33. 'reply' => function ($user) {
  34. $user->with([
  35. 'manage' => function ($u) {
  36. $u->field('id,nickname');
  37. }
  38. ]);
  39. }
  40. ])->where('status', 'normal')->where('pid', 0)->field('id,goods_id,content,star,user_id,images,comments,createtime')->with([
  41. 'User' => function ($u) {
  42. $u->field('id,nickname,avatar');
  43. }
  44. ])->order('createtime', 'desc')->limit(10);
  45. }
  46. ])->whereIn('status',[GoodsEnum::STATUS_ON_SALE,GoodsEnum::STATUS_SOLD_OUT])->where('id', $id)->find();
  47. if (!$row) {
  48. $this->error('未找到该商品');
  49. }
  50. // 浏览次数
  51. $row->setInc('views');
  52. //收藏
  53. if ($this->auth->isLogin()) {
  54. $row->is_collect = !!(Collect::where('user_id', $this->auth->id)->where('goods_id', $id)->where('status', 1)->find());
  55. } else {
  56. $row->is_collect = false;
  57. }
  58. $row->sku_spec = SkuSpecService::getGoodsSkuSpec($id);
  59. // 要处理规格的图片
  60. // 这个错误是因为 $row->sku_spec 是一个重载属性(通过魔术方法 __get() 获取),不能直接通过引用修改。我们需要先将其转换为普通数组,处理后再赋值回去。
  61. if (!empty($row->sku_spec)) {
  62. $skuSpecData = $row->sku_spec; // 先转换为普通数组
  63. foreach ($skuSpecData as $key => &$item) {
  64. if (!empty($item['sku_value'])) {
  65. foreach ($item['sku_value'] as $k => &$v) {
  66. $v['image'] = empty($v['image']) ? '' : cdnurl($v['image'], true);
  67. }
  68. }
  69. }
  70. $row->sku_spec = $skuSpecData; // 处理完后重新赋值
  71. }
  72. //
  73. //服务保障
  74. $row->guarantee = $row->guarantee_ids ? Guarantee::field('id,name,intro')->where('id', 'IN', $row->guarantee_ids)->where('status', 'normal')->select() : [];
  75. //属性
  76. $row->attributes = AttributeValue::getAttributeList($row->attribute_ids);
  77. //好评度
  78. $row->favor_rate = Comment::degree($id);
  79. //评论
  80. $comment = collection($row->comment)->toArray();
  81. foreach ($comment as &$item) {
  82. if ($item['user']) {
  83. $item['user']['avatar'] = cdnurl($item['user']['avatar'], true);
  84. }
  85. }
  86. $row->setRelation('comment', $comment);
  87. unset($item);
  88. //优惠券
  89. // $conditions = CouponCondition::getGoodsCondition($id, $row->category_id, $row->brand_id);
  90. // $sql = "condition_ids IS NULL OR condition_ids=''";
  91. // foreach ($conditions as $key => $item) {
  92. // $sql .= " OR FIND_IN_SET('{$item['id']}',condition_ids)";
  93. // }
  94. // $couponList = Coupon::field('id,name,result,result_data,allow_num,begintime,endtime,use_times,received_num,give_num,mode,createtime')
  95. // ->where($sql)
  96. // ->where('is_open', 1)
  97. // ->where('is_private', 'no')
  98. // ->where('endtime', '>', time())
  99. // ->select();
  100. // //已经登录,渲染已领的优惠券
  101. // $coupon_ids = [];
  102. // if ($this->auth->isLogin()) {
  103. // $coupon_ids = UserCoupon::where('user_id', $this->auth->id)->column('coupon_id');
  104. // }
  105. // foreach ($couponList as $key => &$item) {
  106. // Coupon::render($item, $coupon_ids);
  107. // $item->hidden(['received_num', 'give_num', 'condition_ids']);
  108. // }
  109. // $row->coupon = $couponList;
  110. $row->visible(explode(',', 'id,title,type,spec_type,sub_title,category_ids,price,lineation_price,sales,views,is_hot,
  111. image,content,images,sku_spec,sku,comment,is_collect,guarantee,attributes,favor_rate,coupon'));
  112. $row = $row->toArray();
  113. $row['content'] = \app\common\library\Service::formatTplToUniapp($row['content']);
  114. $this->success('获取成功', $row);
  115. }
  116. //列表
  117. public function lists()
  118. {
  119. $param = $this->request->param();
  120. // 增加验证器处理
  121. $validate = new \app\api\validate\Goods();
  122. if (!$validate->scene('lists')->check($param)) {
  123. $this->error($validate->getError());
  124. }
  125. $pageSize = $param['pageSize'] ?? 10;
  126. $orderby = $param['orderby'] ?? 'weigh';
  127. $orderway = $param['orderway'] ?? 'desc';
  128. $query = GoodsModel::where(function ($query) use ($param) {
  129. $query->where('status',GoodsEnum::STATUS_ON_SALE);
  130. //关键词
  131. if (isset($param['keywords']) && !empty($param['keywords'])) {
  132. $query->where('title|keywords', 'like', '%' . $param['keywords'] . '%');
  133. $log = \app\common\model\SearchLog::getByKeywords($param['keywords']);
  134. if ($log) {
  135. $log->setInc("nums");
  136. } else {
  137. \app\common\model\SearchLog::create(['keywords' => $param['keyword'], 'nums' => 1, 'status' => 'hidden']);
  138. }
  139. }
  140. //分类
  141. if (isset($param['category_id']) && !empty($param['category_id'])) {
  142. $categoryIds = [];
  143. // 获取子集
  144. $categoryChildIds = \app\common\model\Category::getCategoryChildrenIds($param['category_id']);
  145. $categoryIds = array_merge($categoryChildIds, [$param['category_id']]);
  146. $query->where(function ($query) use ($categoryIds) {
  147. // 所有子分类使用 find_in_set or 匹配,亲测速度并不慢
  148. foreach ($categoryIds as $key => $category_id) {
  149. $query->whereOrRaw("find_in_set($category_id, category_ids)");
  150. }
  151. });
  152. }
  153. //属性
  154. if (isset($param['attributes']) && !empty($param['attributes'])) {
  155. $query->where('id', 'IN', \app\common\model\GoodsAttr::getGoodsIds($param['attributes']));
  156. }
  157. //品牌
  158. if (isset($param['brand_id']) && !empty($param['brand_id'])) {
  159. $query->where('brand_id', 'IN', $param['brand_id']);
  160. }
  161. //价格
  162. if (isset($param['price']) && !empty($param['price'])) {
  163. $priceArr = explode('-', $param['price']);
  164. if (count($priceArr) == 2) {
  165. if (isset($priceArr[0])) {
  166. $priceArr[0] = (float)$priceArr[0];
  167. }
  168. if (isset($priceArr[1])) {
  169. $priceArr[1] = (float)$priceArr[1];
  170. }
  171. $query->where('price', 'BETWEEN', $priceArr);
  172. }
  173. }
  174. });
  175. if (!empty($orderby) && !empty($orderway)) {
  176. $query = $query->order("{$orderby} {$orderway}");
  177. }
  178. $list = $query->paginate($pageSize);
  179. foreach ($list as $item) {
  180. $item->visible(explode(',', 'id,title,image,price,sales,views,description,lineation_price,is_hot,createtime'));
  181. }
  182. $this->success('', $list);
  183. }
  184. //获取小程序码
  185. public function getWxCode()
  186. {
  187. $goods_id = $this->request->post('goods_id');
  188. $version = $this->request->post('version', 'release');
  189. if (empty($goods_id)) {
  190. $this->error('参数错误');
  191. }
  192. $user_id = '';
  193. if ($this->auth->isLogin()) {
  194. $user_id = $this->auth->id;
  195. }
  196. $resource = '';
  197. $fileStream = (new \app\common\library\message\Mini)->getWxCodeUnlimited([
  198. 'scene' => "invite_id={$user_id}&goods_id={$goods_id}",
  199. 'env_version' => $version, //要打开的小程序版本。正式版为 release,体验版为 trial,开发版为 develop
  200. 'page' => 'pages/goods/detail',
  201. 'check_path' => false
  202. ]);
  203. if (is_null(json_decode($fileStream))) {
  204. try {
  205. $img = imagecreatefromstring($fileStream);
  206. ob_start();
  207. imagepng($img);
  208. $resource = ob_get_clean();
  209. } catch (\Exception $e) {
  210. \think\Log::write($e->getMessage());
  211. $this->error("获取微信二维码失败!");
  212. }
  213. } else {
  214. $config = get_addon_config('shop');
  215. if ($config['wxapp']) {
  216. $localFile = ROOT_PATH . 'public' . $config['wxapp'];
  217. if (is_file($localFile)) {
  218. $resource = file_get_contents($localFile);
  219. } else {
  220. $resource = Http::get(cdnurl($config['wxapp'], true));
  221. }
  222. }
  223. if (config('app_debug')) {
  224. Log::write($fileStream);
  225. }
  226. }
  227. if (!$resource) {
  228. Log::write($fileStream);
  229. $this->error("获取二维码失败!");
  230. }
  231. $base64_data = base64_encode($resource);
  232. $base64_file = 'data:image/jpg;base64,' . $base64_data;
  233. $this->success('获取成功', $base64_file);
  234. }
  235. }