StoreMix.php 15 KB

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