StoreSeckill.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /**
  3. *
  4. * @author: xaboy<365615158@qq.com>
  5. * @day: 2017/12/18
  6. */
  7. namespace app\models\store;
  8. use app\admin\model\ump\StoreSeckillTime;
  9. use crmeb\basic\BaseModel;
  10. use crmeb\services\GroupDataService;
  11. use app\admin\model\store\StoreProductAttrValue;
  12. use app\models\store\StoreProduct;
  13. /**
  14. * TODO 秒杀产品Model
  15. * Class StoreSeckill
  16. * @package app\models\store
  17. */
  18. class StoreSeckill extends BaseModel
  19. {
  20. /**
  21. * 数据表主键
  22. * @var string
  23. */
  24. protected $pk = 'id';
  25. /**
  26. * 模型名称
  27. * @var string
  28. */
  29. protected $name = 'store_seckill';
  30. protected function getImagesAttr($value)
  31. {
  32. return json_decode($value, true) ?: [];
  33. }
  34. public function getDescriptionAttr($value)
  35. {
  36. return htmlspecialchars_decode($value);
  37. }
  38. public static function getSeckillCount()
  39. {
  40. $seckillTime = sys_data('routine_seckill_time') ?: [];//秒杀时间段
  41. $timeInfo = ['time' => 0, 'continued' => 0];
  42. foreach ($seckillTime as $key => $value) {
  43. $currentHour = date('H');
  44. $activityEndHour = bcadd((int)$value['time'], (int)$value['continued'], 0);
  45. if ($currentHour >= (int)$value['time'] && $currentHour < $activityEndHour && $activityEndHour < 24) {
  46. $timeInfo = $value;
  47. break;
  48. }
  49. }
  50. if ($timeInfo['time'] == 0) return 0;
  51. $activityEndHour = bcadd((int)$timeInfo['time'], (int)$timeInfo['continued'], 0);
  52. $startTime = bcadd(strtotime(date('Y-m-d')), bcmul($timeInfo['time'], 3600, 0));
  53. $stopTime = bcadd(strtotime(date('Y-m-d')), bcmul($activityEndHour, 3600, 0));
  54. return self::where('is_del', 0)->where('status', 1)->where('start_time', '<=', $startTime)->where('stop_time', '>=', $stopTime)->count();
  55. }
  56. /**
  57. * 获取秒杀列表
  58. * @param $time
  59. * @param int $page
  60. * @param int $limit
  61. * @return array
  62. * @throws \think\db\exception\DataNotFoundException
  63. * @throws \think\db\exception\DbException
  64. * @throws \think\db\exception\ModelNotFoundException
  65. */
  66. public static function seckillList($time, $page = 0, $limit = 20)
  67. {
  68. if ($page) $list = StoreSeckill::alias('n')->join('store_product c', 'c.id=n.product_id')->where('c.is_show', 1)->where('c.is_del', 0)->where('n.is_del', 0)->where('n.status', 1)->where('n.start_time', '<=', time())->where('n.stop_time', '>=', time() - 86400)->where('n.time_id', $time)->field('n.*')->order('n.sort desc')->page($page, $limit)->select();
  69. else $list = StoreSeckill::alias('n')->join('store_product c', 'c.id=n.product_id')->where('c.is_show', 1)->where('c.is_del', 0)->where('n.is_del', 0)->where('n.status', 1)->where('n.start_time', '<=', time())->where('n.stop_time', '>=', time() - 86400)->where('n.time_id', $time)->field('n.*')->order('sort desc')->select();
  70. if ($list) return $list->hidden(['cost', 'add_time', 'is_del'])->toArray();
  71. return [];
  72. }
  73. /**
  74. * 获取所有秒杀产品
  75. * @param string $field
  76. * @return array
  77. */
  78. public static function getListAll($offset = 0, $limit = 10, $field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock,sales')
  79. {
  80. $time = time();
  81. $model = self::where('is_del', 0)->where('status', 1)->where('stock', '>', 0)->field($field)
  82. ->where('start_time', '<', $time)->where('stop_time', '>', $time)->order('sort DESC,add_time DESC');
  83. $model = $model->limit($offset, $limit);
  84. $list = $model->select();
  85. if ($list) return $list->toArray();
  86. else return [];
  87. }
  88. /**
  89. * 获取热门推荐的秒杀产品
  90. * @param int $limit
  91. * @param string $field
  92. * @return array
  93. */
  94. public static function getHotList($limit = 0, $field = 'id,product_id,image,title,price,ot_price,start_time,stop_time,stock')
  95. {
  96. $time = time();
  97. $model = self::where('is_hot', 1)->where('is_del', 0)->where('status', 1)->where('stock', '>', 0)->field($field)
  98. ->where('start_time', '<', $time)->where('stop_time', '>', $time)->order('sort DESC,add_time DESC');
  99. if ($limit) $model->limit($limit);
  100. $list = $model->select();
  101. if ($list) return $list->toArray();
  102. else return [];
  103. }
  104. /**
  105. * 获取一条秒杀产品
  106. * @param $id
  107. * @param string $field
  108. * @return array|false|\PDOStatement|string|\think\Model
  109. */
  110. public static function getValidProduct($id, $field = '*')
  111. {
  112. $time = time();
  113. $info = self::alias('n')->join('store_product c', 'c.id=n.product_id')->where('n.id', $id)->where('c.is_show', 1)->where('c.is_del', 0)->where('n.is_del', 0)->where('n.status', 1)->where('n.start_time', '<', $time)->where('n.stop_time', '>', $time - 86400)->field('n.*,SUM(c.sales+c.ficti) as total')->find();
  114. if ($info['id']) {
  115. return $info;
  116. } else {
  117. return [];
  118. }
  119. }
  120. /**
  121. * 获取秒杀是否有开启
  122. * @return bool
  123. */
  124. public static function getSeckillContStatus()
  125. {
  126. $time = time();
  127. $count = self::where('is_del', 0)->where('status', 1)->where('start_time', '<', $time)->where('stop_time', '>', $time)->count();
  128. return $count ? true : false;
  129. }
  130. public static function initFailSeckill()
  131. {
  132. self::where('is_hot', 1)->where('is_del', 0)->where('status', '<>', 1)->where('stop_time', '<', time())->update(['status' => '-1']);
  133. }
  134. public static function idBySimilaritySeckill($id, $limit = 4, $field = '*')
  135. {
  136. $time = time();
  137. $list = [];
  138. $productId = self::where('id', $id)->value('product_id');
  139. if ($productId) {
  140. $list = array_merge($list, self::where('product_id', $productId)->where('id', '<>', $id)
  141. ->where('is_del', 0)->where('status', 1)->where('stock', '>', 0)
  142. ->field($field)->where('start_time', '<', $time)->where('stop_time', '>', $time)
  143. ->order('sort DESC,add_time DESC')->limit($limit)->select()->toArray());
  144. }
  145. $limit = $limit - count($list);
  146. if ($limit) {
  147. $list = array_merge($list, self::getHotList($limit, $field));
  148. }
  149. return $list;
  150. }
  151. /** 获取秒杀产品库存
  152. * @param $id
  153. * @return mixed
  154. */
  155. public static function getProductStock($id)
  156. {
  157. return self::where('id', $id)->value('stock');
  158. }
  159. /**
  160. * 获取字段值
  161. * @param $id
  162. * @param string $field
  163. * @return mixed
  164. */
  165. public static function getProductField($id, $field = 'title')
  166. {
  167. return self::where('id', $id)->value($field);
  168. }
  169. /**
  170. * 修改秒杀库存
  171. * @param int $num
  172. * @param int $seckillId
  173. * @return bool
  174. */
  175. public static function decSeckillStock($num = 0, $seckillId = 0, $unique = '')
  176. {
  177. $product_id = self::where('id', $seckillId)->value('product_id');
  178. if ($unique) {
  179. $res = false !== StoreProductAttrValue::decProductAttrStock($seckillId, $unique, $num, 1);
  180. $res = $res && self::where('id', $seckillId)->dec('stock', $num)->inc('sales', $num)->update();
  181. $sku = StoreProductAttrValue::where('product_id', $seckillId)->where('unique', $unique)->where('type', 1)->value('suk');
  182. $res = $res && StoreProductAttrValue::where('product_id', $product_id)->where('suk', $sku)->where('type', 0)->dec('stock', $num)->inc('sales', $num)->update();
  183. } else {
  184. $res = false !== self::where('id', $seckillId)->dec('stock', $num)->inc('sales', $num)->update();
  185. }
  186. $res = $res && StoreProduct::where('id', $product_id)->dec('stock', $num)->inc('sales', $num)->update();
  187. return $res;
  188. }
  189. /**
  190. * 增加库存较少销量
  191. * @param int $num
  192. * @param int $seckillId
  193. * @return bool
  194. */
  195. public static function incSeckillStock($num = 0, $seckillId = 0)
  196. {
  197. $seckill = self::where('id', $seckillId)->field(['stock', 'sales'])->find();
  198. if (!$seckill) return true;
  199. if ($seckill->sales > 0) $seckill->sales = bcsub($seckill->sales, $num, 0);
  200. if ($seckill->sales < 0) $seckill->sales = 0;
  201. $seckill->stock = bcadd($seckill->stock, $num, 0);
  202. return $seckill->save();
  203. }
  204. }