Statmarketing.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. * DSMall多用户商城
  12. * ============================================================================
  13. * 版权所有 2014-2028 长沙德尚网络科技有限公司,并保留所有权利。
  14. * 网站地址: http://www.csdeshang.com
  15. * ----------------------------------------------------------------------------
  16. * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用 .
  17. * 不允许对程序代码以任何形式任何目的的再发布。
  18. * ============================================================================
  19. * 控制器
  20. */
  21. class Statmarketing extends AdminControl
  22. {
  23. public function initialize()
  24. {
  25. parent::initialize(); // TODO: Change the autogenerated stub
  26. Lang::load(base_path().'admin/lang/'.config('lang.default_lang').'/stat.lang.php');
  27. include_once root_path(). 'extend/mall/statistics.php';
  28. include_once root_path(). 'extend/mall/datehelper.php';
  29. $stat_model = model('stat');
  30. //存储参数
  31. $this->search_arr = input('param.');
  32. //处理搜索时间
  33. if (in_array(request()->action(),array('promotion','group'))){
  34. $this->search_arr = $stat_model->dealwithSearchTime($this->search_arr);
  35. //获得系统年份
  36. $year_arr = getSystemYearArr();
  37. //获得系统月份
  38. $month_arr = getSystemMonthArr();
  39. //获得本月的周时间段
  40. $week_arr = getMonthWeekArr($this->search_arr['week']['current_year'], $this->search_arr['week']['current_month']);
  41. View::assign('year_arr', $year_arr);
  42. View::assign('month_arr', $month_arr);
  43. View::assign('week_arr', $week_arr);
  44. }
  45. View::assign('search_arr', $this->search_arr);
  46. }
  47. /**
  48. * 促销分析
  49. */
  50. public function promotion(){
  51. if(!isset($this->search_arr['search_type'])){
  52. $this->search_arr['search_type'] = 'day';
  53. }
  54. $stat_model = model('stat');
  55. //获得搜索的开始时间和结束时间
  56. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  57. $where = array();
  58. $where[]=array('order_isvalid','=',1);//计入统计的有效订单
  59. $where[] = array('order_add_time','between',$searchtime_arr);
  60. $where[]=array('goods_type','in',array(2,3,4));
  61. //下单量
  62. $field = ' goods_type,count(DISTINCT order_id) as ordernum,SUM(goods_num) as goodsnum,SUM(goods_pay_price) as orderamount';
  63. $statlist_tmp = $stat_model->statByStatordergoods($where, $field, 0, 0,'', 'goods_type');
  64. //优惠类型数组
  65. $goodstype_arr = array(2=>lang('goodstype_2'),3=>lang('goodstype_3'),4=>lang('goodstype_4'));
  66. $statlist = array();
  67. $statcount = array('ordernum'=>0,'goodsnum'=>0,'orderamount'=>0.00);
  68. $stat_arr = array();
  69. $stat_json = array('ordernum'=>'','goodsnum'=>'','orderamount'=>'');
  70. if ($statlist_tmp){
  71. foreach((array)$statlist_tmp as $k=>$v){
  72. $statcount['ordernum'] += intval($v['ordernum']);
  73. $statcount['goodsnum'] += intval($v['goodsnum']);
  74. $statcount['orderamount'] += floatval($v['orderamount']);
  75. }
  76. foreach((array)$statlist_tmp as $k=>$v){
  77. $v['ordernumratio'] = round($v['ordernum']/$statcount['ordernum'],4)*100;
  78. $v['goodsnumratio'] = round($v['goodsnum']/$statcount['goodsnum'],4)*100;
  79. $v['orderamountratio'] = round($v['orderamount']/$statcount['orderamount'],4)*100;
  80. $statlist_tmp2[$v['goods_type']] = $v;
  81. $stat_arr['ordernum'][] = array('p_name'=>$goodstype_arr[$v['goods_type']],'allnum'=>$v['ordernumratio']);
  82. $stat_arr['goodsnum'][] = array('p_name'=>$goodstype_arr[$v['goods_type']],'allnum'=>$v['goodsnumratio']);
  83. $stat_arr['orderamount'][] = array('p_name'=>$goodstype_arr[$v['goods_type']],'allnum'=>$v['orderamountratio']);
  84. }
  85. foreach ($goodstype_arr as $k=>$v){
  86. if (isset($statlist_tmp2[$k])){
  87. $statlist_tmp2[$k]['goodstype_text'] = $v;
  88. $statlist[] = $statlist_tmp2[$k];
  89. } else {
  90. $statlist[] = array('goodstype_text'=>$k,'goodstype_text'=>$v,'ordernum'=>0,'goodsnum'=>0,'orderamount'=>0.00);
  91. }
  92. }
  93. $stat_json['ordernum'] = getStatData_Pie(array('title'=>lang('statstore_ordernum'),'name'=>lang('statstore_ordernum').'(%)','label_show'=>false,'series'=>$stat_arr['ordernum']));
  94. $stat_json['goodsnum'] = getStatData_Pie(array('title'=>lang('goodsnum'),'name'=>lang('goodsnum').'(%)','label_show'=>false,'series'=>$stat_arr['goodsnum']));
  95. $stat_json['orderamount'] = getStatData_Pie(array('title'=>lang('statstore_orderamount'),'name'=>lang('statstore_orderamount').'(%)','label_show'=>false,'series'=>$stat_arr['orderamount']));
  96. }
  97. View::assign('statcount',$statcount);
  98. View::assign('statlist',$statlist);
  99. View::assign('stat_json',$stat_json);
  100. View::assign('searchtime',implode('|',$searchtime_arr));
  101. $this->setAdminCurItem('promotion');
  102. return View::fetch('marketing_promotion');
  103. }
  104. /**
  105. * 促销销售趋势分析
  106. */
  107. public function promotiontrend(){
  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. if(!isset($this->search_arr['search_type'])){
  213. $this->search_arr['search_type'] = 'day';
  214. }
  215. $stat_model = model('stat');
  216. //获得搜索的开始时间和结束时间
  217. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  218. View::assign('searchtime',implode('|',$searchtime_arr));
  219. $this->setAdminCurItem('group');
  220. return View::fetch('marketing_group');
  221. }
  222. /**
  223. * 抢购统计
  224. */
  225. public function grouplist(){
  226. $groupbuy_model = model('groupbuy');
  227. $where = array();
  228. $where[]=array('groupbuy_is_vr','=',0);//不统计虚拟抢购
  229. $searchtime_arr_tmp = explode('|',$this->search_arr['t']);
  230. foreach ((array)$searchtime_arr_tmp as $k=>$v){
  231. $searchtime_arr[] = intval($v);
  232. }
  233. $where[] = array('groupbuy_starttime','between',"$searchtime_arr[0],$searchtime_arr[1]");
  234. $where[]=array('groupbuy_state','in',array(10,20,30));
  235. $gname = trim(input('param.gname'));
  236. if ($gname){
  237. $where[]=array('groupbuy_name','like',"%{$gname}%");
  238. }
  239. $grouplist_tmp = $groupbuy_model->getGroupbuyExtendList($where,10,'groupbuy_starttime asc');
  240. $grouplist=array();
  241. if ($grouplist_tmp){
  242. foreach ((array)$grouplist_tmp as $k=>$v){
  243. $v['goodsnum'] = 0;
  244. $v['ordernum'] = 0;
  245. $v['orderrate'] = round(0,2);
  246. $v['goodsamount'] = ds_price_format(0);
  247. $grouplist[$v['groupbuy_id']] = $v;
  248. }
  249. //查询抢购的订单
  250. $where = array();
  251. $where[] = array('order_isvalid','=',1);//计入统计的有效订单
  252. $where[]=array('goods_type','=',2);//抢购
  253. $where[]=array('promotions_id','in',array_keys($grouplist));
  254. $field = 'promotions_id,SUM(goods_num) as goodsnum,COUNT(DISTINCT order_id) as ordernum,SUM(goods_pay_price) as goodsamount';
  255. $order_list = model('stat')->statByStatordergoods($where, $field, 0, 0, '', 'promotions_id');
  256. foreach ((array)$order_list as $k=>$v){
  257. $grouplist[$v['promotions_id']]['goodsnum'] = $v['goodsnum'];
  258. $grouplist[$v['promotions_id']]['ordernum'] = $v['ordernum'];
  259. if (intval($grouplist[$v['promotions_id']]['groupbuy_views']) > 0){
  260. $grouplist[$v['promotions_id']]['orderrate'] = round(($v['ordernum']/$grouplist[$v['promotions_id']]['views'])*100,2);
  261. }
  262. $grouplist[$v['promotions_id']]['goodsamount'] = $v['goodsamount'];
  263. }
  264. }
  265. View::assign('grouplist',$grouplist);
  266. View::assign('show_page',$groupbuy_model->page_info->render());
  267. View::assign('searchtime',input('param.t'));
  268. echo View::fetch('marketing_grouplist');
  269. }
  270. /**
  271. * 抢购商品统计
  272. */
  273. public function groupgoods(){
  274. $stat_model = model('stat');
  275. $where = array();
  276. $statlist= array();
  277. $searchtime_arr_tmp = explode('|',$this->search_arr['t']);
  278. foreach ((array)$searchtime_arr_tmp as $k=>$v){
  279. $searchtime_arr[] = intval($v);
  280. }
  281. $where[] = array('order_add_time','between',$searchtime_arr);
  282. $where[] = array('goods_type','=',2);//抢购
  283. $field = " goods_id,goods_name";
  284. $field .= " ,SUM(goods_num) as goodsnum";
  285. $field .= " ,SUM(goods_pay_price) as goodsamount";
  286. $field .= " ,SUM(IF(order_state='".ORDER_STATE_CANCEL."',goods_num,0)) as cancelgoodsnum";
  287. $field .= " ,SUM(IF(order_state='".ORDER_STATE_CANCEL."',goods_pay_price,0)) as cancelgoodsamount";
  288. $field .= " ,SUM(IF(order_state<>'".ORDER_STATE_CANCEL."' and order_state<>'".ORDER_STATE_NEW."',goods_num,0)) as finishgoodsnum";
  289. $field .= " ,SUM(IF(order_state<>'".ORDER_STATE_CANCEL."' and order_state<>'".ORDER_STATE_NEW."',goods_pay_price,0)) as finishgoodsamount";
  290. $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');
  291. if (!in_array(trim(@$this->search_arr['orderby']),$orderby_arr)){
  292. $this->search_arr['orderby'] = 'goodsnum desc';
  293. }
  294. $orderby = trim($this->search_arr['orderby']).',goods_id desc';
  295. //统计记录总条数
  296. $count_arr = $stat_model->getoneByStatordergoods($where, 'count(DISTINCT goods_id) as countnum');
  297. $countnum = intval($count_arr['countnum']);
  298. if (@$this->search_arr['exporttype'] == 'excel'){
  299. $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);
  300. } else {
  301. $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');
  302. }
  303. $statheader = array();
  304. $statheader[] = array('text'=>lang('ds_goods_name'),'key'=>'goods_name','class'=>'alignleft');
  305. $statheader[] = array('text'=>lang('goodsnum'),'key'=>'goodsnum','isorder'=>1);
  306. $statheader[] = array('text'=>lang('statstore_orderamount'),'key'=>'goodsamount','isorder'=>1);
  307. $statheader[] = array('text'=>lang('cancel_goods_number'),'key'=>'cancelgoodsnum','isorder'=>1);
  308. $statheader[] = array('text'=>lang('cancel_amount'),'key'=>'cancelgoodsamount','isorder'=>1);
  309. $statheader[] = array('text'=>lang('finish_goods_number'),'key'=>'finishgoodsnum','isorder'=>1);
  310. $statheader[] = array('text'=>lang('finish_amount'),'key'=>'finishgoodsamount','isorder'=>1);
  311. foreach ((array)$statlist_tmp as $k=>$v){
  312. $tmp = $v;
  313. foreach ($statheader as $h_k=>$h_v){
  314. $tmp[$h_v['key']] = $v[$h_v['key']];
  315. if ($h_v['key'] == 'goods_name'){
  316. $tmp[$h_v['key']] = '<a href="'.(string)url('home/Goods/index', array('goods_id' => $v['goods_id'])).'" target="_blank">'.$v['goods_name'].'</a>';
  317. }
  318. }
  319. $statlist[] = $tmp;
  320. }
  321. if (@$this->search_arr['exporttype'] == 'excel'){
  322. //导出Excel
  323. $excel_obj = new \excel\Excel();
  324. $excel_data = array();
  325. //设置样式
  326. $excel_obj->setStyle(array('id'=>'s_title','Font'=>array('FontName'=>'宋体','Size'=>'12','Bold'=>'1')));
  327. //header
  328. foreach ($statheader as $k=>$v){
  329. $excel_data[0][] = array('styleid'=>'s_title','data'=>$v['text']);
  330. }
  331. //data
  332. foreach ((array)$statlist as $k=>$v){
  333. foreach ($statheader as $h_k=>$h_v){
  334. $excel_data[$k+1][] = array('data'=>$v[$h_v['key']]);
  335. }
  336. }
  337. $excel_data = $excel_obj->charset($excel_data,CHARSET);
  338. $excel_obj->addArray($excel_data);
  339. $excel_obj->addWorksheet($excel_obj->charset(lang('groupbuy_goods_statis'),CHARSET));
  340. $excel_obj->generateXML($excel_obj->charset(lang('groupbuy_goods_statis'),CHARSET).date('Y-m-d-H',TIMESTAMP));
  341. exit();
  342. } else {
  343. View::assign('statheader',$statheader);
  344. View::assign('statlist',$statlist);
  345. View::assign('show_page',Db::name('statordergoods')->paginate(10,$countnum)->render());
  346. View::assign('searchtime',input('param.t'));
  347. View::assign('orderby',$this->search_arr['orderby']);
  348. View::assign('actionurl',(string)url('Statmarketing/groupgoods',['t'=>$this->search_arr['t']]));
  349. echo View::fetch('stat_listandorder');
  350. }
  351. }
  352. protected function getAdminItemList()
  353. {
  354. $menu_array=array(
  355. array('name'=>'promotion','text'=>lang('stat_promotion'),'url'=>(string)url('Statmarketing/promotion')),
  356. array('name'=>'group','text'=>lang('stat_group'),'url'=>(string)url('Statmarketing/group'))
  357. );
  358. return $menu_array;
  359. }
  360. }