StoreSeckill.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <?php
  2. namespace app\admin\model\ump;
  3. use app\admin\model\order\StoreOrder;
  4. use app\admin\model\store\StoreProductRelation;
  5. use app\admin\model\system\SystemGroupData;
  6. use crmeb\traits\ModelTrait;
  7. use crmeb\basic\BaseModel;
  8. use app\admin\model\store\StoreProduct;
  9. use crmeb\services\PHPExcelService;
  10. /**
  11. * Class StoreSeckill
  12. * @package app\admin\model\store
  13. */
  14. class StoreSeckill extends BaseModel
  15. {
  16. /**
  17. * 数据表主键
  18. * @var string
  19. */
  20. protected $pk = 'id';
  21. /**
  22. * 模型名称
  23. * @var string
  24. */
  25. protected $name = 'store_seckill';
  26. use ModelTrait;
  27. public function getDescriptionAttr($value)
  28. {
  29. return htmlspecialchars_decode($value);
  30. }
  31. /**
  32. * 秒杀产品过滤条件
  33. * @param $model
  34. * @param $type
  35. * @return mixed
  36. */
  37. public static function setWhereType($model, $type)
  38. {
  39. switch ($type) {
  40. case 1:
  41. $data = ['status' => 0, 'is_del' => 0];
  42. break;
  43. case 2:
  44. $data = ['status' => 1, 'is_del' => 0];
  45. break;
  46. case 3:
  47. $data = ['status' => 1, 'is_del' => 0, 'stock' => 0];
  48. break;
  49. case 4:
  50. $data = ['status' => 1, 'is_del' => 0, 'stock' => ['elt', 1]];
  51. break;
  52. case 5:
  53. $data = ['is_del' => 1];
  54. break;
  55. }
  56. if (isset($data)) $model = $model->where($data);
  57. return $model;
  58. }
  59. /**
  60. * 秒杀产品数量 图标展示
  61. * @param $type
  62. * @param $data
  63. * @return array
  64. */
  65. public static function getChatrdata($type, $data)
  66. {
  67. $legdata = ['销量', '数量', '点赞', '收藏'];
  68. $model = self::setWhereType(self::order('id desc'), $type);
  69. $list = self::getModelTime(compact('data'), $model)
  70. ->field('FROM_UNIXTIME(add_time,"%Y-%c-%d") as un_time,count(id) as count,sum(sales) as sales')
  71. ->group('un_time')
  72. ->distinct(true)
  73. ->select()
  74. ->each(function ($item) use ($data) {
  75. $item['collect'] = self::getModelTime(compact('data'), new StoreProductRelation)->where('type', 'collect')->count();
  76. $item['like'] = self::getModelTime(compact('data'), new StoreProductRelation())->where('type', 'like')->count();
  77. })->toArray();
  78. $chatrList = [];
  79. $datetime = [];
  80. $data_item = [];
  81. $itemList = [0 => [], 1 => [], 2 => [], 3 => []];
  82. foreach ($list as $item) {
  83. $itemList[0][] = $item['sales'];
  84. $itemList[1][] = $item['count'];
  85. $itemList[2][] = $item['like'];
  86. $itemList[3][] = $item['collect'];
  87. array_push($datetime, $item['un_time']);
  88. }
  89. foreach ($legdata as $key => $leg) {
  90. $data_item['name'] = $leg;
  91. $data_item['type'] = 'line';
  92. $data_item['data'] = $itemList[$key];
  93. $chatrList[] = $data_item;
  94. unset($data_item);
  95. }
  96. unset($leg);
  97. $badge = self::getbadge(compact('data'), $type);
  98. $count = self::setWhereType(self::getModelTime(compact('data'), new self()), $type)->count();
  99. return compact('datetime', 'chatrList', 'legdata', 'badge', 'count');
  100. }
  101. /**
  102. * 秒杀产品数量
  103. * @param $where
  104. * @param $type
  105. * @return array
  106. */
  107. public static function getbadge($where, $type)
  108. {
  109. $StoreOrderModel = new StoreOrder();
  110. $replenishment_num = sys_config('replenishment_num');
  111. $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20;
  112. $stock1 = self::getModelTime($where, new self())->where('stock', '<', $replenishment_num)->column('stock', 'id');
  113. $sum_stock = self::where('stock', '<', $replenishment_num)->column('stock', 'id');
  114. $stk = [];
  115. foreach ($stock1 as $item) {
  116. $stk[] = $replenishment_num - $item;
  117. }
  118. $lack = array_sum($stk);
  119. $sum = [];
  120. foreach ($sum_stock as $val) {
  121. $sum[] = $replenishment_num - $val;
  122. }
  123. return [
  124. [
  125. 'name' => '商品种类',
  126. 'field' => '件',
  127. 'count' => self::setWhereType(new self(), $type)->where('add_time', '<', mktime(0, 0, 0, date('m'), date('d'), date('Y')))->count(),
  128. 'content' => '商品种类总数',
  129. 'background_color' => 'layui-bg-blue',
  130. 'sum' => self::count(),
  131. 'class' => 'fa fa fa-ioxhost',
  132. ],
  133. [
  134. 'name' => '新增商品',
  135. 'field' => '件',
  136. 'count' => self::setWhereType(self::getModelTime($where, new self), $type)->sum('stock'),
  137. 'content' => '新增商品总数',
  138. 'background_color' => 'layui-bg-cyan',
  139. 'sum' => self::where('status', 1)->sum('stock'),
  140. 'class' => 'fa fa-line-chart',
  141. ],
  142. [
  143. 'name' => '秒杀成功商品件数',
  144. 'field' => '件',
  145. 'count' => self::getModelTime($where, $StoreOrderModel)->where('seckill_id', '<>', 0)->sum('total_num'),
  146. 'content' => '秒杀成功商品总件数',
  147. 'background_color' => 'layui-bg-green',
  148. 'sum' => $StoreOrderModel->where('seckill_id', '<>', 0)->sum('total_num'),
  149. 'class' => 'fa fa-bar-chart',
  150. ],
  151. [
  152. 'name' => '缺货商品',
  153. 'field' => '件',
  154. 'count' => $lack,
  155. 'content' => '总商品数量',
  156. 'background_color' => 'layui-bg-orange',
  157. 'sum' => array_sum($sum),
  158. 'class' => 'fa fa-cube',
  159. ],
  160. ];
  161. }
  162. /**
  163. * 销量排行 top 10
  164. * layui-bg-red 红 layui-bg-orange 黄 layui-bg-green 绿 layui-bg-blue 蓝 layui-bg-cyan 黑
  165. */
  166. public static function getMaxList($where)
  167. {
  168. $classs = ['layui-bg-red', 'layui-bg-orange', 'layui-bg-green', 'layui-bg-blue', 'layui-bg-cyan'];
  169. $model = StoreOrder::alias('a')->join('store_seckill b', 'b.id=a.seckill_id')->where('a.paid', 1);
  170. $list = self::getModelTime($where, $model, 'a.add_time')->group('a.seckill_id')->order('p_count desc')->limit(10)
  171. ->field(['count(a.seckill_id) as p_count', 'b.title as store_name', 'sum(b.price) as sum_price'])->select();
  172. if (count($list)) $list = $list->toArray();
  173. $maxList = [];
  174. $sum_count = 0;
  175. $sum_price = 0;
  176. foreach ($list as $item) {
  177. $sum_count += $item['p_count'];
  178. $sum_price = bcadd($sum_price, $item['sum_price'], 2);
  179. }
  180. unset($item);
  181. foreach ($list as $key => &$item) {
  182. $item['w'] = bcdiv($item['p_count'], $sum_count, 2) * 100;
  183. $item['class'] = isset($classs[$key]) ? $classs[$key] : (isset($classs[$key - count($classs)]) ? $classs[$key - count($classs)] : '');
  184. $item['store_name'] = self::getSubstrUTf8($item['store_name']);
  185. }
  186. $maxList['sum_count'] = $sum_count;
  187. $maxList['sum_price'] = $sum_price;
  188. $maxList['list'] = $list;
  189. return $maxList;
  190. }
  191. /**
  192. * 获取秒杀利润
  193. * @param $where
  194. * @return array
  195. */
  196. public static function ProfityTop10($where)
  197. {
  198. $classs = ['layui-bg-red', 'layui-bg-orange', 'layui-bg-green', 'layui-bg-blue', 'layui-bg-cyan'];
  199. $model = StoreOrder::alias('a')->join('store_seckill b', 'b.id = a.seckill_id')->where('a.paid', 1);
  200. $list = self::getModelTime($where, $model, 'a.add_time')->group('a.seckill_id')->order('profity desc')->limit(10)
  201. ->field(['count(a.seckill_id) as p_count', 'b.title as store_name', 'sum(b.price) as sum_price', '(b.price-b.cost) as profity'])
  202. ->select();
  203. if (count($list)) $list = $list->toArray();
  204. $maxList = [];
  205. $sum_count = 0;
  206. $sum_price = 0;
  207. foreach ($list as $item) {
  208. $sum_count += $item['p_count'];
  209. $sum_price = bcadd($sum_price, $item['sum_price'], 2);
  210. }
  211. foreach ($list as $key => &$item) {
  212. $item['w'] = bcdiv($item['sum_price'], $sum_price, 2) * 100;
  213. $item['class'] = isset($classs[$key]) ? $classs[$key] : (isset($classs[$key - count($classs)]) ? $classs[$key - count($classs)] : '');
  214. $item['store_name'] = self::getSubstrUTf8($item['store_name'], 30);
  215. }
  216. $maxList['sum_count'] = $sum_count;
  217. $maxList['sum_price'] = $sum_price;
  218. $maxList['list'] = $list;
  219. return $maxList;
  220. }
  221. /**
  222. * 获取秒杀缺货
  223. * @param $where
  224. * @return array
  225. */
  226. public static function getLackList($where)
  227. {
  228. $replenishment_num = sys_config('replenishment_num');
  229. $replenishment_num = $replenishment_num > 0 ? $replenishment_num : 20;
  230. $list = self::where('stock', '<', $replenishment_num)->field(['id', 'title as store_name', 'stock', 'price'])->page((int)$where['page'], (int)$where['limit'])->order('stock asc')->select();
  231. if (count($list)) $list = $list->toArray();
  232. $count = self::where('stock', '<', $replenishment_num)->count();
  233. return ['count' => $count, 'data' => $list];
  234. }
  235. /**
  236. * 秒杀产品评价
  237. * @param array $where
  238. * @return array
  239. */
  240. public static function getNegativeList($where = array())
  241. {
  242. $replenishment_num = 3;
  243. return [];
  244. }
  245. /**
  246. * 秒杀产品退货
  247. * @param array $where
  248. * @return mixed
  249. */
  250. public static function getBargainRefundList($where = array())
  251. {
  252. $model = StoreOrder::alias('a')->join('store_seckill b', 'b.id=a.seckill_id');
  253. $list = self::getModelTime($where, $model, 'a.add_time')->where('a.refund_status', '<>', 0)->group('a.seckill_id')->order('count desc')->page((int)$where['page'], (int)$where['limit'])
  254. ->field(['count(a.seckill_id) as count', 'b.title as store_name', 'sum(b.price) as sum_price'])->select();
  255. if (count($list)) $list = $list->toArray();
  256. return $list;
  257. }
  258. /**
  259. * @param $where
  260. * @return array
  261. */
  262. public static function systemPage($where)
  263. {
  264. $model = new self;
  265. $model = $model->alias('s');
  266. // $model = $model->join('StoreProduct p','p.id=s.product_id');
  267. if ($where['status'] != '') $model = $model->where('s.status', $where['status']);
  268. if ($where['store_name'] != '') $model = $model->where('s.title|s.id', 'LIKE', "%$where[store_name]%");
  269. $model = $model->page(bcmul($where['page'], $where['limit'], 0), $where['limit']);
  270. $model = $model->order('s.id desc');
  271. $model = $model->where('s.is_del', 0);
  272. return self::page($model, function ($item) {
  273. $item['store_name'] = StoreProduct::where('id', $item['product_id'])->value('store_name');
  274. if ($item['status']) {
  275. if ($item['start_time'] > time())
  276. $item['start_name'] = '活动未开始';
  277. else if (bcadd($item['stop_time'], 86400) < time())
  278. $item['start_name'] = '活动已结束';
  279. else if (bcadd($item['stop_time'], 86400) > time() && $item['start_time'] < time()) {
  280. $config = SystemGroupData::get($item['time_id']);
  281. if ($config) {
  282. $arr = json_decode($config->value, true);
  283. $now_hour = date('H', time());
  284. $start_hour = $arr['time']['value'];
  285. $continued = $arr['continued']['value'];
  286. $end_hour = $start_hour + $continued;
  287. if ($start_hour > $now_hour) {
  288. $item['start_name'] = '活动未开始';
  289. } elseif ($end_hour < $now_hour) {
  290. $item['start_name'] = '活动已结束';
  291. } else {
  292. $item['start_name'] = '正在进行中';
  293. }
  294. } else {
  295. $item['start_name'] = '正在进行中';
  296. }
  297. }
  298. } else $item['start_name'] = '关闭';
  299. }, $where, $where['limit']);
  300. }
  301. public static function SaveExcel($where)
  302. {
  303. $model = new self;
  304. if ($where['status'] != '') $model = $model->where('status', $where['status']);
  305. if ($where['store_name'] != '') $model = $model->where('title|id', 'LIKE', "%$where[store_name]%");
  306. $list = $model->order('id desc')->where('is_del', 0)->select();
  307. count($list) && $list = $list->toArray();
  308. $excel = [];
  309. foreach ($list as $item) {
  310. $item['store_name'] = StoreProduct::where('id', $item['product_id'])->value('store_name');
  311. if ($item['status']) {
  312. if ($item['start_time'] > time())
  313. $item['start_name'] = '活动未开始';
  314. else if ($item['stop_time'] < time())
  315. $item['start_name'] = '活动已结束';
  316. else if ($item['stop_time'] > time() && $item['start_time'] < time())
  317. $item['start_name'] = '正在进行中';
  318. } else $item['start_name'] = '关闭';
  319. $excel[] = [
  320. $item['id'],
  321. $item['title'],
  322. $item['info'],
  323. $item['ot_price'],
  324. $item['price'],
  325. $item['stock'],
  326. $item['start_name'],
  327. $item['stop_time'],
  328. $item['stop_time'],
  329. $item['status'] ? '开启' : '关闭',
  330. ];
  331. }
  332. PHPExcelService::setExcelHeader(['编号', '活动标题', '活动简介', '原价', '秒杀价', '库存', '秒杀状态', '结束时间', '状态'])
  333. ->setExcelTile('秒杀产品导出', ' ', ' 生成时间:' . date('Y-m-d H:i:s', time()))
  334. ->setExcelContent($excel)
  335. ->ExcelSave();
  336. }
  337. /**
  338. * 获取秒杀产品id
  339. * @return array
  340. */
  341. public static function getSeckillIdAll()
  342. {
  343. return self::where('is_del', 0)->column('id', 'id');
  344. }
  345. /**
  346. * 获取秒杀的所有产品
  347. * @return int|string
  348. */
  349. public static function getSeckillCount()
  350. {
  351. return self::where('is_del', 0)->count();
  352. }
  353. /**
  354. * TODO 获取某个字段值
  355. * @param $id
  356. * @param string $field
  357. * @return mixed
  358. */
  359. public static function getSeckillField($id, $field = 'title')
  360. {
  361. return self::where('id', $id)->value($field);
  362. }
  363. /**
  364. * 判断产品当前时间段是否有秒杀活动
  365. * @param $product_id
  366. * @param $time_id
  367. * @return array|null|\think\Model
  368. * @throws \think\db\exception\DataNotFoundException
  369. * @throws \think\db\exception\DbException
  370. * @throws \think\db\exception\ModelNotFoundException
  371. */
  372. public static function checkSeckill($product_id, $time_id)
  373. {
  374. return self::where('product_id', $product_id)->where('time_id', $time_id)->where('is_del', 0)->find();
  375. }
  376. }