Presale.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\presale\model;
  11. use app\model\BaseModel;
  12. use app\model\goods\Goods;
  13. use app\model\system\Config as ConfigModel;
  14. use app\model\system\Cron;
  15. use think\facade\Cache;
  16. use think\facade\Db;
  17. /**
  18. * 预售活动
  19. */
  20. class Presale extends BaseModel
  21. {
  22. private $status = [
  23. 0 => '未开始',
  24. 1 => '进行中',
  25. 2 => '已结束',
  26. 3 => '已关闭'
  27. ];
  28. /**
  29. * 获取预售活动状态
  30. * @return array
  31. */
  32. public function getPresaleStatus()
  33. {
  34. return $this->success($this->status);
  35. }
  36. /**
  37. * 添加预售
  38. * @param $presale_data
  39. * @param $goods
  40. * @param $sku_list
  41. * @return array
  42. */
  43. public function addPresale($presale_data, $goods, $sku_list)
  44. {
  45. if (empty($goods[ 'sku_ids' ])) {
  46. return $this->error('', '该活动至少需要一个商品参与');
  47. }
  48. $presale_data[ 'create_time' ] = time();
  49. //查询该商品是否存在预售
  50. $presale_info = model('promotion_presale_goods')->getInfo(
  51. [
  52. [ 'ppg.site_id', '=', $presale_data[ 'site_id' ] ],
  53. [ 'pp.status', 'in', '0,1' ],
  54. [ 'ppg.goods_id', 'in', $goods[ 'goods_ids' ] ],
  55. [ '', 'exp', Db::raw('not ( (`start_time` > ' . $presale_data[ 'end_time' ] . ' and `start_time` > ' . $presale_data[ 'start_time' ] . ' ) or (`end_time` < ' . $presale_data[ 'start_time' ] . ' and `end_time` < ' . $presale_data[ 'end_time' ] . '))') ]
  56. ], 'ppg.id', 'ppg', [ [ 'promotion_presale pp', 'pp.presale_id = ppg.presale_id', 'left' ] ]
  57. );
  58. if (!empty($presale_info)) {
  59. return $this->error('', "当前商品在当前时间段内已经存在预售活动");
  60. }
  61. if (time() > $presale_data[ 'end_time' ]) {
  62. return $this->error('', '当前时间不能大于结束时间');
  63. }
  64. if ($presale_data[ 'start_time' ] <= time()) {
  65. $presale_data[ 'status' ] = 1;
  66. $presale_data[ 'status_name' ] = $this->status[ 1 ];
  67. } else {
  68. $presale_data[ 'status' ] = 0;
  69. $presale_data[ 'status_name' ] = $this->status[ 0 ];
  70. }
  71. model("promotion_presale")->startTrans();
  72. try {
  73. foreach ($goods[ 'goods_ids' ] as $goods_id) {
  74. //添加预售活动
  75. $presale_data[ 'goods_id' ] = $goods_id;
  76. $presale_id = model("promotion_presale")->add($presale_data);
  77. $presale_stock = 0;
  78. $sku_list_data = [];
  79. foreach ($sku_list as $k => $sku) {
  80. if ($sku[ 'goods_id' ] == $goods_id) {
  81. $presale_stock += $sku[ 'presale_stock' ];//总库存
  82. $sku_list_data[] = [
  83. 'site_id' => $presale_data[ 'site_id' ],
  84. 'presale_id' => $presale_id,
  85. 'goods_id' => $goods_id,
  86. 'sku_id' => $sku[ 'sku_id' ],
  87. 'presale_stock' => $sku[ 'presale_stock' ],
  88. 'presale_deposit' => $sku[ 'presale_deposit' ],
  89. 'presale_price' => $sku[ 'presale_price' ],
  90. ];
  91. }
  92. }
  93. array_multisort(array_column($sku_list_data, 'presale_deposit'), SORT_ASC, $sku_list_data);
  94. model('promotion_presale_goods')->addList($sku_list_data);
  95. model('promotion_presale')->update(
  96. [
  97. 'presale_stock' => $presale_stock,
  98. 'presale_deposit' => $sku_list_data[ 0 ][ 'presale_deposit' ],
  99. 'presale_price' => $sku_list_data[ 0 ][ 'presale_price' ],
  100. 'sku_id' => $sku_list_data[ 0 ][ 'sku_id' ]
  101. ],
  102. [ [ 'presale_id', '=', $presale_id ] ]
  103. );
  104. $cron = new Cron();
  105. if ($presale_data[ 'status' ] == 1) {
  106. $goods = new Goods();
  107. $goods->modifyPromotionAddon($goods_id, [ 'presale' => $presale_id ]);
  108. $cron->addCron(1, 0, "预售活动关闭", "ClosePresale", $presale_data[ 'end_time' ], $presale_id);
  109. } else {
  110. $cron->addCron(1, 0, "预售活动开启", "OpenPresale", $presale_data[ 'start_time' ], $presale_id);
  111. $cron->addCron(1, 0, "预售活动关闭", "ClosePresale", $presale_data[ 'end_time' ], $presale_id);
  112. }
  113. }
  114. model('promotion_presale')->commit();
  115. return $this->success();
  116. } catch (\Exception $e) {
  117. model('promotion_presale')->rollback();
  118. return $this->error('', $e->getMessage());
  119. }
  120. }
  121. /**
  122. * 编辑预售
  123. * @param $presale_data
  124. * @param $goods
  125. * @param $sku_list
  126. * @return array
  127. */
  128. public function editPresale($presale_data, $goods, $sku_list)
  129. {
  130. if (empty($goods[ 'sku_ids' ])) {
  131. return $this->error('', '该活动至少需要一个商品参与');
  132. }
  133. //查询该商品是否存在预售
  134. $presale_info = model('promotion_presale_goods')->getInfo(
  135. [
  136. [ 'ppg.site_id', '=', $presale_data[ 'site_id' ] ],
  137. [ 'pp.status', 'in', '0,1' ],
  138. [ 'ppg.presale_id', '<>', $presale_data[ 'presale_id' ] ],
  139. [ 'ppg.sku_id', 'in', $goods[ 'sku_ids' ] ],
  140. [ '', 'exp', Db::raw('not ( (`start_time` > ' . $presale_data[ 'end_time' ] . ' and `start_time` > ' . $presale_data[ 'start_time' ] . ' ) or (`end_time` < ' . $presale_data[ 'start_time' ] . ' and `end_time` < ' . $presale_data[ 'end_time' ] . '))') ]
  141. ], 'ppg.id', 'ppg', [ [ 'promotion_presale pp', 'pp.presale_id = ppg.presale_id', 'left' ] ]
  142. );
  143. if (!empty($presale_info)) {
  144. return $this->error('', "当前商品在当前时间段内已经存在预售活动");
  145. }
  146. $presale_count = model("promotion_presale")->getCount([ [ 'presale_id', '=', $presale_data[ 'presale_id' ] ], [ 'site_id', '=', $presale_data[ 'site_id' ] ] ]);
  147. if ($presale_count == 0) {
  148. return $this->error('', '该预售活动不存在');
  149. }
  150. $cron = new Cron();
  151. if (time() > $presale_data[ 'end_time' ]) {
  152. return $this->error('', '当前时间不能大于结束时间');
  153. }
  154. if ($presale_data[ 'start_time' ] <= time()) {
  155. $presale_data[ 'status' ] = 1;
  156. $presale_data[ 'status_name' ] = $this->status[ 1 ];
  157. } else {
  158. $presale_data[ 'status' ] = 0;
  159. $presale_data[ 'status_name' ] = $this->status[ 0 ];
  160. }
  161. $presale_data[ 'modify_time' ] = time();
  162. model('promotion_presale')->startTrans();
  163. try {
  164. $presale_stock = 0;
  165. $sku_list_data = [];
  166. foreach ($sku_list as $k => $sku) {
  167. $count = model('promotion_presale_goods')->getCount([ [ 'sku_id', '=', $sku[ 'sku_id' ] ], [ 'presale_id', '=', $presale_data[ 'presale_id' ] ] ]);
  168. $is_delete = $sku[ 'is_delete' ];
  169. unset($sku[ 'is_delete' ]);
  170. if ($is_delete == 2) {//是否参与 1参与 2不参与
  171. if ($count) {
  172. model('promotion_presale_goods')->delete([ [ 'sku_id', '=', $sku[ 'sku_id' ] ], [ 'presale_id', '=', $presale_data[ 'presale_id' ] ] ]);
  173. }
  174. } else {
  175. $presale_stock += $sku[ 'presale_stock' ];//总库存
  176. $sku_data = [
  177. 'site_id' => $presale_data[ 'site_id' ],
  178. 'presale_id' => $presale_data[ 'presale_id' ],
  179. 'goods_id' => $goods[ 'goods_id' ],
  180. 'sku_id' => $sku[ 'sku_id' ],
  181. 'presale_stock' => $sku[ 'presale_stock' ],
  182. 'presale_deposit' => $sku[ 'presale_deposit' ],
  183. 'presale_price' => $sku[ 'presale_price' ],
  184. ];
  185. if ($count > 0) {
  186. model('promotion_presale_goods')->update($sku_data, [ [ 'sku_id', '=', $sku[ 'sku_id' ] ], [ 'presale_id', '=', $presale_data[ 'presale_id' ] ] ]);
  187. } else {
  188. model('promotion_presale_goods')->add($sku_data);
  189. }
  190. $sku_list_data[] = $sku_data;
  191. }
  192. }
  193. array_multisort(array_column($sku_list_data, 'presale_deposit'), SORT_ASC, $sku_list_data);
  194. model("promotion_presale")->update(
  195. array_merge($presale_data, [
  196. 'presale_stock' => $presale_stock,
  197. 'presale_deposit' => $sku_list_data[ 0 ][ 'presale_deposit' ],
  198. 'presale_price' => $sku_list_data[ 0 ][ 'presale_price' ],
  199. 'sku_id' => $sku_list_data[ 0 ][ 'sku_id' ]
  200. ]),
  201. [ [ 'presale_id', '=', $presale_data[ 'presale_id' ] ] ]
  202. );
  203. if ($presale_data[ 'start_time' ] <= time()) {
  204. $goods_model = new Goods();
  205. $goods_model->modifyPromotionAddon($goods[ 'goods_id' ], [ 'presale' => $presale_data[ 'presale_id' ] ]);
  206. //活动商品启动
  207. $this->cronOpenPresale($presale_data[ 'presale_id' ]);
  208. $cron->deleteCron([ [ 'event', '=', 'OpenPresale' ], [ 'relate_id', '=', $presale_data[ 'presale_id' ] ] ]);
  209. $cron->deleteCron([ [ 'event', '=', 'ClosePresale' ], [ 'relate_id', '=', $presale_data[ 'presale_id' ] ] ]);
  210. $cron->addCron(1, 0, "预售活动关闭", "ClosePresale", $presale_data[ 'end_time' ], $presale_data[ 'presale_id' ]);
  211. } else {
  212. $cron->deleteCron([ [ 'event', '=', 'OpenPresale' ], [ 'relate_id', '=', $presale_data[ 'presale_id' ] ] ]);
  213. $cron->deleteCron([ [ 'event', '=', 'ClosePresale' ], [ 'relate_id', '=', $presale_data[ 'presale_id' ] ] ]);
  214. $cron->addCron(1, 0, "预售活动开启", "OpenPresale", $presale_data[ 'start_time' ], $presale_data[ 'presale_id' ]);
  215. $cron->addCron(1, 0, "预售活动关闭", "ClosePresale", $presale_data[ 'end_time' ], $presale_data[ 'presale_id' ]);
  216. }
  217. model('promotion_presale')->commit();
  218. return $this->success();
  219. } catch (\Exception $e) {
  220. model('promotion_presale')->rollback();
  221. return $this->error('', $e->getMessage());
  222. }
  223. }
  224. /**
  225. * 增加预售组人数及购买人数
  226. * @param array $data
  227. * @param array $condition
  228. * @return array
  229. */
  230. public function editPresaleNum($data = [], $condition = [])
  231. {
  232. $res = model('promotion_presale')->update($data, $condition);
  233. return $this->success($res);
  234. }
  235. /**
  236. * 删除预售活动
  237. * @param $presale_id
  238. * @param $site_id
  239. * @return array|\multitype
  240. */
  241. public function deletePresale($presale_id, $site_id)
  242. {
  243. //预售信息
  244. $presale_info = model('promotion_presale')->getInfo([ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ], 'status');
  245. if ($presale_info) {
  246. if ($presale_info[ 'status' ] != 1) {
  247. $res = model('promotion_presale')->delete([ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ]);
  248. if ($res) {
  249. //删除商品
  250. model('promotion_presale_goods')->delete([ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ]);
  251. $cron = new Cron();
  252. $cron->deleteCron([ [ 'event', '=', 'OpenPresale' ], [ 'relate_id', '=', $presale_id ] ]);
  253. $cron->deleteCron([ [ 'event', '=', 'ClosePresale' ], [ 'relate_id', '=', $presale_id ] ]);
  254. }
  255. return $this->success($res);
  256. } else {
  257. return $this->error('', '预售活动进行中,请先关闭该活动');
  258. }
  259. } else {
  260. return $this->error('', '预售活动不存在');
  261. }
  262. }
  263. /**
  264. * 关闭预售活动
  265. * @param $presale_id
  266. * @param $site_id
  267. * @return array
  268. */
  269. public function finishPresale($presale_id, $site_id)
  270. {
  271. //预售信息
  272. $presale_info = model('promotion_presale')->getInfo([ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ], 'status,goods_id');
  273. if (!empty($presale_info)) {
  274. if ($presale_info[ 'status' ] != 3) {
  275. $res = model('promotion_presale')->update([ 'status' => 3, 'status_name' => $this->status[ 3 ] ], [ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ]);
  276. $cron = new Cron();
  277. $cron->deleteCron([ [ 'event', '=', 'OpenPresale' ], [ 'relate_id', '=', $presale_id ] ]);
  278. $cron->deleteCron([ [ 'event', '=', 'ClosePresale' ], [ 'relate_id', '=', $presale_id ] ]);
  279. $goods = new Goods();
  280. $goods->modifyPromotionAddon($presale_info[ 'goods_id' ], [ 'presale' => $presale_id ], true);
  281. $presale_order = new PresaleOrderCommon();
  282. $presale_order->depositPresaleOrderClose([ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ]);
  283. return $this->success($res);
  284. } else {
  285. $this->error('', '该预售活动已关闭');
  286. }
  287. } else {
  288. $this->error('', '该预售活动不存在');
  289. }
  290. }
  291. /**
  292. * 获取预售信息
  293. * @param array $condition
  294. * @param string $field
  295. * @return array
  296. */
  297. public function getPresaleInfo($condition = [], $field = '*')
  298. {
  299. $presale_info = model("promotion_presale")->getInfo($condition, $field);
  300. return $this->success($presale_info);
  301. }
  302. /**
  303. * 获取预售详细信息
  304. * @param $presale_id
  305. * @param $site_id
  306. * @return array
  307. */
  308. public function getPresaleDetail($presale_id, $site_id)
  309. {
  310. //预售信息
  311. $alias = 'p';
  312. $join = [
  313. [
  314. 'goods g',
  315. 'g.goods_id = p.goods_id',
  316. 'inner'
  317. ]
  318. ];
  319. $presale_info = model("promotion_presale")->getInfo(
  320. [
  321. [ 'p.presale_id', '=', $presale_id ], [ 'p.site_id', '=', $site_id ],
  322. [ 'g.goods_state', '=', 1 ], [ 'g.is_delete', '=', 0 ]
  323. ], 'p.*', $alias, $join
  324. );
  325. if (!empty($presale_info)) {
  326. //商品sku信息
  327. $goods_list = model('goods_sku')->getList(
  328. [ [ 'goods_id', '=', $presale_info[ 'goods_id' ] ] ],
  329. 'goods_id,sku_id,sku_name,price,sku_images,stock,sku_image'
  330. );
  331. foreach ($goods_list as $k => $v) {
  332. $v[ 'stock' ] = numberFormat($v[ 'stock' ]);
  333. $presale_goods = model('promotion_presale_goods')->getInfo(
  334. [ [ 'presale_id', '=', $presale_id ], [ 'sku_id', '=', $v[ 'sku_id' ] ] ],
  335. 'presale_stock,presale_deposit,presale_price'
  336. );
  337. if (empty($presale_goods)) {
  338. $presale_goods = [
  339. 'presale_stock' => 0,
  340. 'presale_deposit' => 0,
  341. 'presale_price' => 0
  342. ];
  343. }
  344. $goods_list[ $k ] = array_merge($v, $presale_goods);
  345. }
  346. array_multisort(array_column($goods_list, 'presale_price'), SORT_DESC, $goods_list);
  347. $presale_info[ 'sku_list' ] = $goods_list;
  348. }
  349. return $this->success($presale_info);
  350. }
  351. /**
  352. * 获取预售详细信息
  353. * @param $presale_id
  354. * @param $site_id
  355. * @return array
  356. */
  357. public function getPresaleJoinGoodsList($presale_id, $site_id)
  358. {
  359. //预售信息
  360. $alias = 'p';
  361. $join = [
  362. [ 'goods g', 'g.goods_id = p.goods_id', 'inner' ]
  363. ];
  364. $presale_info = model("promotion_presale")->getInfo(
  365. [
  366. [ 'p.presale_id', '=', $presale_id ], [ 'p.site_id', '=', $site_id ],
  367. [ 'g.goods_state', '=', 1 ], [ 'g.is_delete', '=', 0 ]
  368. ], 'p.*', $alias, $join
  369. );
  370. if (!empty($presale_info)) {
  371. $goods_list = model('promotion_presale_goods')->getList(
  372. [ [ 'ppg.presale_id', '=', $presale_info[ 'presale_id' ] ] ],
  373. 'ppg.presale_stock,ppg.presale_deposit,ppg.presale_price,sku.sku_id,sku.sku_name,sku.price,sku.sku_image,sku.stock',
  374. '', 'ppg', [ [ 'goods_sku sku', 'sku.sku_id = ppg.sku_id', 'inner' ] ]
  375. );
  376. foreach ($goods_list as $k => $v) {
  377. $goods_list[ $k ][ 'stock' ] = numberFormat($goods_list[ $k ][ 'stock' ]);
  378. }
  379. $presale_info[ 'sku_list' ] = $goods_list;
  380. }
  381. return $this->success($presale_info);
  382. }
  383. /**
  384. * 预售商品详情
  385. * @param array $condition
  386. * @param string $field
  387. * @return array
  388. */
  389. public function getPresaleGoodsDetail($condition = [], $field = '')
  390. {
  391. $alias = 'ppg';
  392. if (empty($field)) {
  393. $field = 'ppg.id,ppg.presale_id,ppg.goods_id,ppg.sku_id,ppg.presale_stock,ppg.presale_stock as stock,ppg.presale_deposit,ppg.presale_price,(pp.sale_num + g.virtual_sale) as sale_num,pp.presale_name,
  394. pp.presale_num,pp.start_time,pp.end_time,pp.pay_start_time,pp.pay_end_time,pp.deliver_type,pp.deliver_time,sku.site_id,sku.sku_name,sku.sku_spec_format,sku.price,sku.promotion_type,pp.remark,
  395. sku.click_num,(g.sale_num + g.virtual_sale) as goods_sale_num,sku.collect_num,sku.sku_image,sku.sku_images,sku.site_id,sku.goods_content,sku.goods_state,sku.is_virtual,
  396. sku.is_free_shipping,sku.goods_spec_format,sku.goods_attr_format,sku.introduction,sku.unit,sku.video_url,sku.evaluate,sku.goods_service_ids,sku.support_trade_type,
  397. g.goods_image,g.goods_stock,g.goods_name,sku.qr_id,g.stock_show,g.sale_show,g.label_name';
  398. }
  399. $join = [
  400. [ 'goods_sku sku', 'ppg.sku_id = sku.sku_id', 'inner' ],
  401. [ 'goods g', 'g.goods_id = sku.goods_id', 'inner' ],
  402. [ 'promotion_presale pp', 'ppg.presale_id = pp.presale_id', 'inner' ],
  403. ];
  404. $presale_goods_info = model('promotion_presale_goods')->getInfo($condition, $field, $alias, $join);
  405. if (!empty($presale_goods_info)) {
  406. if (isset($presale_goods_info[ 'goods_sale_num' ])) {
  407. $presale_goods_info[ 'goods_sale_num' ] = numberFormat($presale_goods_info[ 'goods_sale_num' ]);
  408. }
  409. if (isset($presale_goods_info[ 'goods_stock' ])) {
  410. $presale_goods_info[ 'goods_stock' ] = numberFormat($presale_goods_info[ 'goods_stock' ]);
  411. }
  412. }
  413. return $this->success($presale_goods_info);
  414. }
  415. /**
  416. * 预售商品详情
  417. * @param array $condition
  418. * @return array
  419. */
  420. public function getPresaleGoodsSkuList($condition = [])
  421. {
  422. $alias = 'ppg';
  423. $field = 'ppg.id,ppg.presale_id,ppg.sku_id,ppg.presale_stock,ppg.presale_stock as stock,ppg.presale_deposit,ppg.presale_price,sku.sku_name,
  424. sku.sku_spec_format,sku.price,sku.sku_image,sku.sku_images,sku.goods_spec_format,g.goods_image';
  425. $join = [
  426. [ 'promotion_presale pp', 'ppg.presale_id = pp.presale_id', 'inner' ],
  427. [ 'goods_sku sku', 'ppg.sku_id = sku.sku_id', 'inner' ],
  428. [ 'goods g', 'g.goods_id = sku.goods_id', 'inner' ],
  429. ];
  430. $list = model('promotion_presale_goods')->getList($condition, $field, 'ppg.id asc', $alias, $join);
  431. return $this->success($list);
  432. }
  433. /**
  434. * 获取预售列表
  435. * @param array $condition
  436. * @param string $field
  437. * @param string $order
  438. * @param string $limit
  439. */
  440. public function getPresaleList($condition = [], $field = '', $order = '', $limit = null)
  441. {
  442. $alias = 'pp';
  443. if (empty($field)) {
  444. $field = 'pp.*,g.price,g.goods_name,g.goods_image,(g.sale_num + g.virtual_sale) as goods_sale_num,g.unit,g.goods_stock,g.recommend_way';
  445. }
  446. $join = [
  447. [ 'goods g', 'pp.goods_id = g.goods_id', 'inner' ]
  448. ];
  449. $list = model('promotion_presale')->getList($condition, $field, $order, $alias, $join, '', $limit);
  450. foreach ($list as $k => $v) {
  451. if (isset($v[ 'goods_sale_num' ])) {
  452. $list[ $k ][ 'goods_sale_num' ] = numberFormat($list[ $k ][ 'goods_sale_num' ]);
  453. }
  454. if (isset($v[ 'goods_stock' ])) {
  455. $list[ $k ][ 'goods_stock' ] = numberFormat($list[ $k ][ 'goods_stock' ]);
  456. }
  457. }
  458. return $this->success($list);
  459. }
  460. /**
  461. * 获取预售分页列表
  462. * @param array $condition
  463. * @param number $page
  464. * @param string $page_size
  465. * @param string $order
  466. * @param string $field
  467. */
  468. public function getPresalePageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '')
  469. {
  470. $field = 'p.*,g.goods_name,g.goods_image,g.price';
  471. $alias = 'p';
  472. $join = [
  473. [
  474. 'goods g',
  475. 'p.goods_id = g.goods_id',
  476. 'inner'
  477. ]
  478. ];
  479. $list = model('promotion_presale')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
  480. return $this->success($list);
  481. }
  482. /**
  483. * 获取预售商品列表
  484. * @param $presale_id
  485. * @param $site_id
  486. * @return array
  487. */
  488. public function getPresaleGoodsList($presale_id, $site_id)
  489. {
  490. $field = 'pbg.*,sku.sku_name,sku.price,sku.sku_image,sku.stock';
  491. $alias = 'pbg';
  492. $join = [
  493. [
  494. 'goods g',
  495. 'g.goods_id = pbg.goods_id',
  496. 'inner'
  497. ],
  498. [
  499. 'goods_sku sku',
  500. 'sku.sku_id = pbg.sku_id',
  501. 'inner'
  502. ]
  503. ];
  504. $condition = [
  505. [ 'pbg.presale_id', '=', $presale_id ], [ 'pbg.site_id', '=', $site_id ],
  506. [ 'g.is_delete', '=', 0 ], [ 'g.goods_state', '=', 1 ]
  507. ];
  508. $list = model('promotion_presale_goods')->getList($condition, $field, '', $alias, $join);
  509. foreach ($list as $k => $v) {
  510. $list[ $k ][ 'stock' ] = numberFormat($list[ $k ][ 'stock' ]);
  511. }
  512. return $this->success($list);
  513. }
  514. /**
  515. * 获取预售商品分页列表
  516. * @param array $condition
  517. * @param number $page
  518. * @param string $page_size
  519. * @param string $order
  520. * @param string $field
  521. */
  522. public function getPresaleGoodsPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'pp.presale_id desc', $field = '')
  523. {
  524. $alias = 'pp';
  525. if (empty($field)) {
  526. $field = 'pp.*,g.price,g.goods_name,g.goods_image,(g.sale_num + g.virtual_sale) as goods_sale_num,g.unit,g.goods_stock,g.recommend_way';
  527. }
  528. $join = [
  529. [ 'goods g', 'pp.goods_id = g.goods_id', 'inner' ]
  530. ];
  531. $res = model('promotion_presale')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
  532. foreach ($res[ 'list' ] as $k => $v) {
  533. if (isset($v[ 'goods_sale_num' ])) {
  534. $res[ 'list' ][ $k ][ 'goods_sale_num' ] = numberFormat($res[ 'list' ][ $k ][ 'goods_sale_num' ]);
  535. }
  536. if (isset($v[ 'goods_stock' ])) {
  537. $res[ 'list' ][ $k ][ 'goods_stock' ] = numberFormat($res[ 'list' ][ $k ][ 'goods_stock' ]);
  538. }
  539. }
  540. return $this->success($res);
  541. }
  542. /**
  543. * 开启预售活动
  544. * @param $presale_id
  545. * @return array|\multitype
  546. */
  547. public function cronOpenPresale($presale_id)
  548. {
  549. $presale_info = model('promotion_presale')->getInfo([ [ 'presale_id', '=', $presale_id ] ], 'status,goods_id');
  550. if (!empty($presale_info)) {
  551. if ($presale_info[ 'status' ] == 0) {
  552. $res = model('promotion_presale')->update([ 'status' => 1, 'status_name' => $this->status[ 1 ] ], [ [ 'presale_id', '=', $presale_id ] ]);
  553. $goods = new Goods();
  554. $goods->modifyPromotionAddon($presale_info[ 'goods_id' ], [ 'presale' => $presale_id ]);
  555. return $this->success($res);
  556. } else {
  557. return $this->error("", "预售活动已开启或者关闭");
  558. }
  559. } else {
  560. return $this->error("", "预售活动不存在");
  561. }
  562. }
  563. /**
  564. * 关闭预售活动
  565. * @param $presale_id
  566. * @return array|\multitype
  567. */
  568. public function cronClosePresale($presale_id)
  569. {
  570. $presale_info = model('promotion_presale')->getInfo([ [ 'presale_id', '=', $presale_id ] ], 'status,goods_id');
  571. if (!empty($presale_info)) {
  572. if ($presale_info[ 'status' ] == 1) {
  573. $res = model('promotion_presale')->update([ 'status' => 2, 'status_name' => $this->status[ 2 ] ], [ [ 'presale_id', '=', $presale_id ] ]);
  574. $goods = new Goods();
  575. $goods->modifyPromotionAddon($presale_info[ 'goods_id' ], [ 'presale' => $presale_id ], true);
  576. return $this->success($res);
  577. } else {
  578. return $this->error("", "该活动已结束");
  579. }
  580. } else {
  581. return $this->error("", "预售活动不存在");
  582. }
  583. }
  584. /**
  585. * 判断规格值是否禁用
  586. * @param $presale_id
  587. * @param $site_id
  588. * @param $goods
  589. * @return false|string
  590. */
  591. public function getGoodsSpecFormat($presale_id, $site_id, $goods_spec_format = '', $sku_id = 0)
  592. {
  593. //获取活动参与的商品sku_ids
  594. $sku_ids = model('promotion_presale_goods')->getColumn([ [ 'presale_id', '=', $presale_id ], [ 'site_id', '=', $site_id ] ], 'sku_id');
  595. $goods_model = new Goods();
  596. if ($sku_id == 0) {
  597. $res = $goods_model->getGoodsSpecFormat($sku_ids, $goods_spec_format);
  598. } else {
  599. $res = $goods_model->getEmptyGoodsSpecFormat($sku_ids, $sku_id);
  600. }
  601. return $res;
  602. }
  603. /**
  604. * 判断sku是否参与预售
  605. * @param $sku_id
  606. * @return array
  607. */
  608. public function isJoinPresaleBySkuId($sku_id)
  609. {
  610. $condition = [
  611. [ 'ppg.sku_id', '=', $sku_id ],
  612. [ 'pp.status', '=', 1 ],
  613. [ 'pp.end_time', '>=', time() ]
  614. ];
  615. $alias = 'ppg';
  616. $join = [
  617. [ 'promotion_presale pp', 'pp.presale_id = ppg.presale_id', 'inner' ]
  618. ];
  619. $info = model('promotion_presale_goods')->getInfo($condition, 'ppg.presale_id,ppg.sku_id', $alias, $join);
  620. if (empty($info)) {
  621. return $this->error();
  622. } else {
  623. return $this->success([ 'promotion_type' => 'presale', 'presale_id' => $info[ 'presale_id' ], 'sku_id' => $sku_id ]);
  624. }
  625. }
  626. /**
  627. * 获取会员已购该商品数
  628. * @param $goods_id
  629. * @param $member_id
  630. * @return float
  631. */
  632. public function getGoodsPurchasedNum($presale_id, $member_id)
  633. {
  634. $num = model("promotion_presale_order")->getSum([
  635. [ 'member_id', '=', $member_id ],
  636. [ 'presale_id', '=', $presale_id ],
  637. [ 'order_status', '<>', PresaleOrderCommon::ORDER_CLOSE ],
  638. [ 'refund_status', '<>', PresaleOrderRefund::REFUND_COMPLETE ]
  639. ], 'num');
  640. return $num;
  641. }
  642. /**
  643. * 获取预售订单数量
  644. * @param $condition
  645. * @param string $field
  646. * @return array
  647. */
  648. public function getPresaleOrderCount($condition, $field = '*')
  649. {
  650. $count = model("promotion_presale_order")->getCount($condition, $field);
  651. return $this->success($count);
  652. }
  653. /**
  654. * 查询预售商品数量
  655. * @param array $where
  656. * @param string $field
  657. * @param string $alias
  658. * @param null $join
  659. * @param null $group
  660. * @return array
  661. */
  662. public function getPresaleGoodsCount($where = [], $field = '*', $alias = 'a', $join = null, $group = null)
  663. {
  664. $count = model("promotion_presale_order")->getCount($where, $field, $alias, $join, $group);
  665. return $this->success($count);
  666. }
  667. /**
  668. * 生成预售二维码
  669. * @param $presale_id
  670. * @param string $name
  671. * @param string $type 类型 create创建 get获取
  672. * @return mixed|array
  673. */
  674. public function qrcode($presale_id, $name, $site_id, $type = 'create')
  675. {
  676. $data = [
  677. 'site_id' => $site_id,
  678. 'app_type' => "all", // all为全部
  679. 'type' => $type, // 类型 create创建 get获取
  680. 'data' => [
  681. 'id' => $presale_id
  682. ],
  683. 'page' => '/pages_promotion/presale/detail',
  684. 'qrcode_path' => 'upload/qrcode/presale',
  685. 'qrcode_name' => "presale_qrcode_" . $presale_id
  686. ];
  687. event('Qrcode', $data, true);
  688. $app_type_list = config('app_type');
  689. $path = [];
  690. foreach ($app_type_list as $k => $v) {
  691. switch ( $k ) {
  692. case 'h5':
  693. $wap_domain = getH5Domain();
  694. $path[ $k ][ 'status' ] = 1;
  695. $path[ $k ][ 'url' ] = $wap_domain . $data[ 'page' ] . '?id=' . $presale_id;
  696. $path[ $k ][ 'img' ] = "upload/qrcode/presale/presale_qrcode_" . $presale_id . "_" . $k . ".png";
  697. break;
  698. case 'weapp' :
  699. $config = new ConfigModel();
  700. $res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_CONFIG' ] ]);
  701. if (!empty($res[ 'data' ])) {
  702. if (empty($res[ 'data' ][ 'value' ][ 'qrcode' ])) {
  703. $path[ $k ][ 'status' ] = 2;
  704. $path[ $k ][ 'message' ] = '未配置微信小程序';
  705. } else {
  706. $path[ $k ][ 'status' ] = 1;
  707. $path[ $k ][ 'img' ] = $res[ 'data' ][ 'value' ][ 'qrcode' ];
  708. }
  709. } else {
  710. $path[ $k ][ 'status' ] = 2;
  711. $path[ $k ][ 'message' ] = '未配置微信小程序';
  712. }
  713. break;
  714. case 'wechat' :
  715. $config = new ConfigModel();
  716. $res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_CONFIG' ] ]);
  717. if (!empty($res[ 'data' ])) {
  718. if (empty($res[ 'data' ][ 'value' ][ 'qrcode' ])) {
  719. $path[ $k ][ 'status' ] = 2;
  720. $path[ $k ][ 'message' ] = '未配置微信公众号';
  721. } else {
  722. $path[ $k ][ 'status' ] = 1;
  723. $path[ $k ][ 'img' ] = $res[ 'data' ][ 'value' ][ 'qrcode' ];
  724. }
  725. } else {
  726. $path[ $k ][ 'status' ] = 2;
  727. $path[ $k ][ 'message' ] = '未配置微信公众号';
  728. }
  729. break;
  730. }
  731. }
  732. $return = [
  733. 'path' => $path,
  734. 'name' => $name,
  735. ];
  736. return $this->success($return);
  737. }
  738. /**
  739. * 商品用到的分类
  740. * @param $condition
  741. * @return array
  742. */
  743. public function getGoodsCategoryIds($condition)
  744. {
  745. $cache_name = "shop_presale_goods_category_" . md5(json_encode($condition));
  746. $cache_time = 60;
  747. $cache_res = Cache::get($cache_name);
  748. if (empty($cache_res) || time() - $cache_res[ 'time' ] > $cache_time) {
  749. $list = Db::name('promotion_presale')
  750. ->alias('pp')
  751. ->join('goods g', 'pp.goods_id = g.goods_id', 'inner')
  752. ->where($condition)
  753. ->group('g.category_id')
  754. ->column('g.category_id');
  755. $category_ids = trim(join('0', $list), ',');
  756. $category_id_arr = array_unique(explode(',', $category_ids));
  757. Cache::set($cache_name, [ 'time' => time(), 'data' => $category_id_arr ]);
  758. } else {
  759. $category_id_arr = $cache_res[ 'data' ];
  760. }
  761. return $this->success($category_id_arr);
  762. }
  763. public function urlQrcode($page, $qrcode_param, $promotion_type, $site_id)
  764. {
  765. $params = [
  766. 'site_id' => $site_id,
  767. 'data' => $qrcode_param,
  768. 'page' => $page,
  769. 'promotion_type' => $promotion_type,
  770. 'h5_path' => $page . '?id=' . $qrcode_param[ 'id' ],
  771. 'qrcode_path' => 'upload/qrcode/presale',
  772. 'qrcode_name' => 'presale_qrcode_' . $promotion_type . '_' . $qrcode_param[ 'id' ] . '_' . $site_id
  773. ];
  774. $solitaire = event('ExtensionInformation', $params, true);
  775. return $this->success($solitaire);
  776. }
  777. }