GoodsSaleStatistics.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. namespace app\api\model;
  3. use app\common\model\GoodsSaleStatistics as GoodsSaleStatisticsModel;
  4. use think\facade\Db;
  5. /**
  6. * 商品销售数据每日统计模型
  7. * @package app\api\model
  8. */
  9. class GoodsSaleStatistics extends GoodsSaleStatisticsModel
  10. {
  11. /**
  12. * 批量写入每日/每周/每月数据
  13. * 发布上线时,只需执行一次
  14. */
  15. public static function addInitVisit()
  16. {
  17. $begin_date = '20211001'; // 生成初始数据开始时间,建议时间为:小程序上线时间
  18. $end_date = date('Ymd', strtotime('-1 days')); // 生成初始数据结束时间,建议时间为:昨天
  19. // 每日
  20. $date_arr = period_date(strtotime($begin_date), strtotime($end_date), 'Ymd');
  21. foreach ($date_arr as $date) {
  22. self::addData(1, $date);
  23. }
  24. // 每周
  25. $date_arr = period_week(strtotime('20211001'), strtotime($end_date), true);
  26. foreach ($date_arr as $date) {
  27. self::addData(2, $date);
  28. }
  29. // 每月
  30. $date_arr = period_month(strtotime('20211001'), strtotime($end_date), true);
  31. foreach ($date_arr as $date) {
  32. $date = month_first_last($date);
  33. self::addData(3, $date);
  34. }
  35. }
  36. public static function addData($ftype, $date)
  37. {
  38. if ($ftype == 1) {
  39. $startTime = strtotime("{$date} 00:00:00");
  40. $endTime = strtotime("{$date} 23:59:59");
  41. $refDate = date('Y-m-d', strtotime($date));
  42. } elseif ($ftype == 2) {
  43. $startTime = strtotime("{$date['s']} 00:00:00");
  44. $endTime = strtotime("{$date['e']} 23:59:59");
  45. $refDate = "{$date['s']}--{$date['e']}";
  46. } elseif ($ftype == 3) {
  47. $startTime = strtotime("{$date['s']} 00:00:00");
  48. $endTime = strtotime("{$date['e']} 23:59:59");
  49. $refDate = "{$date['s']}--{$date['e']}";
  50. } else {
  51. return ;
  52. }
  53. $payData = self::getPayData($startTime, $endTime);
  54. $orderData = self::getOrderData($startTime, $endTime);
  55. $firstOrder = self::getFirstOrder($startTime, $endTime);
  56. $reorder = self::getReorder($startTime, $endTime);
  57. self::formatData($ftype, $refDate, $startTime, $endTime, $payData,$orderData, $firstOrder, $reorder);
  58. }
  59. /**
  60. * @param $date
  61. * @param $payData
  62. * @param array $pvUv
  63. * @return mixed
  64. */
  65. private static function formatData($ftype, $refDate, $startTime, $endTime, $payData, $orderData = [], $firstOrder = [], $reorder = [])
  66. {
  67. // $idArr = array_unique(array_merge(array_keys($payData), array_keys($orderData), array_keys($firstOrder), array_keys($reorder)));
  68. $idArr = Db::name('goods')->where('is_delete', '=', 0)->column('goods_id');
  69. if (empty($idArr)) {
  70. return;
  71. }
  72. foreach ($idArr as $id) {
  73. $payCount = 0;
  74. $payGoodsCount = 0;
  75. $payUserCount = 0;
  76. $orderAmount = 0;
  77. $orderCount = 0;
  78. $orderUserCount = 0;
  79. $firstOrderUsers = 0;
  80. $recorderUsers = 0;
  81. if (isset($payData[$id])) {
  82. $payCount = $payData[$id]['pay_count'];
  83. $payGoodsCount = $payData[$id]['pay_goods_count'];
  84. $payUserCount = $payData[$id]['pay_user_count'];
  85. $orderAmount = $payData[$id]['order_amount'];
  86. }
  87. if (isset($orderData[$id])) {
  88. $orderCount = $orderData[$id]['order_count'];
  89. $orderUserCount = $orderData[$id]['order_user_count'];
  90. }
  91. if (isset($firstOrder[$id])) {
  92. $firstOrderUsers = $firstOrder[$id]['first_order_users'];
  93. }
  94. if (isset($reorder[$id])) {
  95. $recorderUsers = $reorder[$id]['recorder_users'];
  96. }
  97. $insert = [
  98. 'goods_id' => $id,
  99. 'ftype' => $ftype,
  100. 'ref_date' => $refDate,
  101. 'start_time' => $startTime,
  102. 'end_time' => $endTime,
  103. 'pay_count' => $payCount ?? 0,
  104. 'pay_goods_count' => $payGoodsCount ?? 0,
  105. 'pay_user_count' => $payUserCount ?? 0,
  106. 'order_amount' => $orderAmount ?? 0,
  107. 'order_count' => $orderCount ?? 0,
  108. 'order_user_count' => $orderUserCount ?? 0,
  109. 'first_order_users' => $firstOrderUsers ?? 0,
  110. 'recorder_users' => $recorderUsers ?? 0,
  111. ];
  112. $info = self::where('goods_id', $id)->where('ref_date', $refDate)->find();
  113. if (empty($info)) {
  114. (new self)->save($insert);
  115. } else {
  116. $info->where('id', $info['id'])->update($insert);
  117. }
  118. }
  119. }
  120. private static function getPayData($startTime, $endTime)
  121. {
  122. $data = Db::name('order')->alias('order')
  123. ->whereBetween('order.pay_time', [$startTime, $endTime])
  124. ->where('order.is_delete', '=', 0)
  125. ->where('og.goods_type', '<>', 20) // // 排除赠品
  126. ->leftJoin('order_goods og', 'og.order_id=order.order_id')
  127. ->group('og.goods_id')
  128. ->column('og.goods_id,count(distinct(og.order_id)) as pay_count,sum(og.total_num) as pay_goods_count,count(distinct(og.user_id)) as pay_user_count,sum(og.total_pay_price+og.rice_card_money) as order_amount','og.goods_id');
  129. return $data;
  130. }
  131. private static function getOrderData($startTime, $endTime)
  132. {
  133. $data = Db::name('order')->alias('order')
  134. ->whereBetween('order.create_time', [$startTime, $endTime])
  135. ->where('order.is_delete', '=', 0)
  136. ->leftJoin('order_goods og', 'og.order_id=order.order_id')
  137. ->group('og.goods_id')
  138. ->column('og.goods_id,count(distinct(og.order_id)) as order_count,count(distinct(og.user_id)) as order_user_count','og.goods_id');
  139. return $data;
  140. }
  141. //⑧首次下单人数:统计首次下单为该商品的用户人数
  142. private static function getFirstOrder($startTime, $endTime)
  143. {
  144. $data = Db::query("select og.goods_id,count(o.user_id) as first_order_users
  145. from (select user_id,min(pay_time) as mp from `yoshop_order` group by user_id) as ump,`yoshop_order` as o
  146. left join yoshop_order_goods as og on og.order_id=o.order_id where ump.user_id=o.user_id and ump.mp=o.pay_time
  147. and pay_time >= ? and pay_time < ? and ump.mp > 0 group by og.goods_id order by goods_id;", [$startTime, $endTime]);
  148. if (empty($data)) {
  149. return [];
  150. }
  151. $res = [];
  152. foreach ($data as $item) {
  153. $res[$item['goods_id']] = $item;
  154. }
  155. return $res;
  156. }
  157. //⑨复购人数:统计用户购买该商品次数≥2的用户人数
  158. private static function getReorder($startTime, $endTime)
  159. {
  160. $data = Db::query("select og.goods_id,count(o.user_id) as recorder_users,
  161. sum(og.total_pay_price+og.rice_card_money) as amount,ump.mp
  162. from (select user_id,min(pay_time) as mp from `yoshop_order` group by user_id) as ump,`yoshop_order` as o
  163. left join yoshop_order_goods as og on og.order_id=o.order_id where ump.user_id=o.user_id and ump.mp=o.pay_time
  164. and pay_time >= ? and pay_time < ? and ump.mp > 0 group by og.goods_id having count(o.user_id) > 1 order by goods_id;", [$startTime, $endTime]);
  165. if (empty($data)) {
  166. return [];
  167. }
  168. $res = [];
  169. foreach ($data as $item) {
  170. $res[$item['goods_id']] = $item;
  171. }
  172. return $res;
  173. }
  174. }