Card.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\cardservice\shop\controller;
  11. use addon\cardservice\model\CardGoods;
  12. use addon\cardservice\model\MemberCard as MemberCardModel;
  13. use addon\form\model\Form;
  14. use app\model\goods\Goods as GoodsModel;
  15. use app\model\goods\GoodsBrand as GoodsBrandModel;
  16. use app\model\goods\GoodsService as GoodsServiceModel;
  17. use app\model\store\Store as StoreModel;
  18. use app\model\web\Config as ConfigModel;
  19. use app\shop\controller\BaseShop;
  20. /**
  21. * 虚拟商品
  22. * Class Virtualgoods
  23. * @package app\shop\controller
  24. */
  25. class Card extends BaseShop
  26. {
  27. protected $replace = [
  28. 'ADDON_CARDSERVICE_CSS' => __ROOT__ . '/addon/cardservice/shop/view/public/css',
  29. 'ADDON_CARDSERVICE_JS' => __ROOT__ . '/addon/cardservice/shop/view/public/js',
  30. 'ADDON_CARDSERVICE_IMG' => __ROOT__ . '/addon/cardservice/shop/view/public/img',
  31. ];
  32. /**
  33. * 添加商品
  34. * @return mixed
  35. */
  36. public function addGoods()
  37. {
  38. if (request()->isAjax()) {
  39. $category_id = input("category_id", 0);// 分类id
  40. $category_json = json_encode($category_id);//分类字符串
  41. $category_id = '';
  42. $data = [
  43. 'goods_name' => input("goods_name", ""),// 商品名称,
  44. 'goods_attr_class' => input("goods_attr_class", ""),// 商品类型id,
  45. 'goods_attr_name' => input("goods_attr_name", ""),// 商品类型名称,
  46. 'is_limit' => input("is_limit", "0"),// 商品是否限购,
  47. 'limit_type' => input("limit_type", "1"),// 商品限购类型,
  48. 'site_id' => $this->site_id,
  49. 'category_id' => $category_id,
  50. 'category_json' => $category_json,
  51. 'goods_image' => input("goods_image", ""),// 商品主图路径
  52. 'goods_content' => input("goods_content", ""),// 商品详情
  53. 'goods_state' => input("goods_state", ""),// 商品状态(1.正常0下架)
  54. 'price' => input("price", 0),// 商品价格(取第一个sku)
  55. 'renew_price' => input("renew_price", 0), // 续费价格
  56. 'market_price' => input("market_price", 0),// 市场价格(取第一个sku)
  57. 'cost_price' => input("cost_price", 0),// 成本价(取第一个sku)
  58. 'sku_no' => input("sku_no", ""),// 商品sku编码
  59. 'weight' => input("weight", ""),// 重量
  60. 'volume' => input("volume", ""),// 体积
  61. 'goods_stock' => input("goods_stock", 0),// 商品库存(总和)
  62. 'goods_stock_alarm' => input("goods_stock_alarm", 0),// 库存预警
  63. 'goods_spec_format' => input("goods_spec_format", ""),// 商品规格格式
  64. 'goods_attr_format' => input("goods_attr_format", ""),// 商品参数格式
  65. 'introduction' => input("introduction", ""),// 促销语
  66. 'keywords' => input("keywords", ""),// 关键词
  67. 'unit' => input("unit", ""),// 单位
  68. 'sort' => input("sort", 0),// 排序,
  69. 'video_url' => input("video_url", ""),// 视频
  70. 'goods_sku_data' => input("goods_sku_data", ""),// SKU商品数据
  71. 'goods_service_ids' => input("goods_service_ids", ''),// 商品服务id集合
  72. 'label_id' => input("label_id", ''),// 商品分组id
  73. 'brand_id' => input("brand_id", 0),//品牌id
  74. 'virtual_sale' => input("virtual_sale", 0),// 虚拟销量
  75. 'max_buy' => input("max_buy", 0),// 限购
  76. 'min_buy' => input("min_buy", 0),// 起售
  77. 'recommend_way' => input('recommend_way', 0), // 推荐方式,1:新品,2:精品,3;推荐
  78. 'timer_on' => strtotime(input('timer_on', 0)),//定时上架
  79. 'timer_off' => strtotime(input('timer_off', 0)),//定时下架
  80. 'is_consume_discount' => input('is_consume_discount', 0),//是否参与会员折扣
  81. 'qr_id' => input('qr_id', 0),// 社群二维码id
  82. 'template_id' => input('template_id', 0), // 商品海报id
  83. 'sale_show' => input('sale_show', 0),//
  84. 'stock_show' => input('stock_show', 0),//
  85. 'market_price_show' => input('market_price_show', 0),//
  86. 'barrage_show' => input('barrage_show', 0),//
  87. 'form_id' => input('form_id', 0),
  88. 'sale_channel' => input('sale_channel', 'all'),
  89. 'sale_store' => input('sale_store', 'all'),
  90. 'card_type' => input('card_type', ''),
  91. 'validity_type' => input('validity_type', 0),
  92. 'discount_goods_type' => input('discount_goods_type', 'all'),
  93. 'discount' => input('discount', 0),
  94. 'common_num' => input('common_num', 0),
  95. 'relation_goods' => input('relation_goods', '[]'),
  96. 'is_unify_price' => input('is_unify_price', 1),
  97. ];
  98. if ($data[ 'validity_type' ] == 1) {
  99. $data[ 'validity_day' ] = input("validity_day", 0);
  100. } else if ($data[ 'validity_type' ] == 2) {
  101. $data[ 'validity_time' ] = strtotime(input("validity_time", ''));
  102. }
  103. $virtual_goods_model = new CardGoods();
  104. $res = $virtual_goods_model->addGoods($data);
  105. return $res;
  106. } else {
  107. $virtual_goods_model = new CardGoods();
  108. // 商品服务
  109. $goods_service_model = new GoodsServiceModel();
  110. $service_list = $goods_service_model->getServiceList([ [ 'site_id', '=', $this->site_id ] ], 'id,service_name,icon')[ 'data' ];
  111. $this->assign("service_list", $service_list);
  112. // 商品品牌
  113. $goods_brand_model = new GoodsBrandModel();
  114. $brand_list = $goods_brand_model->getBrandList([ [ 'site_id', '=', $this->site_id ] ], 'brand_id,brand_name', 'sort asc')[ 'data' ];
  115. $this->assign("brand_list", $brand_list);
  116. //商品默认排序值
  117. $config_model = new ConfigModel();
  118. $sort_config = $config_model->getGoodsSort($this->site_id);
  119. $sort_config = $sort_config[ 'data' ][ 'value' ];
  120. $this->assign("sort_config", $sort_config);
  121. //获取商品海报
  122. $poster_list = event('PosterTemplate', [ 'site_id' => $this->site_id ], true);
  123. if (!empty($poster_list)) {
  124. $poster_list = $poster_list[ 'data' ];
  125. }
  126. $this->assign('poster_list', $poster_list);
  127. $this->assign('virtualcard_exit', addon_is_exit('virtualcard', $this->site_id));
  128. $form_is_exit = addon_is_exit('form', $this->site_id);
  129. if ($form_is_exit) {
  130. $form_list = ( new Form() )->getFormList([ [ 'site_id', '=', $this->site_id ], [ 'form_type', '=', 'goods' ], [ 'is_use', '=', 1 ] ], 'id desc', 'id, form_name')[ 'data' ];
  131. $this->assign('form_list', $form_list);
  132. }
  133. $this->assign('form_is_exit', $form_is_exit);
  134. $this->assign('all_goodsclass', event('GoodsClass'));
  135. $this->assign('goods_class', $virtual_goods_model->getGoodsClass());
  136. $this->assign('card_type', $virtual_goods_model->getCardType());
  137. $this->assign('store_is_exit', addon_is_exit('store', $this->site_id));
  138. return $this->fetch("card/add_goods", [], $this->replace);
  139. }
  140. }
  141. /**
  142. * 编辑商品
  143. * @return mixed
  144. */
  145. public function editGoods()
  146. {
  147. $virtual_goods_model = new CardGoods();
  148. if (request()->isAjax()) {
  149. $category_id = input("category_id", 0);// 分类id
  150. $category_json = json_encode($category_id);//分类字符串
  151. $category_id = '';
  152. $data = [
  153. 'goods_id' => input("goods_id", 0),// 商品id
  154. 'goods_name' => input("goods_name", ""),// 商品名称,
  155. 'goods_attr_class' => input("goods_attr_class", ""),// 商品类型id,
  156. 'goods_attr_name' => input("goods_attr_name", ""),// 商品类型名称,
  157. 'is_limit' => input("is_limit", "0"),// 商品是否限购,
  158. 'limit_type' => input("limit_type", "1"),// 商品限购类型,
  159. 'site_id' => $this->site_id,
  160. 'category_id' => $category_id,
  161. 'category_json' => $category_json,
  162. 'goods_image' => input("goods_image", ""),// 商品主图路径
  163. 'goods_content' => input("goods_content", ""),// 商品详情
  164. 'goods_state' => input("goods_state", ""),// 商品状态(1.正常0下架)
  165. 'price' => input("price", 0),// 商品价格(取第一个sku)
  166. 'renew_price' => input("renew_price", 0), // 续费价格
  167. 'market_price' => input("market_price", 0),// 市场价格(取第一个sku)
  168. 'cost_price' => input("cost_price", 0),// 成本价(取第一个sku)
  169. 'sku_no' => input("sku_no", ""),// 商品sku编码
  170. 'weight' => input("weight", ""),// 重量
  171. 'volume' => input("volume", ""),// 体积
  172. 'goods_stock' => input("goods_stock", 0),// 商品库存(总和)
  173. 'goods_stock_alarm' => input("goods_stock_alarm", 0),// 库存预警
  174. 'goods_spec_format' => input("goods_spec_format", ""),// 商品规格格式
  175. 'goods_attr_format' => input("goods_attr_format", ""),// 商品参数格式
  176. 'introduction' => input("introduction", ""),// 促销语
  177. 'keywords' => input("keywords", ""),// 关键词
  178. 'unit' => input("unit", ""),// 单位
  179. 'sort' => input("sort", 0),// 排序,
  180. 'video_url' => input("video_url", ""),// 视频
  181. 'goods_sku_data' => input("goods_sku_data", ""),// SKU商品数据
  182. 'goods_service_ids' => input("goods_service_ids", ''),// 商品服务id集合
  183. 'label_id' => input("label_id", ''),// 商品分组id
  184. 'brand_id' => input("brand_id", 0),//品牌id
  185. 'virtual_sale' => input("virtual_sale", 0),// 虚拟销量
  186. 'max_buy' => input("max_buy", 0),// 限购
  187. 'min_buy' => input("min_buy", 0),// 起售
  188. 'recommend_way' => input('recommend_way', 0), // 推荐方式,1:新品,2:精品,3;推荐
  189. 'timer_on' => strtotime(input('timer_on', 0)),//定时上架
  190. 'timer_off' => strtotime(input('timer_off', 0)),//定时下架
  191. 'spec_type_status' => input('spec_type_status', 0),
  192. 'is_consume_discount' => input('is_consume_discount', 0),//是否参与会员折扣
  193. 'qr_id' => input('qr_id', 0),// 社群二维码id
  194. 'template_id' => input('template_id', 0), // 商品海报id
  195. 'sale_show' => input('sale_show', 0),//
  196. 'stock_show' => input('stock_show', 0),//
  197. 'market_price_show' => input('market_price_show', 0),//
  198. 'barrage_show' => input('barrage_show', 0),//
  199. 'form_id' => input('form_id', 0),
  200. 'sale_channel' => input('sale_channel', 'all'),
  201. 'sale_store' => input('sale_store', 'all'),
  202. 'validity_type' => input('validity_type', 0),
  203. 'discount_goods_type' => input('discount_goods_type', 'all'),
  204. 'discount' => input('discount', 0),
  205. 'common_num' => input('common_num', 0),
  206. 'relation_goods' => input('relation_goods', '[]'),
  207. 'is_unify_price' => input('is_unify_price', 1),
  208. ];
  209. if ($data[ 'validity_type' ] == 1) {
  210. $data[ 'validity_day' ] = input("validity_day", 0);
  211. } else if ($data[ 'validity_type' ] == 2) {
  212. $data[ 'validity_time' ] = strtotime(input("validity_time", ''));
  213. }
  214. $res = $virtual_goods_model->editGoods($data);
  215. return $res;
  216. } else {
  217. $goods_model = new GoodsModel();
  218. $goods_id = input("goods_id", 0);
  219. $goods_info = $virtual_goods_model->editGetGoodsInfo([ 'goods_id' => $goods_id, 'site_id' => $this->site_id ])[ 'data' ];
  220. if (empty($goods_info)) $this->error('未获取到商品信息');
  221. $goods_sku_list = $goods_model->getGoodsSkuList([ [ 'goods_id', '=', $goods_id ], [ 'site_id', '=', $this->site_id ] ], "sku_id,sku_name,sku_no,sku_spec_format,price,market_price,cost_price,stock,virtual_indate,sku_image,sku_images,goods_spec_format,spec_name,stock_alarm,is_default", '')[ 'data' ];
  222. $goods_info[ 'sku_list' ] = $goods_sku_list;
  223. $this->assign("goods_info", $goods_info);
  224. // 商品服务
  225. $goods_service_model = new GoodsServiceModel();
  226. $service_list = $goods_service_model->getServiceList([ [ 'site_id', '=', $this->site_id ] ], 'id,service_name,icon')[ 'data' ];
  227. $this->assign("service_list", $service_list);
  228. // 商品品牌
  229. $goods_brand_model = new GoodsBrandModel();
  230. $brand_list = $goods_brand_model->getBrandList([ [ 'site_id', '=', $this->site_id ] ], 'brand_id,brand_name', 'sort asc')[ 'data' ];
  231. $this->assign("brand_list", $brand_list);
  232. //获取商品海报
  233. $poster_list = event('PosterTemplate', [ 'site_id' => $this->site_id ], true);
  234. if (!empty($poster_list)) {
  235. $poster_list = $poster_list[ 'data' ];
  236. }
  237. $this->assign('poster_list', $poster_list);
  238. $form_is_exit = addon_is_exit('form', $this->site_id);
  239. if ($form_is_exit) {
  240. $form_list = ( new Form() )->getFormList([ [ 'site_id', '=', $this->site_id ], [ 'form_type', '=', 'goods' ], [ 'is_use', '=', 1 ] ], 'id desc', 'id, form_name')[ 'data' ];
  241. $this->assign('form_list', $form_list);
  242. }
  243. $this->assign('form_is_exit', $form_is_exit);
  244. $store_is_exit = addon_is_exit('store', $this->site_id);
  245. if ($store_is_exit && $goods_info[ 'sale_store' ] != 'all') {
  246. $store_list = ( new StoreModel() )->getStoreList([ [ 'site_id', '=', $this->site_id ], [ 'store_id', 'in', $goods_info[ 'sale_store' ] ] ], 'store_id,store_name,status,address,full_address,is_frozen');
  247. $this->assign('store_list', $store_list[ 'data' ]);
  248. }
  249. $this->assign('store_is_exit', $store_is_exit);
  250. $this->assign('card_type', $virtual_goods_model->getCardType());
  251. return $this->fetch("card/edit_goods", [], $this->replace);
  252. }
  253. }
  254. public function goodscard()
  255. {
  256. $goods_id = input('goods_id', 0);
  257. $model = new MemberCardModel();
  258. if (request()->isAjax()) {
  259. $page_index = input('page', 1);
  260. $page_size = input('page_size', PAGE_LIST_ROWS);
  261. $search_text = input('search_text', '');
  262. $condition = [
  263. [ 'mgc.site_id', '=', $this->site_id ],
  264. [ 'mgc.goods_id', '=', $goods_id ],
  265. ];
  266. if (!empty($search_text)) {
  267. $condition[] = [ 'm.nickname', 'like', '%' . $search_text . '%' ];
  268. }
  269. $field = 'mgc.*, g.goods_name,g.price,g.goods_image,m.username,m.nickname,m.headimg';
  270. $join = [
  271. [ 'goods g', 'mgc.goods_id = g.goods_id', 'inner' ],
  272. [ 'member m', 'mgc.member_id = m.member_id', 'left' ],
  273. ];
  274. $list = $model->getCardPageList($condition, $field, 'mgc.create_time desc', $page_index, $page_size, 'mgc', $join);
  275. return $list;
  276. } else {
  277. $this->assign('goods_id', $goods_id);
  278. $goods_model = new GoodsModel();
  279. $goods_info = $goods_model->getGoodsInfo([ [ 'goods_id', '=', $goods_id ], [ 'site_id', '=', $this->site_id ] ], 'goods_id, goods_name,goods_image,price,goods_state,goods_stock,sale_num');
  280. $this->assign('goods_info', $goods_info[ 'data' ]);
  281. $card_stat = $model->getCardInfo([ [ 'goods_id', '=', $goods_id ], [ 'site_id', '=', $this->site_id ] ], 'sum(total_num) as total_num, sum(total_use_num) as total_use_num')[ 'data' ] ?? [];
  282. $this->assign('total_num', $card_stat[ 'total_num' ] ?? 0);
  283. $this->assign('total_use_num', $card_stat[ 'total_use_num' ] ?? 0);
  284. $card_info = $model->getCardSelect([ [ 'goods_id', '=', $goods_id ], [ 'site_id', '=', $this->site_id ] ])[ 'data' ] ?? [];
  285. $this->assign('card_info', $card_info);
  286. return $this->fetch('card/goods_card');
  287. }
  288. }
  289. public function membergoodscard()
  290. {
  291. $member_id = input('member_id', 0);
  292. if (request()->isAjax()) {
  293. $page_index = input('page', 1);
  294. $page_size = input('page_size', PAGE_LIST_ROWS);
  295. $search_text = input('search_text', '');
  296. $condition = [
  297. [ 'mgc.site_id', '=', $this->site_id ],
  298. [ 'mgc.member_id', '=', $member_id ],
  299. ];
  300. if (!empty($search_text)) {
  301. $condition[] = [ 'g.goods_name', 'like', '%' . $search_text . '%' ];
  302. }
  303. $model = new MemberCardModel();
  304. $card_goods = new CardGoods();
  305. $field = 'mgc.*, g.goods_name,g.price,g.goods_image,m.username,m.nickname,m.headimg';
  306. $join = [
  307. [ 'goods g', 'mgc.goods_id = g.goods_id', 'inner' ],
  308. [ 'member m', 'mgc.member_id = m.member_id', 'left' ],
  309. ];
  310. $list = $model->getCardPageList($condition, $field, 'mgc.create_time desc', $page_index, $page_size, 'mgc', $join);
  311. foreach ($list[ 'data' ][ 'list' ] as $k => $v) {
  312. $list[ 'data' ][ 'list' ][ $k ][ 'card_type_name' ] = $card_goods->getCardType($v[ 'card_type' ])[ 'title' ];
  313. }
  314. return $list;
  315. } else {
  316. $this->assign('member_id', $member_id);
  317. return $this->fetch('card/member_goods_card');
  318. }
  319. }
  320. public function detail()
  321. {
  322. $card_id = input('card_id', 0);
  323. $model = new MemberCardModel();
  324. $card_goods = new CardGoods();
  325. $condition = [
  326. [ 'mgc.card_id', '=', $card_id ],
  327. [ 'mgc.site_id', '=', $this->site_id ],
  328. ];
  329. $field = 'mgc.*, g.goods_name,g.price,g.goods_image,m.username,m.nickname,m.headimg';
  330. $join = [
  331. [ 'goods g', 'mgc.goods_id = g.goods_id', 'inner' ],
  332. [ 'member m', 'mgc.member_id = m.member_id', 'left' ],
  333. ];
  334. $detail = $model->getCardInfo($condition, $field, 'mgc', $join)[ 'data' ] ?? [];
  335. $detail[ 'card_type_name' ] = $card_goods->getCardType($detail[ 'card_type' ])[ 'title' ];
  336. $this->assign('detail', $detail);
  337. $condition = [];
  338. $condition[] = [ 'mgc.card_id', '=', $card_id ];
  339. $condition[] = [ 'g.goods_state', '=', 1 ];
  340. $condition[] = [ 'g.is_delete', '=', 0 ];
  341. $field = 'mgc.*, g.sku_name';
  342. $join = [
  343. [ 'goods_sku g', 'mgc.sku_id = g.sku_id', 'left' ],
  344. ];
  345. $item_list = $model->getCartItemList($condition, $field, 'mgc.item_id asc', 'mgc', $join)[ 'data' ] ?? [];
  346. $this->assign('item_list', $item_list);
  347. return $this->fetch('card/detail');
  348. }
  349. public function getCardItem()
  350. {
  351. if (request()->isAjax()) {
  352. $page_index = input('page', 1);
  353. $page_size = input('page_size', PAGE_LIST_ROWS);
  354. $card_id = input('card_id', 0);
  355. $condition = [];
  356. $condition[] = [ 'mgc.site_id', '=', $this->site_id ];
  357. $condition[] = [ 'mgc.card_id', '=', $card_id ];
  358. $condition[] = [ 'g.goods_state', '=', 1 ];
  359. $condition[] = [ 'g.is_delete', '=', 0 ];
  360. $alias = 'mgc';
  361. $field = 'mgc.*, g.goods_name,g.price,g.goods_image,g.introduction,m.nickname,m.headimg,m.mobile';
  362. $join = [
  363. [ 'goods g', 'mgc.goods_id = g.goods_id', 'inner' ],
  364. [ 'member m', 'mgc.member_id = m.member_id', 'left' ],
  365. ];
  366. $model = new MemberCardModel();
  367. $card_goods = new CardGoods();
  368. $list = $model->getCartItemPageList($condition, $field, 'mgc.item_id asc', $page_index, $page_size, $alias, $join);
  369. foreach ($list[ 'data' ][ 'list' ] as $k => $v) {
  370. $list[ 'data' ][ 'list' ][ $k ][ 'card_type_name' ] = $card_goods->getCardType($v[ 'card_type' ])[ 'title' ];
  371. }
  372. return $list;
  373. }
  374. }
  375. public function records()
  376. {
  377. if (request()->isAjax()) {
  378. $page_index = input('page', 1);
  379. $page_size = input('page_size', PAGE_LIST_ROWS);
  380. $card_id = input('card_id', 0);
  381. $item_id = input('item_id', 0);
  382. $condition = [];
  383. $condition[] = [ 'cr.site_id', '=', $this->site_id ];
  384. if (!empty($item_id)) {
  385. $condition[] = [ 'cr.card_item_id', '=', $item_id ];
  386. }
  387. if (!empty($card_id)) {
  388. $condition[] = [ 'cr.card_id', '=', $card_id ];
  389. }
  390. $alias = 'cr';
  391. $prefix = config('database.connections.mysql.prefix');
  392. $field = 'cr.*, sku.sku_name,sku.sku_image,sku.sku_images,sku.price,ci.num as item_num,
  393. IF(cr.type = \'order\', (select order_id from `' . $prefix . 'order_goods` og where og.order_goods_id = cr.relation_id), 0) as order_id, s.store_name';
  394. $join = [
  395. [ 'member_goods_card_item ci', 'ci.item_id = cr.card_item_id', 'left' ],
  396. [ 'goods_sku sku', 'ci.sku_id = sku.sku_id', 'left' ],
  397. [ 'store s', 'cr.store_id = s.store_id', 'left' ],
  398. ];
  399. $model = new MemberCardModel();
  400. $list = $model->getMemberCardRecordsPageList($condition, $field, 'cr.create_time desc', $page_index, $page_size, $alias, $join);
  401. return $list;
  402. }
  403. }
  404. }