Goods.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Niucloud-admin 企业快速开发的多应用管理平台
  4. // +----------------------------------------------------------------------
  5. // | 官方网址:https://www.niucloud.com
  6. // +----------------------------------------------------------------------
  7. // | niucloud团队 版权所有 开源版本可自由商用
  8. // +----------------------------------------------------------------------
  9. // | Author: Niucloud Team
  10. // +----------------------------------------------------------------------
  11. namespace addon\mall\app\model\goods;
  12. use addon\mall\app\dict\coupon\CouponDict;
  13. use addon\mall\app\dict\goods\GoodsDict;
  14. use addon\mall\app\model\coupon\Coupon;
  15. use addon\mall\app\model\coupon\CouponGoods;
  16. use app\dict\sys\FileDict;
  17. use app\model\shop\Shop;
  18. use app\model\site\Site;
  19. use core\base\BaseModel;
  20. use think\model\concern\SoftDelete;
  21. use think\model\relation\HasMany;
  22. use think\model\relation\HasOne;
  23. /**
  24. * 商品模型
  25. * Class Goods
  26. * @package addon\mall\app\model\goods
  27. */
  28. class Goods extends BaseModel
  29. {
  30. use SoftDelete;
  31. /**
  32. * 数据表主键
  33. * @var string
  34. */
  35. protected $pk = 'goods_id';
  36. /**
  37. * 模型名称
  38. * @var string
  39. */
  40. protected $name = 'mall_goods';
  41. /**
  42. * 定义软删除标记字段.
  43. * @var string
  44. */
  45. protected $deleteTime = 'delete_time';
  46. /**
  47. * 定义软删除字段的默认值
  48. * @var int
  49. */
  50. protected $defaultSoftDelete = 0;
  51. // 设置json类型字段
  52. protected $json = [ 'goods_category', 'label_ids', 'service_ids', 'delivery_type', 'audit_info', 'attr_format' ];
  53. // 设置JSON数据返回数组
  54. protected $jsonAssoc = true;
  55. /**
  56. * 状态字段转化
  57. * @param $value
  58. * @param $data
  59. * @return mixed
  60. */
  61. public function getGoodsTypeNameAttr($value, $data)
  62. {
  63. if (!empty($data[ 'goods_type' ])) {
  64. return GoodsDict::getType($data[ 'goods_type' ])[ 'name' ] ?? '';
  65. }
  66. return '';
  67. }
  68. /**
  69. * 状态字段转化
  70. * @param $value
  71. * @param $data
  72. * @return mixed
  73. */
  74. public function getGoodsEditPathAttr($value, $data)
  75. {
  76. if (!empty($data[ 'goods_type' ])) {
  77. return GoodsDict::getType($data[ 'goods_type' ])[ 'path' ] ?? '';
  78. }
  79. return '';
  80. }
  81. /**
  82. * 获取封面缩略图(小)
  83. */
  84. public function getGoodsCoverThumbSmallAttr($value, $data)
  85. {
  86. if (isset($data[ 'goods_cover' ]) && $data[ 'goods_cover' ] != '') {
  87. return get_thumb_images($data[ 'site_id' ], $data[ 'goods_cover' ], FileDict::SMALL);
  88. }
  89. return [];
  90. }
  91. /**
  92. * 获取封面缩略图(中)
  93. */
  94. public function getGoodsCoverThumbMidAttr($value, $data)
  95. {
  96. if (isset($data[ 'goods_cover' ]) && $data[ 'goods_cover' ] != '') {
  97. return get_thumb_images($data[ 'site_id' ], $data[ 'goods_cover' ], FileDict::MID);
  98. }
  99. return [];
  100. }
  101. /**
  102. * 获取封面缩略图(大)
  103. */
  104. public function getGoodsCoverThumbBigAttr($value, $data)
  105. {
  106. if (isset($data[ 'goods_cover' ]) && $data[ 'goods_cover' ] != '') {
  107. return get_thumb_images($data[ 'site_id' ], $data[ 'goods_cover' ], FileDict::BIG);
  108. }
  109. return [];
  110. }
  111. /**
  112. * 获取商品图片缩略图(小)
  113. */
  114. public function getGoodsImageThumbSmallAttr($value, $data)
  115. {
  116. if (isset($data[ 'goods_image' ]) && $data[ 'goods_image' ] != '') {
  117. $goods_image = explode(',', $data[ 'goods_image' ]);
  118. $img_arr = [];
  119. foreach ($goods_image as $k => $v) {
  120. $img = get_thumb_images($data[ 'site_id' ], $v, FileDict::SMALL);
  121. if (!empty($img)) {
  122. $img_arr[] = $img;
  123. }
  124. }
  125. return $img_arr;
  126. }
  127. return [];
  128. }
  129. /**
  130. * 获取商品图片缩略图(中)
  131. */
  132. public function getGoodsImageThumbMidAttr($value, $data)
  133. {
  134. if (isset($data[ 'goods_image' ]) && $data[ 'goods_image' ] != '') {
  135. $goods_image = explode(',', $data[ 'goods_image' ]);
  136. $img_arr = [];
  137. foreach ($goods_image as $k => $v) {
  138. $img = get_thumb_images($data[ 'site_id' ], $v, FileDict::MID);
  139. if (!empty($img)) {
  140. $img_arr[] = $img;
  141. }
  142. }
  143. return $img_arr;
  144. }
  145. return [];
  146. }
  147. /**
  148. * 获取商品图片缩略图(大)
  149. */
  150. public function getGoodsImageThumbBigAttr($value, $data)
  151. {
  152. if (isset($data[ 'goods_image' ]) && $data[ 'goods_image' ] != '') {
  153. $goods_image = explode(',', $data[ 'goods_image' ]);
  154. $img_arr = [];
  155. foreach ($goods_image as $k => $v) {
  156. $img = get_thumb_images($data[ 'site_id' ], $v, FileDict::BIG);
  157. if (!empty($img)) {
  158. $img_arr[] = $img;
  159. }
  160. }
  161. return $img_arr;
  162. }
  163. return [];
  164. }
  165. /**
  166. * 获取商品分类
  167. */
  168. public function getGoodsCategoryAttr($value, $data)
  169. {
  170. if (!is_array($value)) {
  171. $value = json_decode($value, true);
  172. }
  173. if (!empty($value)) {
  174. return array_map(function($item) {
  175. return (int) $item;
  176. }, $value);
  177. }
  178. return [];
  179. }
  180. public function getGoodsLabelNameAttr($value, $data)
  181. {
  182. if (isset($data[ 'label_ids' ]) && !empty($data[ 'label_ids' ])) {
  183. $goods_label_model = new Label();
  184. return $goods_label_model->where([
  185. [ 'label_id', 'in', $data[ 'label_ids' ] ],
  186. [ 'status', '=', 1 ]
  187. ])->field('label_id, label_name, style_type,color_json,icon')->order('sort desc,label_id desc')->select()->toArray();
  188. }
  189. }
  190. public function getGoodsBrandAttr($value, $data)
  191. {
  192. if (isset($data[ 'brand_id' ]) && !empty($data[ 'brand_id' ])) {
  193. $goods_brand_model = new Brand();
  194. $info = $goods_brand_model->where([
  195. [ 'brand_id', '=', $data[ 'brand_id' ] ],
  196. ])->field('brand_id,brand_name,logo,color_json')
  197. ->findOrEmpty()->toArray();
  198. return $info;
  199. }
  200. }
  201. /**
  202. * 搜索器:商品商品id
  203. * @param $value
  204. * @param $data
  205. */
  206. public function searchGoodsIdAttr($query, $value, $data)
  207. {
  208. if ($value) {
  209. $query->where('goods_id', $value);
  210. }
  211. }
  212. /**
  213. * 搜索器:商品商品名称
  214. * @param $value
  215. * @param $data
  216. */
  217. public function searchGoodsNameAttr($query, $value, $data)
  218. {
  219. if ($value) {
  220. $query->where('goods_name', 'like', '%' . $value . '%');
  221. }
  222. }
  223. /**
  224. * 搜索器:商品副标题
  225. * @param $value
  226. * @param $data
  227. */
  228. public function searchSubTitleAttr($query, $value, $data)
  229. {
  230. if ($value) {
  231. $query->where('sub_title', 'like', '%' . $value . '%');
  232. }
  233. }
  234. /**
  235. * 搜索器:关键词
  236. * @param $value
  237. * @param $data
  238. */
  239. public function searchKeywordAttr($query, $value, $data)
  240. {
  241. if ($value) {
  242. $query->whereLike('goods_name|sub_title', '%' . $value . '%');
  243. }
  244. }
  245. /**
  246. * 搜索器:商品商品类型
  247. * @param $value
  248. * @param $data
  249. */
  250. public function searchGoodsTypeAttr($query, $value, $data)
  251. {
  252. if ($value) {
  253. $query->where('goods_type', $value);
  254. }
  255. }
  256. /**
  257. * 搜索器:商品商品品牌id
  258. * @param $value
  259. * @param $data
  260. */
  261. public function searchBrandIdAttr($query, $value, $data)
  262. {
  263. if ($value) {
  264. $query->where('brand_id', $value);
  265. }
  266. }
  267. /**
  268. * 搜索器:商品商品品牌id(关联查询使用)
  269. * @param $value
  270. * @param $data
  271. */
  272. public function searchSiteIdAttr($query, $value, $data)
  273. {
  274. if ($value) {
  275. $query->where('goods.site_id', $value);
  276. }
  277. }
  278. /**
  279. * 平台商品分类查询
  280. * @param $query
  281. * @param $value
  282. * @param $data
  283. */
  284. public function searchGoodsMallCategoryAttr($query, $value, $data)
  285. {
  286. if ($value) {
  287. if (is_array($value)) {
  288. $value = end($value);
  289. }
  290. //查询分类信息
  291. $goods_category_model = new Category();
  292. $category_info = $goods_category_model->where([ [ 'category_id', '=', $value ] ])->field('category_id,level,pid')->findOrEmpty()->toArray();
  293. if ($category_info[ 'level' ] == 3) {
  294. $query->where('goods_mall_category', $value);
  295. } elseif ($category_info[ 'level' ] == 2) {
  296. $category_ids = $value;
  297. $category_list = $goods_category_model->where([ [ 'pid', '=', $value ] ])->field('category_id,level,pid')->select()->toArray();
  298. if (!empty($category_list)) {
  299. foreach ($category_list as $k => $v) {
  300. $category_ids = $category_ids . ',' . $v[ 'category_id' ];
  301. }
  302. }
  303. $query->where('goods_mall_category', 'in', $category_ids);
  304. } else {
  305. // 一级
  306. $category_ids = $value;
  307. $child_list = $goods_category_model->where([ [ 'pid', '=', $value ] ])->field('category_id,level,pid')->select()->toArray();
  308. if (!empty($child_list)) {
  309. $child_ids = '';
  310. foreach ($child_list as $k => $v) {
  311. $category_ids = $category_ids . ',' . $v[ 'category_id' ];
  312. $child_ids = $child_ids == '' ? $v[ 'category_id' ] : $child_ids . ',' . $v[ 'category_id' ];
  313. }
  314. $grand_child_list = $goods_category_model->where([ [ 'pid', 'in', $child_ids ] ])->field('category_id,level')->select()->toArray();
  315. if (!empty($grand_child_list)) {
  316. foreach ($grand_child_list as $k_child => $v_child) {
  317. $category_ids = $category_ids . ',' . $v_child[ 'category_id' ];
  318. }
  319. }
  320. $query->where('goods_mall_category', 'in', $category_ids);
  321. } else {
  322. $query->where('goods_mall_category', '=', $category_ids);
  323. }
  324. }
  325. }
  326. }
  327. /**
  328. * 搜索器:商品商品分类
  329. * @param $value
  330. * @param $data
  331. */
  332. public function searchGoodsCategoryAttr($query, $value, $data)
  333. {
  334. if ($value) {
  335. if (is_array($value)) {
  336. $temp_where = array_map(function($item) { return '%"' . $item . '"%'; }, $value);
  337. } else {
  338. $temp_where = [ '%"' . $value . '"%' ];
  339. }
  340. $query->where('goods_category', 'like', $temp_where, 'or');
  341. }
  342. }
  343. /**
  344. * 搜索器:商品标签组
  345. * @param $value
  346. * @param $data
  347. */
  348. public function searchLabelIdsAttr($query, $value, $data)
  349. {
  350. if ($value) {
  351. if (is_array($value)) {
  352. $temp_where = array_map(function($item) { return '%"' . $item . '"%'; }, $value);
  353. } else {
  354. $temp_where = [ '%"' . $value . '"%' ];
  355. }
  356. $query->where('label_ids', 'like', $temp_where, 'or');
  357. }
  358. }
  359. /**
  360. * 搜索器:商品服务
  361. * @param $value
  362. * @param $data
  363. */
  364. public function searchServiceIdsAttr($query, $value, $data)
  365. {
  366. if ($value) {
  367. if (is_array($value)) {
  368. $temp_where = array_map(function($item) { return '%"' . $item . '"%'; }, $value);
  369. } else {
  370. $temp_where = [ '%"' . $value . '"%' ];
  371. }
  372. $query->where('service_ids', 'like', $temp_where, 'or');
  373. }
  374. }
  375. /**
  376. * 搜索器:商品销量
  377. * @param $value
  378. * @param $data
  379. */
  380. public function searchSaleNumAttr($query, $value, $data)
  381. {
  382. if (!empty($data[ 'start_sale_num' ]) && !empty($data[ 'end_sale_num' ])) {
  383. $money = [ $data[ 'start_sale_num' ], $data[ 'end_sale_num' ] ];
  384. sort($money);
  385. $query->where('goods.sale_num', 'between', $money);
  386. } elseif (!empty($data[ 'start_sale_num' ])) {
  387. $query->where('goods.sale_num', '>=', $data[ 'start_sale_num' ]);
  388. } elseif (!empty($data[ 'end_sale_num' ])) {
  389. $query->where('goods.sale_num', '<=', $data[ 'end_sale_num' ]);
  390. }
  391. }
  392. /**
  393. * 搜索器:商品sku是否默认
  394. * @param $value
  395. * @param $data
  396. */
  397. public function searchGoodsSkuIsDefaultAttr($query, $value, $data)
  398. {
  399. if ($value) {
  400. $query->where('goodsSku.is_default', $value);
  401. }
  402. }
  403. /**
  404. * 搜索器:商品sku价格
  405. * @param $value
  406. * @param $data
  407. */
  408. public function searchGoodsSkuPriceAttr($query, $value, $data)
  409. {
  410. if (!empty($data[ 'start_price' ]) && !empty($data[ 'end_price' ])) {
  411. $money = [ $data[ 'start_price' ], $data[ 'end_price' ] ];
  412. sort($money);
  413. $query->where('goodsSku.price', 'between', $money);
  414. } elseif (!empty($data[ 'start_price' ])) {
  415. $query->where('goodsSku.price', '>=', $data[ 'start_price' ]);
  416. } elseif (!empty($data[ 'end_price' ])) {
  417. $query->where('goodsSku.price', '<=', $data[ 'end_price' ]);
  418. }
  419. }
  420. /**
  421. * 搜索器:优惠券id(查询适用优惠券的商品列表)
  422. * @param $value
  423. * @param $data
  424. */
  425. public function searchCouponIdAttr($query, $value, $data)
  426. {
  427. if ($value) {
  428. $coupon_goods_model = new CouponGoods();
  429. $coupon = (new Coupon())->where([ [ 'id', '=', $value ] ])->field('site_id, is_all_site_join, join_site_ids')->findOrEmpty()->toArray();
  430. $coupon_list = $coupon_goods_model->where([ [ 'coupon_id', '=', $value ] ])->field('goods_id,category_id,mall_category_id,brand_id')->select()->toArray();
  431. if (!empty($coupon_list)) {
  432. $goods_ids = array_values(array_filter(array_column($coupon_list, 'goods_id')));
  433. $category_ids = array_values(array_filter(array_column($coupon_list, 'category_id')));
  434. $mall_category_ids = array_values(array_filter(array_column($coupon_list, 'mall_category_id')));
  435. $brand_ids = array_values(array_filter(array_column($coupon_list, 'brand_id')));
  436. if (!empty($goods_ids)) {
  437. $query->where('goods.goods_id', 'in', $goods_ids);
  438. } elseif (!empty($category_ids)) {
  439. $like_arr = [];
  440. foreach ($category_ids as $v) {
  441. $like_arr[] = '%' . $v . '%';
  442. }
  443. $query->where('goods_category', 'like', $like_arr, 'or');
  444. } elseif (!empty($mall_category_ids)) {
  445. $query->where('goods_mall_category', 'in', $mall_category_ids);
  446. } elseif (!empty($brand_ids)) {
  447. $query->where('brand_id', 'in', $brand_ids);
  448. }
  449. }
  450. if (!empty($coupon)) {
  451. if ($coupon['site_id']) {
  452. $query->where(function ($query) use ($coupon){
  453. $query->where('goods.site_id', '=', $coupon['site_id']);
  454. });
  455. } else {
  456. if ($coupon['is_all_site_join'] == CouponDict::NOT_ALL_SITE_JOIN) {
  457. $query->where(function ($query) use ($coupon){
  458. $query->where('goods.site_id', 'in', $coupon['join_site_ids']);
  459. });
  460. }
  461. }
  462. }
  463. }
  464. }
  465. /**
  466. * 搜索器:商品商品状态(1.正常0下架)
  467. * @param $value
  468. * @param $data
  469. */
  470. public function searchStatusAttr($query, $value, $data)
  471. {
  472. if ($value !== '') {
  473. $query->where('goods.status', $value);
  474. }
  475. }
  476. /**
  477. * 搜索器:供应商id
  478. * @param $value
  479. * @param $data
  480. */
  481. public function searchSupplierIdAttr($query, $value, $data)
  482. {
  483. if ($value) {
  484. $query->where('supplier_id', $value);
  485. }
  486. }
  487. /**
  488. * 关联默认商品规格
  489. * @return HasOne
  490. */
  491. public function goodsSku()
  492. {
  493. return $this->hasOne(GoodsSku::class, 'goods_id', 'goods_id');
  494. }
  495. /**
  496. * 关联商品规格列表
  497. * @return HasMany
  498. */
  499. public function skuList()
  500. {
  501. return $this->hasMany(GoodsSku::class, 'goods_id', 'goods_id');
  502. }
  503. /**
  504. * 关联站点信息
  505. * @return HasOne
  506. */
  507. public function site()
  508. {
  509. return $this->hasOne(Site::class, 'site_id', 'site_id');
  510. }
  511. /**
  512. * 关联店铺信息
  513. * @return HasOne
  514. */
  515. public function shop()
  516. {
  517. return $this->hasOne(Shop::class, 'site_id', 'site_id');
  518. }
  519. /**
  520. * 关联商品规格列表
  521. * @return HasMany
  522. */
  523. public function goodsSpec()
  524. {
  525. return $this->hasMany(GoodsSpec::class, 'goods_id', 'goods_id');
  526. }
  527. /**
  528. * 关联默认商品规格
  529. * @return HasOne
  530. */
  531. public function brand()
  532. {
  533. return $this->hasOne(Brand::class, 'brand_id', 'brand_id')
  534. ->joinType('left')
  535. ->withField('brand_id, brand_name, logo, desc');
  536. }
  537. }