Product.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <?php namespace App\Http\Controllers\Api;
  2. use App\Http\Controllers\Admin\ProductType;
  3. use App\Http\Controllers\Api\Api;
  4. use App\Http\Requests\Api\Product as Request;
  5. use App\Models\Business;
  6. use App\Models\Custom;
  7. use App\Models\Product as Model;
  8. use App\Models\Product\Attr as ProductAttr;
  9. use App\Models\Product\City as ProductCity;
  10. use App\Models\Product\Spec as ProductSpec;
  11. use App\Models\Product\Skus as ProductSkus;
  12. use App\Models\ProductPhoto;
  13. use App\Models\Promo;
  14. use App\Models\PromoProduct;
  15. use App\Models\PromoRebate;
  16. use App\Models\RegimentActive;
  17. use App\Models\Regiment;
  18. use App\Models\WeiBan\Tags as WeiBanTags;
  19. use App\Models\Product\Type;
  20. /**
  21. * 产品接口
  22. *
  23. * @author 刘相欣
  24. *
  25. * */
  26. class Product extends Api{
  27. /**
  28. * 获取产品列表 /api/product/get_list
  29. *
  30. * @param string $name 产品名称
  31. * @param int $page 页码,默认1
  32. * @param int $limit 每页条数,默认10条
  33. *
  34. * */
  35. public function get_list(Request $request,Model $Model,Custom $Custom,RegimentActive $RegimentActive,WeiBanTags $WeiBanTags){
  36. // 接口验签
  37. // $this->verify_sign();
  38. // 验证参数
  39. $request->scene('get_list')->validate();
  40. // 检查登录
  41. $uid = $this->getUid();
  42. // 获取客户信息
  43. $custom = $uid ? $Custom->getOne($uid) : [];
  44. // 接收参数
  45. $name = request('name','');
  46. $limit = request('limit',10);
  47. $typeId = request('type_id',0);
  48. // 显示
  49. $map = [['status','=','0'],['stock','>',0]];
  50. // 分类ID
  51. if( $name ) $map[] = ['name','like','%'.$name.'%'];
  52. if( $typeId ) $map[] = ['type_id','=',$typeId];
  53. // 获取分页信息
  54. $Paginator = $Model->query()
  55. ->where($map)
  56. ->orderBy('product.sort')
  57. ->orderBy('product.id')
  58. ->paginate($limit,['product.id','product.sort','product.name','product.thumb','product.spec','product.price','product.market_price','product.stock']);
  59. // 获取数据
  60. $data['total'] = $Paginator->total();
  61. $data['current_page'] = $Paginator->currentPage();
  62. $data['per_page'] = $Paginator->perPage();
  63. $data['last_page'] = $Paginator->lastPage();
  64. $data['data'] = $Paginator->items();
  65. //产品促销活动
  66. $productIds = array_column($Paginator->items(),'id');
  67. $time = time();
  68. $where = [
  69. ['promo.status','=','0'],
  70. ['promo.start_time','<=',$time],
  71. ['promo.end_time','>=',$time],
  72. ['promo_product.status','=',0],
  73. ];
  74. $promoList = PromoProduct::query()
  75. ->join('promo','promo.id','=','promo_product.promo_id')
  76. ->where($where)
  77. ->whereIn('promo_product.product_id',$productIds)
  78. ->select('promo.*','promo_product.product_id','promo_product.id as promo_product_id')
  79. ->get()
  80. ->toArray();
  81. if ($promoList){
  82. $promoList = array_column($promoList,NULL,'product_id');
  83. }
  84. // 查询用户标签
  85. $tags = [];
  86. $cityId = '';
  87. if ($custom){
  88. $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  89. $cityId = $custom['city_id'];
  90. }
  91. // 处理请求
  92. foreach ( $data['data'] as $key => $value ) {
  93. // 处理数据
  94. $value['thumb'] = path_compat($value['thumb']);
  95. $value['regiment_active_id'] = null;
  96. $value['regiment_title'] = '';
  97. // 查询产品拼团信息
  98. $regiment = $RegimentActive::query()->where([['status','=',1],['start_time','<=',$time],['end_time','>=',$time],['product_id','=',$value['id']]])->first(['id as active_id','number','automatic']);
  99. // 如果有拼团信息
  100. if ( $regiment ) {
  101. $value['regiment_active_id']= $regiment['id'];
  102. $value['regiment_title'] = $regiment['automatic'] == 1 ? '多人团' : $regiment['number'].'人团';
  103. }
  104. if ($promoList && $cityId){
  105. if (isset($promoList[$value['id']])){
  106. $promoInfo = $promoList[$value['id']];
  107. $promoTitle = '';
  108. if ($promoInfo['rebate_type'] == 1){
  109. $promoTitle = "满减";
  110. }elseif ($promoInfo['rebate_type'] == 2){
  111. $promoTitle .= "满折";
  112. }elseif ($promoInfo['rebate_type'] == 3){
  113. $promoTitle .= "满赠";
  114. }
  115. $promoInfoCity = [];
  116. if ($promoInfo['city_ids']){
  117. $promoInfoCity = explode(',',$promoInfo['city_ids']);
  118. }
  119. // 判断是不是可以参与
  120. if (!$promoInfoCity || in_array($cityId,$promoInfoCity)){
  121. if( $promoInfo['tag_scope']) {
  122. // 解析数组
  123. $promoInfo['tag_scope'] = explode(',',$promoInfo['tag_scope']);
  124. // 标签范围限定时,默认不能参与
  125. $allowJoin = 0;
  126. // 判断标签是不是存在
  127. if ($tags){
  128. foreach ($tags as $v) {
  129. // 标签范围内,允许参加
  130. if( in_array($v['name'],$promoInfo['tag_scope']) ) $allowJoin = 1;
  131. }
  132. // 在范围
  133. if( $allowJoin ) {
  134. $value['promo_title'] = $promoTitle;
  135. }
  136. }
  137. }else{
  138. $value['promo_title'] = $promoTitle;
  139. }
  140. }
  141. }
  142. }
  143. // 重组数据
  144. $data['data'][$key] = $value;
  145. }
  146. // 返回结果
  147. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  148. }
  149. /**
  150. * 获取产品列表 /api/product/get_detail
  151. *
  152. * @param int $id 产品id
  153. *
  154. * */
  155. public function get_detail(Request $request,Model $Model,ProductPhoto $ProductPhoto,Business $Business,ProductAttr $ProductAttr,ProductSpec $ProductSpec,ProductSkus $ProductSkus,RegimentActive $RegimentActive,Regiment $Regiment,Custom $Custom,WeiBanTags $WeiBanTags,PromoProduct $PromoProduct){
  156. // 接口验签
  157. // $this->verify_sign();
  158. // 验证参数
  159. $request->scene('get_detail')->validate();
  160. // 检查登录
  161. $uid = $this->checkLogin();
  162. // 获取客户信息
  163. $custom = $uid ? $Custom->getOne($uid) : [];
  164. // 接收参数
  165. $id = request('id',0);
  166. // 显示
  167. $map[] = ['status','=','0'];
  168. // 查询
  169. $data = $Model->query()->where($map)->find($id,['id','name','thumb','stock','spec','poster','price','business_id','market_price']);
  170. // 如果没有数据
  171. if( !$data ) return json_send(['code'=>'error','msg'=>'产品已下架','data'=>['error'=>'产品已下架或不存在']]);
  172. // 转数组
  173. $data = $data->toArray();
  174. // 处理数据
  175. $data['thumb'] = path_compat($data['thumb']);
  176. $data['poster'] = $data['poster'] ? path_compat($data['poster']) : '';
  177. $data['description'] = $Model->getDesc($id);
  178. $data['business_info'] = $Business->getOne($data['business_id']);
  179. $data['photo_list'] = $ProductPhoto->getListByProductId($id);
  180. // 缩略图处理
  181. foreach ($data['photo_list'] as $key => $value) {
  182. $value['thumb'] = path_compat($value['thumb']);
  183. $data['photo_list'][$key] = $value;
  184. }
  185. // 主图追加进去
  186. if( $data['photo_list'] ) array_unshift($data['photo_list'],['id'=>0,'sort'=>0,'thumb'=>$data['thumb']]);
  187. // 获取产品属性
  188. $attr = $ProductAttr->getListByProductId($id);
  189. // 规格属性
  190. $specAttr = [];
  191. // 获取数据
  192. foreach ($attr as $value) {
  193. // 默认未选中
  194. $value['active'] = 0;
  195. $specAttr[$value['spec_id']]['spec_id'] = $value['spec_id'];
  196. $specAttr[$value['spec_id']]['spec_name'] = $ProductSpec->getOne($value['spec_id'],'name');
  197. $specAttr[$value['spec_id']]['attr_list'][] = $value;
  198. }
  199. // 获取规格详情数据
  200. $data['product_attr'] = array_values($specAttr);
  201. // 获取SKU数据
  202. $data['product_sku'] = $ProductSkus->getListByProductId($id);
  203. // 获取数据
  204. foreach ($data['product_sku'] as $key=>$value) {
  205. // 默认未选中
  206. $value['sku_thumb'] = $value['sku_thumb'] ? path_compat($value['sku_thumb']) : '';
  207. $data['product_sku'][$key]= $value;
  208. }
  209. // 手机号
  210. if( isset($data['business_info']['phone']) ) unset($data['business_info']['phone']);
  211. if( isset($data['business_info']['logopic']) ) $data['business_info']['logopic'] = path_compat($data['business_info']['logopic']);
  212. //拼团数据
  213. $time = time();
  214. $regimentWhere = [
  215. ['status','=',1],
  216. ['start_time','<=',$time],
  217. ['end_time','>=',$time],
  218. ['product_id','=',$data['id']]
  219. ];
  220. $regimentActive = $RegimentActive::query()
  221. ->where($regimentWhere)
  222. ->first();
  223. $data['regiment_list'] = [];
  224. $data['automatic_info'] = [];
  225. if ( $regimentActive ){
  226. $data['regiment_number'] = $regimentActive['number'];
  227. $data['regiment_active_id'] = $regimentActive['id'];
  228. $data['regiment_price'] = $regimentActive['regiment_price'];
  229. $data['regiment_quota'] = $regimentActive['quota'];
  230. $data['regiment_active'] = $regimentActive;
  231. $data['automatic_info'] = [];
  232. if ($regimentActive['automatic'] == 1){
  233. $automaticInfo = $Regiment::query()->where([['status','=',0],['active_id','=',$regimentActive['id']],['start_time','<=',$time],['end_time','>=',$time]])->first();
  234. if ($automaticInfo){
  235. $data['automatic_info'] = $automaticInfo;
  236. $data['regiment_type'] = 1;
  237. }else{
  238. $data['regiment_type'] = 2;
  239. }
  240. $data['regiment_title'] = '多人团';
  241. }else{
  242. $data['regiment_title'] = $regimentActive['number'].'人团';
  243. $data['regiment_type'] = 2;
  244. $regiment = $Regiment::query()
  245. ->join('custom','custom.uid','=','regiment.custom_uid')
  246. ->where([['regiment.active_id','=',$data['regiment_active_id']],['regiment.product_id','=',$data['id']],['regiment.status','=',0],['regiment.start_time','<=',$time],['regiment.end_time','>=',$time]])
  247. ->select(['regiment.*','custom.username','custom.userpic'])
  248. ->get();
  249. if ($regiment){
  250. foreach ($regiment as &$value) {
  251. $value['userpic'] = $value['userpic'] ? path_compat($value['userpic']) : '';
  252. $surplusNumber = $data['regiment_number'] - $value['people_number'];
  253. if ($surplusNumber > 0){
  254. $value['surplus_number'] = $surplusNumber;
  255. }else{
  256. $value['surplus_number'] = 0;
  257. }
  258. }
  259. $data['regiment_list'] = $regiment;
  260. }
  261. }
  262. }else{
  263. $data['regiment_active_id'] = null;
  264. $data['regiment_type'] = 0;
  265. }
  266. // 查询用户标签
  267. $tags = [];
  268. $cityId = '';
  269. if ($custom){
  270. $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  271. $cityId = $custom['city_id'];
  272. }
  273. //促销活动信息
  274. $promoInfo = $PromoProduct->getListById($data['id']);
  275. if ($promoInfo && $cityId){
  276. $promoTitle = "满". $promoInfo['std_pay']. "元";
  277. if ($promoInfo['rebate_type'] == 1){
  278. $promoTitle .= "减". $promoInfo['rebate']. "元";
  279. }elseif ($promoInfo['rebate_type'] == 2){
  280. $promoTitle .= "打". $promoInfo['rebate']. "折";
  281. }elseif ($promoInfo['rebate_type'] == 3){
  282. $rebate = (string) PromoRebate::query()->join('product','promo_rebate.product_id','=','product.id')->where([['promo_id','=',$promoInfo['id']]])->value('product.name');
  283. $promoTitle .= "赠送". $rebate;
  284. }
  285. $promoInfoCity = [];
  286. if ($promoInfo['city_ids']){
  287. $promoInfoCity = explode(',',$promoInfo['city_ids']);
  288. }
  289. // 判断是不是可以参与
  290. if (!$promoInfoCity || in_array($cityId,$promoInfoCity)){
  291. if( $promoInfo['tag_scope']) {
  292. // 解析数组
  293. $promoInfo['tag_scope'] = explode(',',$promoInfo['tag_scope']);
  294. // 标签范围限定时,默认不能参与
  295. $allowJoin = 0;
  296. // 判断标签是不是存在
  297. if ($tags){
  298. foreach ($tags as $v) {
  299. // 标签范围内,允许参加
  300. if( in_array($v['name'],$promoInfo['tag_scope']) ) $allowJoin = 1;
  301. }
  302. // 在范围
  303. if( $allowJoin ) {
  304. $data['promo_title'] = $promoTitle;
  305. }
  306. }
  307. }else{
  308. $data['promo_title'] = $promoTitle;
  309. }
  310. }
  311. }
  312. // 返回结果
  313. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  314. }
  315. /**
  316. * 获取产品列表 /api/product/get_sku
  317. *
  318. * @param int $id 产品id
  319. *
  320. * */
  321. public function get_sku(Request $request,ProductAttr $ProductAttr,ProductSpec $ProductSpec,ProductSkus $ProductSkus ){
  322. // 接口验签
  323. // $this->verify_sign();
  324. // 验证参数
  325. $request->scene('get_sku')->validate();
  326. // 检查登录
  327. $uid = $this->checkLogin();
  328. // 接收参数
  329. $id = request('id',0);
  330. // 获取产品属性
  331. $attr = $ProductAttr->getListByProductId($id);
  332. // 规格属性
  333. $specAttr = [];
  334. // 获取数据
  335. foreach ($attr as $value) {
  336. // 默认未选中
  337. $value['active'] = 0;
  338. $specAttr[$value['spec_id']]['spec_id'] = $value['spec_id'];
  339. $specAttr[$value['spec_id']]['spec_name'] = $ProductSpec->getOne($value['spec_id'],'name');
  340. $specAttr[$value['spec_id']]['attr_list'][] = $value;
  341. }
  342. // 获取规格详情数据
  343. $data['product_attr'] = $specAttr;
  344. // 获取SKU数据
  345. $data['product_sku'] = $ProductSkus->getListByProductId($id);
  346. // 返回结果
  347. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  348. }
  349. /**
  350. * 获取产品类型列表 /api/product/get_type
  351. *
  352. *
  353. * */
  354. public function get_type(Request $request,Type $ProductType){
  355. // 接口验签
  356. // $this->verify_sign();
  357. // 检查登录
  358. $uid = $this->getUid();
  359. // 获取产品类型
  360. $list = $ProductType->getList();
  361. // 转数组
  362. $list = array_values($list);
  363. // 返回结果
  364. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$list]);
  365. }
  366. }