DiyComponentsData.php 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. <?php
  2. namespace common\models\diy;
  3. use addons\Community\common\models\CommunityGoods;
  4. use addons\Community\common\models\CommunityGoodsSetting;
  5. use addons\Course\common\models\AddonsCourse;
  6. use addons\Store\common\enums\CouponEnum;
  7. use addons\Store\common\models\Store;
  8. use addons\Store\common\models\StoreGoods;
  9. use addons\Store\common\models\StoreGoodsCate;
  10. use addons\Store\common\models\StoreGoodsCateRelate;
  11. use addons\Store\common\models\StoreCoupon;
  12. use common\enums\OrderStatusEnum;
  13. use common\enums\StatusEnum;
  14. use common\helpers\StringHelper;
  15. use common\models\goods\Goods;
  16. use common\models\goods\GoodsCate;
  17. use common\models\goods\GoodsCateRelate;
  18. use common\models\order\Order;
  19. use addons\OperatingNote\common\models\AddonsOperatingNoteContent;
  20. use addons\Store\common\models\StoreGoodsExtra;
  21. use common\enums\AddonsEnum;
  22. use common\models\goods\GoodsExtra;
  23. use common\models\goods\template\GoodsDecorationTemplate;
  24. use common\models\user\User;
  25. use common\models\user\UserLevel;
  26. use common\globals\GlobalInvoke;
  27. use Yii;
  28. use yii\db\Exception;
  29. use yii\helpers\Json;
  30. use common\enums\DiyEnum;
  31. use common\helpers\ArrayHelper;
  32. use common\logic\common\GoodsLogic;
  33. use common\models\mall\MallAddons;
  34. class DiyComponentsData extends \common\models\base\BaseActiveRecord
  35. {
  36. /**
  37. * 获取组件对应的数据
  38. * @Author: lun
  39. * @DateTime: 2021/11/2 0002 19:20
  40. * @Copyright: copyright (c) 2021 广东七件事集团
  41. * @param $mallId
  42. * @param $userId
  43. * @param $list
  44. * @return array
  45. */
  46. public static function getCompentsData($mallId, $list, $userId = 0)
  47. {
  48. $data = [];
  49. $time = time();
  50. $user = User::find()->where(['mall_id' => $mallId, 'id' => $userId])->select('id, mall_id, level')->limit(1)->one();
  51. if (!empty($user)) {
  52. //基础会员等级折扣
  53. $user_level = UserLevel::findOne(['mall_id' => $mallId, 'level' => $user['level'], 'status' => StatusEnum::ENABLED]);
  54. }
  55. foreach ($list as $item) {
  56. switch ($item['identify']) {
  57. case 'order_broadcast': // 订单播报-获取最新的三十条数据
  58. if (empty($item['params']['is_virtual'])) {
  59. $before_day = strtotime(date("Y-m-d", strtotime("-3 day")));
  60. $broadcast_params = ['where' => [['=', 'mall_id', $mallId], ['=', 'pay_status', OrderStatusEnum::PAY], ['>=', 'pay_time', $before_day]], 'with' => 'base_user', 'select' => 'id,user_id,pay_time,created_at', 'order' => 'id desc', 'limit' => $item['limit'] ?? 20];
  61. $orders = Order::lists($broadcast_params, true);
  62. foreach ($orders as $order) {
  63. $nickname = $order['base_user']['nickname'];
  64. $username = (mb_strlen($nickname) > 4) ? mb_substr($nickname, 0, 4) . '...' : $nickname;
  65. $data[$item['site']][] = [
  66. 'avatar' => $order['base_user']['avatar_url'],
  67. 'time' => $time - $order['pay_time'],
  68. 'username' => $username,
  69. 'mobile' => substr_replace($order['base_user']['mobile'], '****', 3, 4),
  70. 'created_at' => $order['created_at'],
  71. ];
  72. }
  73. } else {
  74. $data[$item['site']] = self::virtualOrderBroadcast($item['limit']);
  75. }
  76. break;
  77. case 'goods_cate': // 商品分类
  78. // todo 千人千面功能后续再开发
  79. $goods_cate_ids = GoodsCate::getAllCate($mallId, [$item['id']]);
  80. $goods_ids = GoodsCateRelate::find()->select('goods_id')->andWhere(['in', 'cate_id' ,$goods_cate_ids])->column();
  81. $goods_where[] = ['=', 'mall_id', $mallId];
  82. $goods_where[] = ['in', 'id', $goods_ids];
  83. $goods_where[] = ['=', 'status', StatusEnum::ENABLED];
  84. $goods_where[] = ['=', 'is_on_sale', StatusEnum::ENABLED];
  85. $goods_select = 'id,mch_id,goods_name,subtitle,price,original_price,cover_pic,virtual_sales,sales_num,goods_type,goods_source';
  86. $goods_params = array('where' => $goods_where, 'select' => $goods_select, 'order' => 'sort asc,id desc,created_at desc', 'page' => $item['page'] ?? 1, 'limit' => $item['limit'] ?? 20);
  87. $goods = Goods::lists($goods_params, true);
  88. foreach ($goods as &$good) {
  89. $good['sales_num'] += $good['virtual_sales'];
  90. unset($good['virtual_sales']);
  91. if (!empty($good['goods_source'])) {
  92. $t_class = "\\addons\\{$good['goods_source']}\\common\\service\\ShoppingCartService";
  93. if (is_callable([$t_class, "getCanAddToCart"])) {
  94. $good = $t_class::getCanAddToCart($good, $mallId);
  95. }
  96. }
  97. }
  98. unset($good);
  99. $data[$item['site']] = self::getMemberPrice($mallId, $goods, 1, $userId);
  100. $data = GlobalInvoke::exec(GlobalInvoke::GOODS_LIST_EXTRA,$mallId,['mall_id'=>$mallId,'user_id'=>$userId,'type'=>'goods_cate','goods_list'=>$data]) ?: $data;
  101. $data_temp = $data;
  102. $result = [];
  103. if(isset($data_temp['goods_list'])) {
  104. foreach ($data_temp['goods_list'] as $v) {
  105. $result[] = $v;
  106. }
  107. $data = $result;
  108. }
  109. break;
  110. case 'store_goods_cate': // 商品分类
  111. $goods_cate_ids = StoreGoodsCate::getAllCate($mallId, null, [$item['id']]);
  112. $goods_ids = StoreGoodsCateRelate::find()->select('goods_id')->andWhere(['in', 'cate_id' ,$goods_cate_ids])->column();
  113. $goods_where[] = ['=', 'mall_id', $mallId];
  114. $goods_where[] = ['in', 'id', $goods_ids];
  115. $goods_where[] = ['=', 'status', StatusEnum::ENABLED];
  116. $goods_where[] = ['=', 'is_on_sale', StatusEnum::ENABLED];
  117. $goods_select = 'id,goods_name,subtitle,price,original_price,cover_pic,virtual_sales,sales_num,goods_type,goods_source';
  118. $goods_params = array('where' => $goods_where, 'select' => $goods_select, 'order' => 'sort asc,id desc,created_at desc', 'page' => $item['page'] ?? 1, 'limit' => $item['limit'] ?? 20);
  119. $goods = StoreGoods::lists($goods_params, true);
  120. foreach ($goods as &$good) {
  121. $good['sales_num'] += $good['virtual_sales'];
  122. unset($good['virtual_sales']);
  123. if (!empty($good['goods_source'])) {
  124. $t_class = "\\addons\\{$good['goods_source']}\\common\\service\\ShoppingCartService";
  125. if (is_callable([$t_class, "getCanAddToCart"])) {
  126. $good = $t_class::getCanAddToCart($good, $mallId);
  127. }
  128. }
  129. }
  130. unset($good);
  131. $data[$item['site']] = self::getStoreMemberPrice($mallId, $goods, 1, $userId);
  132. $data = GlobalInvoke::exec(GlobalInvoke::GOODS_LIST_EXTRA,$mallId,['mall_id'=>$mallId,'user_id'=>$userId,'type'=>'goods_cate','goods_list'=>$data]) ?: $data;
  133. $data_temp = $data;
  134. $result = [];
  135. if(isset($data_temp['goods_list'])) {
  136. foreach ($data_temp['goods_list'] as $v) {
  137. $result[] = $v;
  138. }
  139. $data = $result;
  140. }
  141. break;
  142. case 'goods_cate_page':
  143. // todo 千人千面功能后续再开发
  144. $goods_cate_ids = GoodsCate::getAllCate($mallId, [$item['id']]);
  145. $goods_ids = GoodsCateRelate::find()->select('goods_id')->andWhere(['in', 'cate_id' ,$goods_cate_ids])->column();
  146. $goods_where[] = ['=', 'mall_id', $mallId];
  147. $goods_where[] = ['in', 'id', $goods_ids];
  148. $goods_where[] = ['=', 'status', StatusEnum::ENABLED];
  149. $goods_where[] = ['=', 'is_on_sale', StatusEnum::ENABLED];
  150. $goods_select = 'id,mch_id,goods_name,subtitle,price,original_price,cover_pic,virtual_sales,sales_num,goods_type,goods_source';
  151. $goods_params = array('where' => $goods_where, 'select' => $goods_select, 'order' => 'sort asc,id desc,created_at desc', 'page' => $item['page'] ?? 1, 'limit' => $item['limit'] > 0 ? $item['limit'] :20);
  152. $goods_list = Goods::listPage($goods_params, false);
  153. $goods = $goods_list['list'];
  154. if (!empty($goods)) {
  155. foreach ($goods as &$good) {
  156. $good['sales_num'] += $good['virtual_sales'];
  157. unset($good['virtual_sales']);
  158. if (!empty($good['goods_source'])) {
  159. $t_class = "\\addons\\{$good['goods_source']}\\common\\service\\ShoppingCartService";
  160. if (is_callable([$t_class, "getCanAddToCart"])) {
  161. $good = $t_class::getCanAddToCart($good, $mallId);
  162. }
  163. }
  164. }
  165. unset($good);
  166. }
  167. $data[$item['site']] = self::getMemberPrice($mallId, $goods, 1, $userId);
  168. $data = GlobalInvoke::exec(GlobalInvoke::GOODS_LIST_EXTRA,$mallId,['mall_id'=>$mallId,'user_id'=>$userId,'type'=>'goods_cate','goods_list'=>$data]) ?: $data;
  169. $data_temp = $data;
  170. $goods_list['list'] = $data[0];
  171. $result = [];
  172. if(isset($data_temp['goods_list'])) {
  173. // foreach ($data_temp['goods_list'] as $v) {
  174. // $result[] = $v;
  175. // }
  176. // $goods_list['list'] = $result;
  177. $goods_list['list'] = call_user_func_array('array_merge', $data_temp['goods_list']);
  178. }
  179. $data = $goods_list;
  180. break;
  181. case 'store_goods_cate_page':
  182. // todo 千人千面功能后续再开发
  183. $goods_cate_ids = StoreGoodsCate::getAllCate($mallId, null, [$item['id']]);
  184. $goods_ids = StoreGoodsCateRelate::find()->select('goods_id')->andWhere(['in', 'cate_id' ,$goods_cate_ids])->column();
  185. $goods_where[] = ['=', 'mall_id', $mallId];
  186. $goods_where[] = ['in', 'id', $goods_ids];
  187. $goods_where[] = ['=', 'status', StatusEnum::ENABLED];
  188. $goods_where[] = ['=', 'is_on_sale', StatusEnum::ENABLED];
  189. $goods_select = 'id,goods_name,subtitle,price,original_price,cover_pic,virtual_sales,sales_num,goods_type,goods_source';
  190. $goods_params = array('where' => $goods_where, 'select' => $goods_select, 'order' => 'sort asc,id desc,created_at desc', 'page' => $item['page'] ?? 1, 'limit' => $item['limit'] > 0 ? $item['limit'] :20);
  191. $goods_list = StoreGoods::listPage($goods_params, false);
  192. $goods = $goods_list['list'];
  193. if (!empty($goods)) {
  194. foreach ($goods as &$good) {
  195. $good['sales_num'] += $good['virtual_sales'];
  196. unset($good['virtual_sales']);
  197. if (!empty($good['goods_source'])) {
  198. $t_class = "\\addons\\{$good['goods_source']}\\common\\service\\ShoppingCartService";
  199. if (is_callable([$t_class, "getCanAddToCart"])) {
  200. $good = $t_class::getCanAddToCart($good, $mallId);
  201. }
  202. }
  203. }
  204. unset($good);
  205. }
  206. $data[$item['site']] = self::getStoreMemberPrice($mallId, $goods, 1, $userId);
  207. $data = GlobalInvoke::exec(GlobalInvoke::GOODS_LIST_EXTRA,$mallId,['mall_id'=>$mallId,'user_id'=>$userId,'type'=>'goods_cate','goods_list'=>$data]) ?: $data;
  208. $data_temp = $data;
  209. $goods_list['list'] = $data[0];
  210. $result = [];
  211. if(isset($data_temp['goods_list'])) {
  212. foreach ($data_temp['goods_list'] as $v) {
  213. $result[] = $v;
  214. }
  215. $goods_list['list'] = $result;
  216. }
  217. $data = $goods_list;
  218. break;
  219. case 'goods': // 商品
  220. $goods_params = ['where' => [['=', 'mall_id', $mallId], ['in', 'id', Json::decode($item['id'], true)], ['=', 'status', StatusEnum::ENABLED], ['=', 'is_on_sale', StatusEnum::ENABLED]], 'select' => 'id,goods_name,subtitle,price,original_price,cover_pic,(sales_num+virtual_sales) as sales_num,is_attr, goods_type,goods_source', 'index' => 'id'];
  221. if ($item['limit']) {
  222. $goods_params['page'] = $item['page'] ?? 1;
  223. $page_data = Goods::listPage($goods_params, false, true);
  224. $data = $page_data['list'];
  225. } else {
  226. $data = Goods::lists($goods_params, true);
  227. }
  228. if(isset($item['addonsFields'])){
  229. $data = Goods::getAddonsGoodsSetting($mallId, $item['addonsFields'], $data, 'list');
  230. }
  231. if($user_level && !empty($user_level['member_price_is_show'])){
  232. foreach($data as &$good){
  233. $good['member_price_is_show'] = 0;
  234. $good['member_price_info'] = [];
  235. // $item['price'] = GoodsLogic::getMemberPriceList($mallId,$item,$user,true);
  236. $good['member_price'] = GoodsLogic::getMemberPriceList($mallId,$good,$user,true);
  237. }
  238. unset($good);
  239. }else{
  240. $data = self::getMemberPrice($mallId, $data, 0, $userId);
  241. }
  242. $data = GlobalInvoke::exec(GlobalInvoke::GOODS_LIST_EXTRA,$mallId,['mall_id'=>$mallId,'user_id'=>$userId,'type'=>'goods','goods_list'=>$data]) ?: $data;
  243. $data_temp = $data;
  244. $result = [];
  245. if(isset($data_temp['goods_list'])){
  246. foreach ($data_temp['goods_list'] as $v){
  247. if (!empty($v['goods_source'])) {
  248. $t_class = "\\addons\\{$v['goods_source']}\\common\\service\\ShoppingCartService";
  249. if (is_callable([$t_class, "getCanAddToCart"])) {
  250. $v = $t_class::getCanAddToCart($v, $mallId);
  251. }
  252. }
  253. $result[$v['id']] = $v;
  254. }
  255. $data = $result;
  256. } else {
  257. foreach ($data as &$good) {
  258. unset($good['virtual_sales']);
  259. if (!empty($good['goods_source'])) {
  260. $t_class = "\\addons\\{$good['goods_source']}\\common\\service\\ShoppingCartService";
  261. if (is_callable([$t_class, "getCanAddToCart"])) {
  262. $good = $t_class::getCanAddToCart($good, $mallId);
  263. }
  264. }
  265. }
  266. }
  267. if (!empty($item['page']) && !empty($item['limit'])) {
  268. $page_data['list'] = array_values($data);
  269. $data = $page_data;
  270. }
  271. break;
  272. case 'course': // 课程
  273. $course_params = ['where' => [['=', 'mall_id', $mallId], ['=', 'status', StatusEnum::ENABLED]], 'select' => 'id,mall_id,cat_id as cate_id,name,cat_id,sell_type,price,line_off_price,sales,logo,is_open_vm,vm_likes,vm_shares,vm_views,likes,shares,views,comments,status,created_at,introduce', 'index' => 'id'];
  274. $data = AddonsCourse::lists($course_params, true);
  275. break;
  276. case 'operating_note': // 运营笔记
  277. $params = ['where' => [['=', 'mall_id', $mallId], ['in', 'id', Json::decode($item['id'], true)], ['=', 'status', StatusEnum::ENABLED]], 'select' => 'title,cover_img,views_num,likes_num,created_at,content_href,note_type,id,virtual_likes_num,virtual_views_num', 'order' => 'id desc'];
  278. $data = AddonsOperatingNoteContent::lists($params, true);
  279. break;
  280. case 'goods_strategy':
  281. $params = ['strategy' => $item['strategy'], 'displayNumber' => $item['displayNumber']];
  282. $data = GoodsDecorationTemplate::getGoodsListByStrategy($mallId, $params);
  283. break;
  284. case 'store_cate_recommend': // 商品分类
  285. // $where = [
  286. // 'mall_id' => $mallId,
  287. // 'status' => StatusEnum::ENABLED,
  288. // 'is_recommend' => 1,
  289. // 'is_on_sale' => StatusEnum::ENABLED,
  290. // ];
  291. $goods_ids = [];
  292. if (empty($item['cate_id']) && empty($item['id'])) { //没有分类id则返回空
  293. return ['list' => [], 'count' => 0, 'page' => 1, 'limit' => $data['limit']];
  294. }
  295. if (!empty($item['id']) && empty($item['cate_id'])) {
  296. // 判断是否是全部分类
  297. $item['cate_id'] = StoreGoodsCate::getStoreGoodsAllCate($mallId, $item['id']);
  298. }
  299. //根据所有一级分类,获取所有分类
  300. $goods_cate_ids = StoreGoodsCate::getAllCate($mallId, null, $item['cate_id']);
  301. $goods_ids = StoreGoodsCateRelate::find()->select('goods_id')->andWhere(['in', 'cate_id' ,$goods_cate_ids])->column();
  302. //获取对应分类的商品id
  303. if (!empty($goods_ids)) {
  304. $item['id'] = $goods_ids;
  305. } else { //无数据则返回空
  306. return ['list' => [], 'count' => 0, 'page' => 1, 'limit' => $data['limit']];
  307. }
  308. $item['is_recommend'] = 1;
  309. // if (!empty($item['id'])) { //单选分类
  310. // $where = [['c_id' => $item['id']]];
  311. // }
  312. // unset($item['id']);
  313. // if (!empty($item['keyword'])) {
  314. // $where['keyword'] = trim($item['keyword']);
  315. // }
  316. // $params = [
  317. // 'where' => $where,
  318. // 'select' => 'id,store_id,goods_name,price,original_price,cover_pic,(virtual_sales+sales_num) as sales_num, show_style,goods_type',
  319. // 'order' => 'sort asc',
  320. // 'limit' => $item['limit'] ?? 10,
  321. // 'page' => $item['page'] ?? 10,
  322. // ];
  323. // $goods = StoreGoods::listPage($params, false);
  324. $goods = self::storeGoodsSqlCombination($mallId, $item);
  325. if (!empty($goods['list'])) {
  326. $goods['list'] = self::getStoreMemberPrice($mallId, $goods['list'], 1, $userId);
  327. // $goods = array_column($goods, null, 'id');
  328. foreach ($goods['list'] as &$val) {
  329. $val['discount'] = bcsub($val['original_price'], $val['price'], 2);
  330. if ($val['discount'] < 0) $val['discount'] = 0;
  331. }
  332. }
  333. $data = $goods;
  334. break;
  335. case 'store-commodity-cate'://o2o门店商品组--选择分类
  336. $goods_ids = [];
  337. if (empty($item['cate_id'])) { //没有分类id则返回空
  338. return ['list' => [], 'count' => 0, 'page' => 1, 'limit' => $data['limit']];
  339. }
  340. unset($item['id']);
  341. //根据所有一级分类,获取所有分类
  342. $goods_cate_ids = StoreGoodsCate::getAllCate($mallId, null, $item['cate_id']);
  343. $goods_ids = StoreGoodsCateRelate::find()->select('goods_id')->andWhere(['in', 'cate_id' ,$goods_cate_ids])->column();
  344. //获取对应分类的商品id
  345. if (!empty($goods_ids)) {
  346. $item['id'] = $goods_ids;
  347. } else { //无数据则返回空
  348. return ['list' => [], 'count' => 0, 'page' => 1, 'limit' => $data['limit']];
  349. }
  350. //获取商品数据
  351. $goods = self::storeGoodsSqlCombination($mallId, $item);
  352. if (!empty($goods['list'])) {
  353. $goods['list'] = self::getStoreMemberPrice($mallId, $goods['list'], 1, $userId);
  354. // $goods = array_column($goods, null, 'id');
  355. foreach ($goods['list'] as &$val) {
  356. $val['discount'] = bcsub($val['original_price'], $val['price'], 2);
  357. if ($val['discount'] < 0) $val['discount'] = 0;
  358. }
  359. }
  360. $data = $goods;
  361. break;
  362. case 'best-sellers': // 商品
  363. $goods_ids = Json::decode($item['id'], true);
  364. $goods_params = [
  365. 'alias' => 'sg',
  366. 'where' => [
  367. ['sg.mall_id' => $mallId],
  368. ['sg.is_recommend' => 1],
  369. ['sg.id' => $goods_ids],
  370. ['sg.status' => StatusEnum::ENABLED],
  371. ['sg.is_on_sale' => StatusEnum::ENABLED]
  372. ],
  373. 'select' => 'sg.id,sg.store_id,sg.goods_name,sg.subtitle,sg.price,sg.original_price,sg.cover_pic,(sg.sales_num+sg.virtual_sales) as sales_num,sg.show_style,sg.goods_type',
  374. ];
  375. // $item['is_recommend'] = 1;
  376. // $list = self::storeGoodsSqlCombination($mallId, $item);
  377. // $data = $list['list'];
  378. $data = StoreGoods::lists($goods_params, true);
  379. $data = array_column($data, null, 'id');
  380. foreach ($data as &$val) {
  381. $val['discount'] = bcsub($val['original_price'], $val['price'], 2);
  382. if ($val['discount'] < 0) $val['discount'] = 0;
  383. }
  384. if($user_level && !empty($user_level['member_price_is_show'])){
  385. foreach($data as &$item){
  386. $item['member_price_is_show'] = 0;
  387. $item['member_price_info'] = [];
  388. $item['price'] = GoodsLogic::getMemberPriceList($mallId,$item,$user,true);
  389. $item['member_price'] = $item['price'];
  390. }
  391. unset($item);
  392. }else{
  393. $data = self::getMemberPrice($mallId, $data, 0, $userId);
  394. }
  395. break;
  396. case 'store-goods': // o2o商品组
  397. // $goods_params = [
  398. // 'where' => [
  399. // ['=', 'mall_id', $mallId],
  400. // ['in', 'id', Json::decode($item['id'], true)],
  401. // ['=', 'status', StatusEnum::ENABLED],
  402. // ['=', 'is_on_sale', StatusEnum::ENABLED]
  403. // ],
  404. // 'select' => 'id,goods_name,subtitle,price,original_price,cover_pic,(sales_num+virtual_sales) as sales_num,is_attr, goods_type,goods_source',
  405. // 'index' => 'id'
  406. // ];
  407. if (empty($item['id'])) {
  408. return [];
  409. }
  410. $list = self::storeGoodsSqlCombination($mallId, $item);
  411. $data = $list['list'];
  412. // $data = StoreGoods::lists($goods_params, true);
  413. // print_r($data);exit;
  414. // $data = array_column($data, null, 'id');
  415. foreach ($data as &$val) {
  416. $val['discount'] = bcsub($val['original_price'], $val['price'], 2);
  417. if ($val['discount'] < 0) $val['discount'] = 0;
  418. }
  419. if($user_level && !empty($user_level['member_price_is_show'])){
  420. foreach($data as &$good){
  421. $good['member_price_is_show'] = 0;
  422. $good['member_price_info'] = [];
  423. // $good['price'] = \addons\Store\common\logic\goods\GoodsLogic::getMemberPriceList($mallId,$good,$user,true);
  424. $good['member_price'] = \addons\Store\common\logic\goods\GoodsLogic::getMemberPriceList($mallId,$good,$user,true);
  425. }
  426. unset($good);
  427. }else{
  428. $data = self::getStoreMemberPrice($mallId, $data, 1, $userId);
  429. }
  430. // 使用前端传输的ID排序重组
  431. if (empty($item['sort_type'])) {
  432. $tmp = [];
  433. foreach (Json::decode($item['id']) ?? [] as $id) {
  434. $tmp[$id] = ArrayHelper::find($data, function ($i) use ($id) {
  435. return $i['id'] == $id;
  436. });
  437. }
  438. $data = $tmp;
  439. }
  440. // 这里注释的代码先不删
  441. // $count = count($data);
  442. // $keys = range($count, 1);
  443. // $data = array_combine($keys, $data);
  444. break;
  445. case 'location_goods':
  446. $data = CommunityGoods::getComponentData($item, $mallId);
  447. if($user_level && !empty($user_level['member_price_is_show'])){
  448. foreach($data as &$item){
  449. $item['member_price_is_show'] = 0;
  450. $item['member_price_info'] = [];
  451. $item['price'] = GoodsLogic::getMemberPriceList($mallId,$item,$user,true);
  452. $item['member_price'] = $item['price'];
  453. }
  454. unset($item);
  455. }else{
  456. $data = self::getMemberPrice($mallId, $data, 0, $userId);
  457. }
  458. $type = $item['type'] ?? 'goods';
  459. if($type == 'goods_cate'){
  460. $initData = array_values($data);
  461. $data = [];
  462. $data[] = $initData;
  463. }
  464. break;
  465. case 'reserve_location_goods':
  466. $data = Goods::getComponentData($item, $mallId);
  467. if($user_level && !empty($user_level['member_price_is_show'])){
  468. foreach($data as &$item){
  469. $item['member_price_is_show'] = 0;
  470. $item['member_price_info'] = [];
  471. $item['price'] = GoodsLogic::getMemberPriceList($mallId,$item,$user,true);
  472. $item['member_price'] = $item['price'];
  473. }
  474. unset($item);
  475. }else{
  476. $data = self::getMemberPrice($mallId, $data, 0, $userId);
  477. }
  478. $type = $item['type'] ?? 'goods';
  479. if($type == 'goods_cate'){
  480. $initData = array_values($data);
  481. $data = [];
  482. $data[] = $initData;
  483. }
  484. break;
  485. case 'store_coupons':
  486. //o2o优惠券
  487. $store_coupon_ids = $item['id'];
  488. $data = StoreCoupon::lists([
  489. 'where' => [
  490. ['id' => $store_coupon_ids],
  491. ['mall_id' => $mallId],
  492. ['status' => StatusEnum::ENABLED],
  493. ['coupon_status' => CouponEnum::STATUS_RECEIVING]
  494. ],
  495. 'select' => 'id,name,type',
  496. 'index' => 'id'
  497. ], true);
  498. break;
  499. case 'score_game_secondary_card':
  500. if (!MallAddons::isInstall($mallId, AddonsEnum::ADDONS_SCORE_GAME)) {
  501. return ['list' => [], 'count' => 0, 'page' => 1, 'limit' => $data['limit']];
  502. }
  503. $item['is_sell'] = 1;
  504. $card_list = (new \addons\ScoreGame\common\service\SecondaryCardService(['mall_id' => $mallId]))->getCardList($item);
  505. $data = $card_list;
  506. break;
  507. default:
  508. break;
  509. }
  510. }
  511. // 仅返回非空数据
  512. return array_filter($data, function ($item) {
  513. return !empty($item);
  514. });
  515. }
  516. public static function getMemberPrice($mallId, $data, $from = 0, $user_id = 0)
  517. {
  518. $goods_id = $from == 0 ? array_keys($data) : array_column($data, 'id');
  519. $extra_params = ['where' => [['in', 'goods_id', $goods_id]], 'select' => 'is_show_price, member_price_setting, is_member_price,goods_id', 'index' => 'goods_id'];
  520. $goods_extra = GoodsExtra::lists($extra_params, true);
  521. $level = 0;
  522. if ($user_id) {
  523. $user = User::find()->where(['mall_id' => $mallId, 'id' => $user_id])->select('id, mall_id, level')->limit(1)->one();
  524. $level = (!$user || $user->level == 0) ? $level : $user->level;
  525. }
  526. $level_where = ['mall_id' => $mallId, 'status' => StatusEnum::ENABLED];
  527. if ($level > 0) $level_where['level'] = $level;
  528. $user_level = UserLevel::find()->where($level_where)->select('discount, level, mall_id, status')->orderBy('level ASC')->limit(1)->one();
  529. if (!empty($goods_extra)) {
  530. // is_member_price: 是否参与会员价[0不参与会员折扣独立设置, 1参与会员折扣独立设置, 2不参与会员折扣]
  531. foreach ($goods_extra as &$v) {
  532. switch ($v['is_member_price']) {
  533. case 0:
  534. $v['member_price_setting'] = [$user_level ? $user_level->discount : 0];
  535. break;
  536. case 1:
  537. $v['member_price_setting'] = json_decode($v['member_price_setting'], true) ?? [];
  538. break;
  539. default:
  540. $v['member_price_setting'] = [0];
  541. break;
  542. }
  543. }
  544. unset($v);
  545. }
  546. foreach ($data as &$value) {
  547. $value['member_price_is_show'] = 0;
  548. $value['member_price_info'] = [];
  549. if (!isset($goods_extra[$value['id']])) {
  550. $value['member_price'] = 0;
  551. continue;
  552. }
  553. $is_member_price = $goods_extra[$value['id']]['is_member_price'] ?? 0;
  554. if ($is_member_price == 0) {
  555. $value['member_price'] = bcmul($value['price'], $goods_extra[$value['id']]['member_price_setting'][0] / 10, 2);
  556. continue;
  557. }
  558. $member_price = 0;
  559. if ($is_member_price == 1) {
  560. $member_price_arr = $goods_extra[$value['id']]['member_price_setting'];
  561. $level_where = ['mall_id' => $mallId, 'status' => StatusEnum::ENABLED];
  562. $lowest_level = UserLevel::find()->where($level_where)->select('discount, level, mall_id, status')->orderBy('level ASC')->limit(1)->one();
  563. if (!empty($value['is_attr'])) {
  564. if (count($member_price_arr) > 1) {
  565. $temp_level = $user_level ? $user_level->level : 0;
  566. // 有等级显示该等级的价格,否则显示第一个等级的
  567. $member_arr = $member_price_arr['level' . ($temp_level == 0 ? $lowest_level->level : $temp_level)];
  568. if (!empty($member_arr)) {
  569. // 增加排序 默认取最低的会员价
  570. asort($member_arr);
  571. $member_arr = array_values($member_arr);
  572. $member_price = $member_arr[0] ?? 0;
  573. }
  574. }
  575. }else{
  576. if (count($member_price_arr) > 1) {
  577. $key_first = array_key_first($member_price_arr);
  578. if (strpos($key_first, 'level') !== false) {// 判断是单规格还是多规格设置
  579. // 多规格商品处理
  580. $member_prices = $level > 0 ? $member_price_arr['level'.$level] : $member_price_arr['level'.$lowest_level->level];
  581. $member_price = is_array($member_prices) ? current($member_prices) : 0;// 多规格默认获取第一个
  582. } else {
  583. // 单规格商品处理
  584. $member_price = $level > 0 ? $member_price_arr[$level] : $member_price_arr[$lowest_level->level];
  585. }
  586. } else {
  587. $key_first = array_key_first($member_price_arr);// 获取第一个key
  588. if (count($member_price_arr) == 1) $member_price = $member_price_arr[$key_first];
  589. if (count($member_price_arr) < 1) $member_price = 0;
  590. }
  591. }
  592. $value['member_price'] = $member_price;
  593. continue;
  594. }
  595. if ($is_member_price == 2) {
  596. $value['member_price'] = $value['price'];
  597. continue;
  598. }
  599. }
  600. unset($value);
  601. return $data;
  602. }
  603. public static function getStoreMemberPrice($mallId, $data, $from = 0, $user_id = 0)
  604. {
  605. $goods_id = $from == 0 ? array_keys($data) : array_column($data, 'id');
  606. $extra_params = ['where' => [['in', 'goods_id', $goods_id]], 'select' => 'member_price_setting, is_member_price,goods_id', 'index' => 'goods_id'];
  607. $goods_extra = StoreGoodsExtra::lists($extra_params, true);
  608. $level = 0;
  609. if ($user_id) {
  610. $user = User::find()->where(['mall_id' => $mallId, 'id' => $user_id])->select('id, mall_id, level')->limit(1)->one();
  611. $level = (!$user || $user->level == 0) ? $level : $user->level;
  612. }
  613. $level_where = ['mall_id' => $mallId, 'status' => StatusEnum::ENABLED];
  614. if ($level > 0) $level_where['level'] = $level;
  615. $user_level = UserLevel::find()->where($level_where)->select('discount, level, mall_id, status')->orderBy('level ASC')->limit(1)->one();
  616. if (!empty($goods_extra)) {
  617. // is_member_price: 是否参与会员价[0不参与会员折扣独立设置, 1参与会员折扣独立设置, 2不参与会员折扣]
  618. foreach ($goods_extra as &$v) {
  619. switch ($v['is_member_price']) {
  620. case 0:
  621. $v['member_price_setting'] = [$user_level ? $user_level->discount : 0];
  622. break;
  623. case 1:
  624. $v['member_price_setting'] = json_decode($v['member_price_setting'], true) ?? [];
  625. break;
  626. default:
  627. $v['member_price_setting'] = [0];
  628. break;
  629. }
  630. }
  631. unset($v);
  632. }
  633. foreach ($data as &$value) {
  634. $value['member_price_is_show'] = 0;
  635. $value['member_price_info'] = [];
  636. if (!isset($goods_extra[$value['id']])) {
  637. $value['member_price'] = 0;
  638. continue;
  639. }
  640. $is_member_price = $goods_extra[$value['id']]['is_member_price'] ?? 0;
  641. if ($is_member_price == 0) {
  642. $value['member_price'] = bcmul($value['price'], $goods_extra[$value['id']]['member_price_setting'][0] / 10, 2);
  643. continue;
  644. }
  645. $member_price = 0;
  646. if ($is_member_price == 1) {
  647. $member_price_arr = $goods_extra[$value['id']]['member_price_setting'];
  648. $level_where = ['mall_id' => $mallId, 'status' => StatusEnum::ENABLED];
  649. $lowest_level = UserLevel::find()->where($level_where)->select('discount, level, mall_id, status')->orderBy('level ASC')->limit(1)->one();
  650. if (!empty($value['is_attr'])) {
  651. if (count($member_price_arr) > 1) {
  652. $temp_level = $user_level ? $user_level->level : 0;
  653. // 有等级显示该等级的价格,否则显示第一个等级的
  654. $member_arr = $member_price_arr['level' . ($temp_level == 0 ? $lowest_level->level : $temp_level)];
  655. if (!empty($member_arr)) {
  656. // 增加排序 默认取最低的会员价
  657. asort($member_arr);
  658. $member_arr = array_values($member_arr);
  659. $member_price = $member_arr[0] ?? 0;
  660. }
  661. }
  662. }else{
  663. if (count($member_price_arr) > 1) {
  664. $key_first = array_key_first($member_price_arr);
  665. if (strpos($key_first, 'level') !== false) {// 判断是单规格还是多规格设置
  666. // 多规格商品处理
  667. $member_prices = $level > 0 ? $member_price_arr['level'.$level] : $member_price_arr['level'.$lowest_level->level];
  668. $member_price = is_array($member_prices) ? current($member_prices) : 0;// 多规格默认获取第一个
  669. } else {
  670. // 单规格商品处理
  671. $member_price = $level > 0 ? $member_price_arr[$level] : $member_price_arr[$lowest_level->level];
  672. }
  673. } else {
  674. $key_first = array_key_first($member_price_arr);// 获取第一个key
  675. if (count($member_price_arr) == 1) $member_price = $member_price_arr[$key_first];
  676. if (count($member_price_arr) < 1) $member_price = 0;
  677. }
  678. }
  679. $value['member_price'] = $member_price;
  680. continue;
  681. }
  682. if ($is_member_price == 2) {
  683. $value['member_price'] = $value['price'];
  684. continue;
  685. }
  686. }
  687. unset($value);
  688. return $data;
  689. }
  690. /**
  691. * 虚拟订单播报数据
  692. * @Author: lun
  693. * @DateTime: 2021/11/29 0029 17:04
  694. * @Copyright: copyright (c) 2021 广东七件事集团
  695. */
  696. private static function virtualOrderBroadcast($limit = 50)
  697. {
  698. $mobile_prefix = ['130', '150', '133', '173', '177', '135', '138', '139', '180', '159'];
  699. $data = [];
  700. $time = time();
  701. for ($i = 0; $i < $limit; $i++) {
  702. $data[] = [
  703. 'avatar' => Yii::$app->request->hostInfo . '/resources/img/def-virtual-avatar/' . rand(1, 500) . '.png',
  704. 'time' => rand(1, 900),
  705. 'username' => StringHelper::randName(),
  706. 'mobile' => $mobile_prefix[rand(0, 9)] . '****' . rand(1000, 9999),
  707. 'create_at' => $time - rand(1, 900) * 60,
  708. ];
  709. }
  710. return $data;
  711. }
  712. //获取o2o门店商品数据--sql语句拼接
  713. public static function storeGoodsSqlCombination($mallId, $data)
  714. {
  715. $status = StatusEnum::ENABLED;
  716. try {
  717. $where = "(sg.`mall_id` = {$mallId}) AND (sg.`status` = {$status}) AND (sg.`is_on_sale` = {$status}) AND (sg.`check_status` = {$status})";
  718. $page = $data['page'] ? $data['page'] : 1;
  719. if (!empty($data['is_recommend'])) $where .= " AND (sg.`is_recommend` = {$data['is_recommend']})";
  720. if (!empty($data['id'])) { //拼接商品id
  721. if (is_string($data['id'])) $data['id'] = json_decode($data['id'],true);
  722. if (is_array($data['id']) && count($data['id']) >= 1) {
  723. $ids = implode(',', $data['id']);
  724. $where .= " AND sg.`id` in ({$ids})";
  725. } else {
  726. throw new \Exception('商品id非数组');
  727. }
  728. }
  729. if (!empty($data['keyword'])) {
  730. $where .= " AND (sg.`goods_name` like '%" .$data['keyword']. "%')";
  731. }
  732. if (isset($data['store_ids']) && is_array($data['store_ids'])) {
  733. if (!empty($data['store_ids'])) {
  734. $store_ids_str = implode(',', $data['store_ids']);
  735. $where .= " AND sg.store_id in ({$store_ids_str})";
  736. } else {
  737. throw new \Exception('无店铺id');
  738. }
  739. }
  740. $select = "DISTINCT sg.id,sg.store_id,sg.goods_name,sg.subtitle,sg.price,sg.original_price,sg.cover_pic,(sg.sales_num+sg.virtual_sales) as sales_num,sg.is_attr,sg.show_style,sg.goods_type,sg.goods_source,st.latitude,st.longitude,sc.num as comment_num";
  741. $orderBy = '';
  742. //根据经纬数据获取商铺距离
  743. if (!empty($data['longitude']) && !empty($data['latitude'])) {
  744. $select .= ",round(
  745. 2 * 6378.137 * ASIN(
  746. SQRT(
  747. POW(
  748. SIN(
  749. PI() * ({$data['longitude']} - st.longitude) / 360
  750. ),
  751. 2
  752. ) + COS(PI() * {$data['latitude']} / 180) * COS(st.latitude * PI() / 180) * POW(
  753. SIN(
  754. PI() * ({$data['latitude']} - st.latitude) / 360
  755. ),
  756. 2
  757. )
  758. )
  759. )
  760. ,1) AS distance";
  761. $orderBy = 'distance asc';
  762. }
  763. //拼接排序语句
  764. if (!empty($data['sort'])) {
  765. switch ($data['sort']) {
  766. case 'price':
  767. $data['sort_type'] = $data['sort_type']?$data['sort_type']:'asc';
  768. $orderBy = "sg.". $data['sort']. ' '. $data['sort_type'];
  769. break;
  770. case 'sales_num':
  771. $data['sort_type'] = $data['sort_type']?$data['sort_type']:'desc';
  772. $orderBy = $data['sort']. ' '. $data['sort_type'];
  773. break;
  774. case 'distance':
  775. $data['sort_type'] = $data['sort_type']?$data['sort_type']:'asc';
  776. $orderBy = $data['sort']. ' '. $data['sort_type'];
  777. break;
  778. case 'comment_num':
  779. $data['sort_type'] = $data['sort_type']?$data['sort_type']:'desc';
  780. $orderBy = $data['sort']. ' '. $data['sort_type'];
  781. break;
  782. }
  783. }
  784. $orderBy .= ",sg.sort desc,sg.id desc";
  785. $orderBy = ltrim($orderBy, ',');
  786. $sql = "SELECT ".$select. " FROM `qimall_addons_store_goods` as sg";
  787. $sql .= " LEFT JOIN `qimall_addons_store` as st on sg.store_id = st.id";
  788. $sql .= " LEFT JOIN `qimall_order_comments_extra` as sc on sg.store_id = sc.store_id AND sg.id = sc.goods_id";
  789. $sql .= " WHERE " . $where;
  790. $sql .= " ORDER BY ". $orderBy;
  791. $count = \Yii::$app->db->createCommand($sql)->execute();
  792. $sql .= " LIMIT " . ($page - 1) * $data['limit'] . ",{$data['limit']}";
  793. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  794. return ['list' => $list, 'count' => $count, 'page' => $page, 'limit' => $data['limit']];
  795. } catch (\Exception $e) {
  796. // print_r($e->getMessage());exit;
  797. return ['list' => [], 'count' => 0, 'page' => $page, 'limit' => $data['limit']];
  798. }
  799. }
  800. }