Statmarketing.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <?php
  2. /**
  3. * 市场统计分析
  4. */
  5. namespace app\admin\controller;
  6. use think\facade\View;
  7. use think\facade\Db;
  8. use think\facade\Lang;
  9. /**
  10. * ============================================================================
  11. *
  12. * ============================================================================
  13. *
  14. * ----------------------------------------------------------------------------
  15. *
  16. * ============================================================================
  17. * 控制器
  18. */
  19. class Statmarketing extends AdminControl
  20. {
  21. public function initialize()
  22. {
  23. parent::initialize(); // TODO: Change the autogenerated stub
  24. Lang::load(base_path() . 'admin/lang/' . config('lang.default_lang') . '/stat.lang.php');
  25. include_once root_path() . 'extend/mall/statistics.php';
  26. include_once root_path() . 'extend/mall/datehelper.php';
  27. $stat_model = model('stat');
  28. //存储参数
  29. $this->search_arr = input('param.');
  30. //处理搜索时间
  31. if (in_array(request()->action(), array('promotion', 'group'))) {
  32. $this->search_arr = $stat_model->dealwithSearchTime($this->search_arr);
  33. //获得系统年份
  34. $year_arr = getSystemYearArr();
  35. //获得系统月份
  36. $month_arr = getSystemMonthArr();
  37. //获得本月的周时间段
  38. $week_arr = getMonthWeekArr($this->search_arr['week']['current_year'], $this->search_arr['week']['current_month']);
  39. View::assign('year_arr', $year_arr);
  40. View::assign('month_arr', $month_arr);
  41. View::assign('week_arr', $week_arr);
  42. }
  43. View::assign('search_arr', $this->search_arr);
  44. }
  45. /**
  46. * 促销分析
  47. */
  48. public function promotion()
  49. {
  50. if (!isset($this->search_arr['search_type'])) {
  51. $this->search_arr['search_type'] = 'day';
  52. }
  53. $stat_model = model('stat');
  54. //获得搜索的开始时间和结束时间
  55. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  56. $where = array();
  57. $where[] = array('order_isvalid', '=', 1); //计入统计的有效订单
  58. $where[] = array('order_add_time', 'between', $searchtime_arr);
  59. $where[] = array('goods_type', 'in', array(2, 3, 4));
  60. //下单量
  61. $field = ' goods_type,count(DISTINCT order_id) as ordernum,SUM(goods_num) as goodsnum,SUM(goods_pay_price) as orderamount';
  62. $statlist_tmp = $stat_model->statByStatordergoods($where, $field, 0, 0, '', 'goods_type');
  63. //优惠类型数组
  64. $goodstype_arr = array(2 => lang('goodstype_2'), 3 => lang('goodstype_3'), 4 => lang('goodstype_4'));
  65. $statlist = array();
  66. $statcount = array('ordernum' => 0, 'goodsnum' => 0, 'orderamount' => 0.00);
  67. $stat_arr = array();
  68. $stat_json = array('ordernum' => '', 'goodsnum' => '', 'orderamount' => '');
  69. if ($statlist_tmp) {
  70. foreach ((array)$statlist_tmp as $k => $v) {
  71. $statcount['ordernum'] += intval($v['ordernum']);
  72. $statcount['goodsnum'] += intval($v['goodsnum']);
  73. $statcount['orderamount'] += floatval($v['orderamount']);
  74. }
  75. foreach ((array)$statlist_tmp as $k => $v) {
  76. $v['ordernumratio'] = round($v['ordernum'] / $statcount['ordernum'], 4) * 100;
  77. $v['goodsnumratio'] = round($v['goodsnum'] / $statcount['goodsnum'], 4) * 100;
  78. $v['orderamountratio'] = round($v['orderamount'] / $statcount['orderamount'], 4) * 100;
  79. $statlist_tmp2[$v['goods_type']] = $v;
  80. $stat_arr['ordernum'][] = array('p_name' => $goodstype_arr[$v['goods_type']], 'allnum' => $v['ordernumratio']);
  81. $stat_arr['goodsnum'][] = array('p_name' => $goodstype_arr[$v['goods_type']], 'allnum' => $v['goodsnumratio']);
  82. $stat_arr['orderamount'][] = array('p_name' => $goodstype_arr[$v['goods_type']], 'allnum' => $v['orderamountratio']);
  83. }
  84. foreach ($goodstype_arr as $k => $v) {
  85. if (isset($statlist_tmp2[$k])) {
  86. $statlist_tmp2[$k]['goodstype_text'] = $v;
  87. $statlist[] = $statlist_tmp2[$k];
  88. } else {
  89. $statlist[] = array('goodstype_text' => $k, 'goodstype_text' => $v, 'ordernum' => 0, 'goodsnum' => 0, 'orderamount' => 0.00);
  90. }
  91. }
  92. $stat_json['ordernum'] = getStatData_Pie(array('title' => lang('statstore_ordernum'), 'name' => lang('statstore_ordernum') . '(%)', 'label_show' => false, 'series' => $stat_arr['ordernum']));
  93. $stat_json['goodsnum'] = getStatData_Pie(array('title' => lang('goodsnum'), 'name' => lang('goodsnum') . '(%)', 'label_show' => false, 'series' => $stat_arr['goodsnum']));
  94. $stat_json['orderamount'] = getStatData_Pie(array('title' => lang('statstore_orderamount'), 'name' => lang('statstore_orderamount') . '(%)', 'label_show' => false, 'series' => $stat_arr['orderamount']));
  95. }
  96. View::assign('statcount', $statcount);
  97. View::assign('statlist', $statlist);
  98. View::assign('stat_json', $stat_json);
  99. View::assign('searchtime', implode('|', $searchtime_arr));
  100. $this->setAdminCurItem('promotion');
  101. return View::fetch('marketing_promotion');
  102. }
  103. /**
  104. * 促销销售趋势分析
  105. */
  106. public function promotiontrend()
  107. {
  108. //优惠类型数组
  109. $goodstype_arr = array(2 => lang('goodstype_2'), 3 => lang('goodstype_3'), 4 => lang('goodstype_4'));
  110. $stat_model = model('stat');
  111. $where = array();
  112. $searchtime_arr_tmp = explode('|', $this->search_arr['t']);
  113. foreach ((array)$searchtime_arr_tmp as $k => $v) {
  114. $searchtime_arr[] = intval($v);
  115. }
  116. $where[] = array('order_isvalid', '=', 1); //计入统计的有效订单
  117. $where[] = array('order_add_time', 'between', $searchtime_arr);
  118. $where[] = array('goods_type', 'in', array(2, 3, 4));
  119. $field = ' goods_type';
  120. switch ($this->search_arr['stattype']) {
  121. case 'orderamount':
  122. $field .= " ,SUM(goods_pay_price) as orderamount";
  123. $caption = lang('statstore_orderamount');
  124. break;
  125. case 'goodsnum':
  126. $field .= " ,SUM(goods_num) as goodsnum";
  127. $caption = lang('goodsnum');
  128. break;
  129. default:
  130. $field .= " ,count(DISTINCT order_id) as ordernum";
  131. $caption = lang('statstore_ordernum');
  132. break;
  133. }
  134. if ($this->search_arr['search_type'] == 'day') {
  135. //构造横轴数据
  136. for ($i = 0; $i < 24; $i++) {
  137. //横轴
  138. $stat_arr['xAxis']['categories'][] = "$i";
  139. foreach ($goodstype_arr as $k => $v) {
  140. $statlist[$k][$i] = 0;
  141. }
  142. }
  143. $field .= ' ,HOUR(FROM_UNIXTIME(order_add_time)) as timeval ';
  144. }
  145. if ($this->search_arr['search_type'] == 'week') {
  146. //构造横轴数据
  147. for ($i = 1; $i <= 7; $i++) {
  148. $tmp_weekarr = getSystemWeekArr();
  149. //横轴
  150. $stat_arr['xAxis']['categories'][] = $tmp_weekarr[$i];
  151. unset($tmp_weekarr);
  152. foreach ($goodstype_arr as $k => $v) {
  153. $statlist[$k][$i] = 0;
  154. }
  155. }
  156. $field .= ' ,WEEKDAY(FROM_UNIXTIME(order_add_time))+1 as timeval ';
  157. }
  158. if ($this->search_arr['search_type'] == 'month') {
  159. //计算横轴的最大量(由于每个月的天数不同)
  160. $dayofmonth = date('t', $searchtime_arr[0]);
  161. //构造横轴数据
  162. for ($i = 1; $i <= $dayofmonth; $i++) {
  163. //横轴
  164. $stat_arr['xAxis']['categories'][] = $i;
  165. foreach ($goodstype_arr as $k => $v) {
  166. $statlist[$k][$i] = 0;
  167. }
  168. }
  169. $field .= ' ,day(FROM_UNIXTIME(order_add_time)) as timeval ';
  170. }
  171. //查询数据
  172. $statlist_tmp = $stat_model->statByStatordergoods($where, $field, 0, 0, '', 'goods_type');
  173. //整理统计数组
  174. if ($statlist_tmp) {
  175. foreach ($statlist_tmp as $k => $v) {
  176. //将数据按照不同的促销方式分组
  177. foreach ($goodstype_arr as $t_k => $t_v) {
  178. if ($t_k == $v['goods_type']) {
  179. switch ($this->search_arr['stattype']) {
  180. case 'orderamount':
  181. $statlist[$t_k][$v['timeval']] = round($v[$this->search_arr['stattype']], 2);
  182. break;
  183. case 'goodsnum':
  184. $statlist[$t_k][$v['timeval']] = intval($v[$this->search_arr['stattype']]);
  185. break;
  186. default:
  187. $statlist[$t_k][$v['timeval']] = intval($v[$this->search_arr['stattype']]);
  188. break;
  189. }
  190. }
  191. }
  192. }
  193. }
  194. foreach ($goodstype_arr as $k => $v) {
  195. $tmp = array();
  196. $tmp['name'] = $v;
  197. $tmp['data'] = array_values($statlist[$k]);
  198. $stat_arr['series'][] = $tmp;
  199. }
  200. //得到统计图数据
  201. $stat_arr['title'] = $caption . lang('ds_stat');
  202. $stat_arr['yAxis'] = $caption;
  203. $stat_json = getStatData_LineLabels($stat_arr);
  204. View::assign('stat_json', $stat_json);
  205. View::assign('stattype', input('param.stattype'));
  206. echo View::fetch('stat_linelabels');
  207. }
  208. /**
  209. * 抢购统计
  210. */
  211. public function group()
  212. {
  213. if (!isset($this->search_arr['search_type'])) {
  214. $this->search_arr['search_type'] = 'day';
  215. }
  216. $stat_model = model('stat');
  217. //获得搜索的开始时间和结束时间
  218. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  219. View::assign('searchtime', implode('|', $searchtime_arr));
  220. $this->setAdminCurItem('group');
  221. return View::fetch('marketing_group');
  222. }
  223. /**
  224. * 抢购统计
  225. */
  226. public function grouplist()
  227. {
  228. $groupbuy_model = model('groupbuy');
  229. $where = array();
  230. $where[] = array('groupbuy_is_vr', '=', 0); //不统计虚拟抢购
  231. $searchtime_arr_tmp = explode('|', $this->search_arr['t']);
  232. foreach ((array)$searchtime_arr_tmp as $k => $v) {
  233. $searchtime_arr[] = intval($v);
  234. }
  235. $where[] = array('groupbuy_starttime', 'between', "$searchtime_arr[0],$searchtime_arr[1]");
  236. $where[] = array('groupbuy_state', 'in', array(10, 20, 30));
  237. $gname = trim(input('param.gname'));
  238. if ($gname) {
  239. $where[] = array('groupbuy_name', 'like', "%{$gname}%");
  240. }
  241. $grouplist_tmp = $groupbuy_model->getGroupbuyExtendList($where, 10, 'groupbuy_starttime asc');
  242. $grouplist = array();
  243. if ($grouplist_tmp) {
  244. foreach ((array)$grouplist_tmp as $k => $v) {
  245. $v['goodsnum'] = 0;
  246. $v['ordernum'] = 0;
  247. $v['orderrate'] = round(0, 2);
  248. $v['goodsamount'] = ds_price_format(0);
  249. $grouplist[$v['groupbuy_id']] = $v;
  250. }
  251. //查询抢购的订单
  252. $where = array();
  253. $where[] = array('order_isvalid', '=', 1); //计入统计的有效订单
  254. $where[] = array('goods_type', '=', 2); //抢购
  255. $where[] = array('promotions_id', 'in', array_keys($grouplist));
  256. $field = 'promotions_id,SUM(goods_num) as goodsnum,COUNT(DISTINCT order_id) as ordernum,SUM(goods_pay_price) as goodsamount';
  257. $order_list = model('stat')->statByStatordergoods($where, $field, 0, 0, '', 'promotions_id');
  258. foreach ((array)$order_list as $k => $v) {
  259. $grouplist[$v['promotions_id']]['goodsnum'] = $v['goodsnum'];
  260. $grouplist[$v['promotions_id']]['ordernum'] = $v['ordernum'];
  261. if (intval($grouplist[$v['promotions_id']]['groupbuy_views']) > 0) {
  262. $grouplist[$v['promotions_id']]['orderrate'] = round(($v['ordernum'] / $grouplist[$v['promotions_id']]['views']) * 100, 2);
  263. }
  264. $grouplist[$v['promotions_id']]['goodsamount'] = $v['goodsamount'];
  265. }
  266. }
  267. View::assign('grouplist', $grouplist);
  268. View::assign('show_page', $groupbuy_model->page_info->render());
  269. View::assign('searchtime', input('param.t'));
  270. echo View::fetch('marketing_grouplist');
  271. }
  272. /**
  273. * 抢购商品统计
  274. */
  275. public function groupgoods()
  276. {
  277. $stat_model = model('stat');
  278. $where = array();
  279. $statlist = array();
  280. $searchtime_arr_tmp = explode('|', $this->search_arr['t']);
  281. foreach ((array)$searchtime_arr_tmp as $k => $v) {
  282. $searchtime_arr[] = intval($v);
  283. }
  284. $where[] = array('order_add_time', 'between', $searchtime_arr);
  285. $where[] = array('goods_type', '=', 2); //抢购
  286. $field = " goods_id,goods_name";
  287. $field .= " ,SUM(goods_num) as goodsnum";
  288. $field .= " ,SUM(goods_pay_price) as goodsamount";
  289. $field .= " ,SUM(IF(order_state='" . ORDER_STATE_CANCEL . "',goods_num,0)) as cancelgoodsnum";
  290. $field .= " ,SUM(IF(order_state='" . ORDER_STATE_CANCEL . "',goods_pay_price,0)) as cancelgoodsamount";
  291. $field .= " ,SUM(IF(order_state<>'" . ORDER_STATE_CANCEL . "' and order_state<>'" . ORDER_STATE_NEW . "',goods_num,0)) as finishgoodsnum";
  292. $field .= " ,SUM(IF(order_state<>'" . ORDER_STATE_CANCEL . "' and order_state<>'" . ORDER_STATE_NEW . "',goods_pay_price,0)) as finishgoodsamount";
  293. $orderby_arr = array('goodsnum asc', 'goodsnum desc', 'goodsamount asc', 'goodsamount desc', 'cancelgoodsnum asc', 'cancelgoodsnum desc', 'cancelgoodsamount asc', 'cancelgoodsamount desc', 'finishgoodsnum asc', 'finishgoodsnum desc', 'finishgoodsamount asc', 'finishgoodsamount desc');
  294. if (!in_array(trim(@$this->search_arr['orderby']), $orderby_arr)) {
  295. $this->search_arr['orderby'] = 'goodsnum desc';
  296. }
  297. $orderby = trim($this->search_arr['orderby']) . ',goods_id desc';
  298. //统计记录总条数
  299. $count_arr = $stat_model->getoneByStatordergoods($where, 'count(DISTINCT goods_id) as countnum');
  300. $countnum = intval($count_arr['countnum']);
  301. if (@$this->search_arr['exporttype'] == 'excel') {
  302. $statlist_tmp = Db::query('SELECT ' . $field . ' FROM ' . config('database.connections.mysql.prefix') . 'statordergoods WHERE goods_type=2 AND order_add_time BETWEEN ' . $searchtime_arr[0] . ' AND ' . $searchtime_arr[1] . ' GROUP BY goods_id' . ' ORDER BY ' . $orderby);
  303. } else {
  304. $statlist_tmp = Db::query('SELECT ' . $field . ' FROM ' . config('database.connections.mysql.prefix') . 'statordergoods WHERE goods_type=2 AND order_add_time BETWEEN ' . $searchtime_arr[0] . ' AND ' . $searchtime_arr[1] . ' GROUP BY goods_id' . ' ORDER BY ' . $orderby . ' LIMIT ' . (input('param.page') ? input('param.page') : 0) . ',10');
  305. }
  306. $statheader = array();
  307. $statheader[] = array('text' => lang('ds_goods_name'), 'key' => 'goods_name', 'class' => 'alignleft');
  308. $statheader[] = array('text' => lang('goodsnum'), 'key' => 'goodsnum', 'isorder' => 1);
  309. $statheader[] = array('text' => lang('statstore_orderamount'), 'key' => 'goodsamount', 'isorder' => 1);
  310. $statheader[] = array('text' => lang('cancel_goods_number'), 'key' => 'cancelgoodsnum', 'isorder' => 1);
  311. $statheader[] = array('text' => lang('cancel_amount'), 'key' => 'cancelgoodsamount', 'isorder' => 1);
  312. $statheader[] = array('text' => lang('finish_goods_number'), 'key' => 'finishgoodsnum', 'isorder' => 1);
  313. $statheader[] = array('text' => lang('finish_amount'), 'key' => 'finishgoodsamount', 'isorder' => 1);
  314. foreach ((array)$statlist_tmp as $k => $v) {
  315. $tmp = $v;
  316. foreach ($statheader as $h_k => $h_v) {
  317. $tmp[$h_v['key']] = $v[$h_v['key']];
  318. if ($h_v['key'] == 'goods_name') {
  319. $tmp[$h_v['key']] = '<a href="' . (string)url('home/Goods/index', array('goods_id' => $v['goods_id'])) . '" target="_blank">' . $v['goods_name'] . '</a>';
  320. }
  321. }
  322. $statlist[] = $tmp;
  323. }
  324. if (@$this->search_arr['exporttype'] == 'excel') {
  325. //导出Excel
  326. $excel_obj = new \excel\Excel();
  327. $excel_data = array();
  328. //设置样式
  329. $excel_obj->setStyle(array('id' => 's_title', 'Font' => array('FontName' => '宋体', 'Size' => '12', 'Bold' => '1')));
  330. //header
  331. foreach ($statheader as $k => $v) {
  332. $excel_data[0][] = array('styleid' => 's_title', 'data' => $v['text']);
  333. }
  334. //data
  335. foreach ((array)$statlist as $k => $v) {
  336. foreach ($statheader as $h_k => $h_v) {
  337. $excel_data[$k + 1][] = array('data' => $v[$h_v['key']]);
  338. }
  339. }
  340. $excel_data = $excel_obj->charset($excel_data, CHARSET);
  341. $excel_obj->addArray($excel_data);
  342. $excel_obj->addWorksheet($excel_obj->charset(lang('groupbuy_goods_statis'), CHARSET));
  343. $excel_obj->generateXML($excel_obj->charset(lang('groupbuy_goods_statis'), CHARSET) . date('Y-m-d-H', TIMESTAMP));
  344. exit();
  345. } else {
  346. View::assign('statheader', $statheader);
  347. View::assign('statlist', $statlist);
  348. View::assign('show_page', Db::name('statordergoods')->paginate(10, $countnum)->render());
  349. View::assign('searchtime', input('param.t'));
  350. View::assign('orderby', $this->search_arr['orderby']);
  351. View::assign('actionurl', (string)url('Statmarketing/groupgoods', ['t' => $this->search_arr['t']]));
  352. echo View::fetch('stat_listandorder');
  353. }
  354. }
  355. protected function getAdminItemList()
  356. {
  357. $menu_array = array(
  358. array('name' => 'promotion', 'text' => lang('stat_promotion'), 'url' => (string)url('Statmarketing/promotion')),
  359. array('name' => 'group', 'text' => lang('stat_group'), 'url' => (string)url('Statmarketing/group'))
  360. );
  361. return $menu_array;
  362. }
  363. }