Statstore.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. <?php
  2. /**
  3. * 店铺统计
  4. */
  5. namespace app\admin\controller;
  6. use think\facade\View;
  7. use think\facade\Db;
  8. use excel\Excel;
  9. use think\facade\Lang;
  10. /**
  11. * ============================================================================
  12. *
  13. * ============================================================================
  14. * 版权所有 2014-2028 浙江惠利玛产业互联网有限公司,并保留所有权利。
  15. * 网站地址: https://www.valimart.net/
  16. * ----------------------------------------------------------------------------
  17. *
  18. * ============================================================================
  19. * 控制器
  20. */
  21. class Statstore extends AdminControl
  22. {
  23. private $search_arr;//处理后的参数
  24. private $store_class;//店铺分类
  25. public function initialize()
  26. {
  27. parent::initialize(); // TODO: Change the autogenerated stub
  28. Lang::load(base_path().'admin/lang/'.config('lang.default_lang').'/stat.lang.php');
  29. include_once root_path(). 'extend/mall/statistics.php';
  30. include_once root_path(). 'extend/mall/datehelper.php';
  31. $stat_model = model('stat');
  32. //存储参数
  33. $this->search_arr = input('param.');
  34. //处理搜索时间
  35. if (in_array(request()->action(),array('hotrank','storesales'))){
  36. $this->search_arr = $stat_model->dealwithSearchTime($this->search_arr);
  37. //获得系统年份
  38. $year_arr = getSystemYearArr();
  39. //获得系统月份
  40. $month_arr = getSystemMonthArr();
  41. //获得本月的周时间段
  42. $week_arr = getMonthWeekArr($this->search_arr['week']['current_year'], $this->search_arr['week']['current_month']);
  43. View::assign('year_arr', $year_arr);
  44. View::assign('month_arr', $month_arr);
  45. View::assign('week_arr', $week_arr);
  46. }
  47. View::assign('search_arr', $this->search_arr);
  48. //店铺分类
  49. $this->store_class = rkcache('storeclass', true);
  50. View::assign('store_class', $this->store_class);
  51. }
  52. /**
  53. * 新增店铺
  54. */
  55. public function newstore(){
  56. //导出excel连接地址
  57. $actionurl = (string)url('Statstore/newstore');
  58. $where = array();
  59. //所属店铺分类
  60. $search_sclass = intval(input('param.search_sclass'));
  61. if ($search_sclass > 0){
  62. $where[] = array('storeclass_id','=',$search_sclass);;
  63. $actionurl .= "&search_sclass=$search_sclass";
  64. }
  65. $field = ' count(*) as allnum ';
  66. if(!input('param.search_type')){
  67. $search_type = 'day';
  68. }
  69. else{
  70. $search_type = input('param.search_type');
  71. }
  72. //初始化时间
  73. //天
  74. if(!input('param.search_time')) {
  75. $search_times = date('Y-m-d', TIMESTAMP - 86400);
  76. }else {
  77. $search_times = input('param.search_time');
  78. }
  79. $search_time = strtotime($search_times);//搜索的时间
  80. View::assign('search_time',$search_times);
  81. //周
  82. if(!input('param.search_time_year')) {
  83. $search_time_year = date('Y', TIMESTAMP);
  84. }else {
  85. $search_time_year = input('param.search_time_year');
  86. }
  87. if(!input('param.search_time_month')) {
  88. $search_time_month = date('m', TIMESTAMP);
  89. }else {
  90. $search_time_month = input('param.search_time_month');
  91. }
  92. if(!input('param.search_time_week')) {
  93. $search_time_week = implode('|', getWeek_SdateAndEdate(TIMESTAMP));
  94. }else {
  95. $search_time_week = input('param.search_time_week');
  96. }
  97. $current_year =$search_time_year;
  98. $current_month =$search_time_month;
  99. $current_week = $search_time_week;
  100. $year_arr = getSystemYearArr();
  101. $month_arr = getSystemMonthArr();
  102. $week_arr = getMonthWeekArr($current_year, $current_month);
  103. View::assign('current_year', $current_year);
  104. View::assign('current_month', $current_month);
  105. View::assign('current_week', $current_week);
  106. View::assign('year_arr', $year_arr);
  107. View::assign('month_arr', $month_arr);
  108. View::assign('week_arr', $week_arr);
  109. $stat_model = model('stat');
  110. $statlist = array();//统计数据列表
  111. if($search_type == 'day'){
  112. //构造横轴数据
  113. for($i=0; $i<24; $i++){
  114. //统计图数据
  115. $curr_arr[$i] = 0;//今天
  116. $up_arr[$i] = 0;//昨天
  117. //统计表数据
  118. $uplist_arr[$i]['timetext'] = $i;
  119. $currlist_arr[$i]['timetext'] = $i;
  120. //方便搜索会员列表,计算开始时间和结束时间
  121. $currlist_arr[$i]['stime'] = $search_time+$i*3600;
  122. $currlist_arr[$i]['etime'] = $currlist_arr[$i]['stime']+3600;
  123. $uplist_arr[$i]['val'] = 0;
  124. $currlist_arr[$i]['val'] = 0;
  125. //横轴
  126. $stat_arr['xAxis']['categories'][] = "$i";
  127. }
  128. $stime = $search_time - 86400;//昨天0点
  129. $etime = $search_time + 86400 - 1;//今天24点
  130. $today_day = @date('d', $search_time);//今天日期
  131. $yesterday_day = @date('d', $stime);//昨天日期
  132. $where[] = array('store_addtime','between',array($stime,$etime));
  133. $field .= ' ,DAY(FROM_UNIXTIME(store_addtime)) as dayval,HOUR(FROM_UNIXTIME(store_addtime)) as hourval ';
  134. $memberlist = $stat_model->getNewStoreStatList($where, $field, 0, '', 0, 'dayval,dayval');
  135. if($memberlist){
  136. foreach($memberlist as $k => $v){
  137. if($today_day == $v['dayval']){
  138. $curr_arr[$v['hourval']] = intval($v['allnum']);
  139. $currlist_arr[$v['hourval']]['val'] = intval($v['allnum']);
  140. }
  141. if($yesterday_day == $v['dayval']){
  142. $up_arr[$v['hourval']] = intval($v['allnum']);
  143. $uplist_arr[$v['hourval']]['val'] = intval($v['allnum']);
  144. }
  145. }
  146. }
  147. $stat_arr['series'][0]['name'] = lang('yestoday');
  148. $stat_arr['series'][0]['data'] = array_values($up_arr);
  149. $stat_arr['series'][1]['name'] = lang('today');
  150. $stat_arr['series'][1]['data'] = array_values($curr_arr);
  151. //统计数据标题
  152. $statlist['headertitle'] = array(lang('hour'),lang('yestoday'),lang('today'),lang('compare_to'));
  153. View::assign('actionurl',$actionurl.'&search_type=day&search_time='.date('Y-m-d',$search_time));
  154. }
  155. if($search_type == 'week'){
  156. $current_weekarr = explode('|', $current_week);
  157. $stime = strtotime($current_weekarr[0])-86400*7;
  158. $etime = strtotime($current_weekarr[1])+86400-1;
  159. $up_week = @date('W', $stime);//上周
  160. $curr_week = @date('W', $etime);//本周
  161. //构造横轴数据
  162. for($i=1; $i<=7; $i++){
  163. //统计图数据
  164. $up_arr[$i] = 0;
  165. $curr_arr[$i] = 0;
  166. $tmp_weekarr = getSystemWeekArr();
  167. //统计表数据
  168. $uplist_arr[$i]['timetext'] = $tmp_weekarr[$i];
  169. $currlist_arr[$i]['timetext'] = $tmp_weekarr[$i];
  170. //方便搜索会员列表,计算开始时间和结束时间
  171. $currlist_arr[$i]['stime'] = strtotime($current_weekarr[0])+($i-1)*86400;
  172. $currlist_arr[$i]['etime'] = $currlist_arr[$i]['stime']+86400 - 1;
  173. $uplist_arr[$i]['val'] = 0;
  174. $currlist_arr[$i]['val'] = 0;
  175. //横轴
  176. $stat_arr['xAxis']['categories'][] = $tmp_weekarr[$i];
  177. unset($tmp_weekarr);
  178. }
  179. $where[] = array('store_addtime','between',array($stime,$etime));
  180. $field .= ',WEEKOFYEAR(FROM_UNIXTIME(store_addtime)) as weekval,WEEKDAY(FROM_UNIXTIME(store_addtime))+1 as dayofweekval ';
  181. $memberlist = $stat_model->getNewStoreStatList($where, $field, 0, '', 0, 'weekval,dayofweekval');
  182. if($memberlist){
  183. foreach($memberlist as $k=>$v){
  184. if ($up_week == $v['weekval']){
  185. $up_arr[$v['dayofweekval']] = intval($v['allnum']);
  186. $uplist_arr[$v['dayofweekval']]['val'] = intval($v['allnum']);
  187. }
  188. if ($curr_week == $v['weekval']){
  189. $curr_arr[$v['dayofweekval']] = intval($v['allnum']);
  190. $currlist_arr[$v['dayofweekval']]['val'] = intval($v['allnum']);
  191. }
  192. }
  193. }
  194. $stat_arr['series'][0]['name'] = lang('last_week');
  195. $stat_arr['series'][0]['data'] = array_values($up_arr);
  196. $stat_arr['series'][1]['name'] = lang('this_week');
  197. $stat_arr['series'][1]['data'] = array_values($curr_arr);
  198. //统计数据标题
  199. $statlist['headertitle'] = array(lang('week'),lang('last_week'),lang('this_week'),lang('compare_to'));
  200. View::assign('actionurl',$actionurl.'&search_type=week&search_time_year='.$current_year.'&search_time_month='.$current_month.'&search_time_week='.$current_week);
  201. }
  202. if($search_type == 'month'){
  203. $stime = strtotime($current_year.'-'.$current_month."-01 -1 month");
  204. $etime = getMonthLastDay($current_year,$current_month)+86400-1;
  205. $up_month = date('m',$stime);
  206. $curr_month = date('m',$etime);
  207. //计算横轴的最大量(由于每个月的天数不同)
  208. $up_dayofmonth = date('t',$stime);
  209. $curr_dayofmonth = date('t',$etime);
  210. $x_max = $up_dayofmonth > $curr_dayofmonth ? $up_dayofmonth : $curr_dayofmonth;
  211. //构造横轴数据
  212. for($i=1; $i<=$x_max; $i++){
  213. //统计图数据
  214. $up_arr[$i] = 0;
  215. $curr_arr[$i] = 0;
  216. //统计表数据
  217. $uplist_arr[$i]['timetext'] = $i;
  218. $currlist_arr[$i]['timetext'] = $i;
  219. //方便搜索会员列表,计算开始时间和结束时间
  220. $currlist_arr[$i]['stime'] = strtotime($current_year.'-'.$current_month."-01")+($i-1)*86400;
  221. $currlist_arr[$i]['etime'] = $currlist_arr[$i]['stime']+86400 - 1;
  222. $uplist_arr[$i]['val'] = 0;
  223. $currlist_arr[$i]['val'] = 0;
  224. //横轴
  225. $stat_arr['xAxis']['categories'][] = $i;
  226. }
  227. $where[] = array('store_addtime','between',array($stime,$etime));
  228. $field .= ',MONTH(FROM_UNIXTIME(store_addtime)) as monthval,day(FROM_UNIXTIME(store_addtime)) as dayval ';
  229. $memberlist = $stat_model->getNewStoreStatList($where, $field, 0, '', 0,'monthval,dayval');
  230. if($memberlist){
  231. foreach($memberlist as $k=>$v){
  232. if ($up_month == $v['monthval']){
  233. $up_arr[$v['dayval']] = intval($v['allnum']);
  234. $uplist_arr[$v['dayval']]['val'] = intval($v['allnum']);
  235. }
  236. if ($curr_month == $v['monthval']){
  237. $curr_arr[$v['dayval']] = intval($v['allnum']);
  238. $currlist_arr[$v['dayval']]['val'] = intval($v['allnum']);
  239. }
  240. }
  241. }
  242. $stat_arr['series'][0]['name'] = lang('last_month');
  243. $stat_arr['series'][0]['data'] = array_values($up_arr);
  244. $stat_arr['series'][1]['name'] = lang('this_month');
  245. $stat_arr['series'][1]['data'] = array_values($curr_arr);
  246. //统计数据标题
  247. $statlist['headertitle'] = array(lang('date'),lang('last_month'),lang('this_month'),lang('compare_to'));
  248. View::assign('actionurl',$actionurl.'&search_type=month&search_time_year='.$current_year.'&search_time_month='.$current_month);
  249. }
  250. //计算同比
  251. foreach ((array)$currlist_arr as $k=>$v){
  252. $tmp = array();
  253. $tmp['seartime'] = $v['stime'].'|'.$v['etime'];
  254. $tmp['timetext'] = $v['timetext'];
  255. $tmp['currentdata'] = $v['val'];
  256. $tmp['updata'] = $uplist_arr[$k]['val'];
  257. $tmp['tbrate'] = getTb($tmp['updata'], $tmp['currentdata']);
  258. $statlist['data'][] = $tmp;
  259. }
  260. //导出Excel
  261. if (input('param.exporttype') == 'excel'){
  262. //导出Excel
  263. $excel_obj = new \excel\Excel();
  264. $excel_data = array();
  265. //设置样式
  266. $excel_obj->setStyle(array('id'=>'s_title','Font'=>array('FontName'=>'宋体','Size'=>'12','Bold'=>'1')));
  267. //header
  268. foreach ($statlist['headertitle'] as $v){
  269. $excel_data[0][] = array('styleid'=>'s_title','data'=>$v);
  270. }
  271. //data
  272. foreach ($statlist['data'] as $k=>$v){
  273. $excel_data[$k+1][] = array('data'=>$v['timetext']);
  274. $excel_data[$k+1][] = array('format'=>'Number','data'=>$v['updata']);
  275. $excel_data[$k+1][] = array('format'=>'Number','data'=>$v['currentdata']);
  276. $excel_data[$k+1][] = array('data'=>$v['tbrate']);
  277. }
  278. $excel_data = $excel_obj->charset($excel_data,CHARSET);
  279. $excel_obj->addArray($excel_data);
  280. $excel_obj->addWorksheet($excel_obj->charset(lang('add_store_statis'),CHARSET));
  281. $excel_obj->generateXML($excel_obj->charset(lang('add_store_statis'),CHARSET).date('Y-m-d-H',TIMESTAMP));
  282. exit();
  283. } else {
  284. //得到统计图数据
  285. $stat_arr['title'] = lang('add_store_statis');
  286. $stat_arr['yAxis'] = lang('add_store_number');
  287. $stat_json = getStatData_LineLabels($stat_arr);
  288. View::assign('stat_json',$stat_json);
  289. View::assign('statlist',$statlist);
  290. $this->setAdminCurItem('newstore');
  291. return View::fetch('stat_newstore');
  292. }
  293. }
  294. /**
  295. * 热卖排行
  296. */
  297. public function hotrank(){
  298. if(!isset($this->search_arr['search_type'])){
  299. $this->search_arr['search_type'] = 'day';
  300. }
  301. $stat_model = model('stat');
  302. //获得搜索的开始时间和结束时间
  303. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  304. View::assign('searchtime',implode('|',$searchtime_arr));
  305. //周
  306. if(!input('param.search_time_year')) {
  307. $search_time_year = date('Y', TIMESTAMP);
  308. }else {
  309. $search_time_year = input('param.search_time_year');
  310. }
  311. if(!input('param.search_time_month')) {
  312. $search_time_month = date('m', TIMESTAMP);
  313. }else {
  314. $search_time_month = input('param.search_time_month');
  315. }
  316. if(!input('param.search_time_week')) {
  317. $search_time_week = implode('|', getWeek_SdateAndEdate(TIMESTAMP));
  318. }else {
  319. $search_time_week = input('param.search_time_week');
  320. }
  321. $current_year =$search_time_year;
  322. $current_month =$search_time_month;
  323. $current_week = $search_time_week;
  324. View::assign('current_year', $current_year);
  325. View::assign('current_month', $current_month);
  326. View::assign('current_week', $current_week);
  327. $this->setAdminCurItem('hotrank');
  328. return View::fetch('store_hotrank');
  329. }
  330. /**
  331. * 热卖排行列表
  332. */
  333. public function hotrank_list(){
  334. $datanum = 30;
  335. $stat_model = model('stat');
  336. $type = input('param.type');
  337. switch ($type){
  338. case 'ordernum':
  339. $sort_text = lang('statstore_ordernum');
  340. break;
  341. default:
  342. $type = 'orderamount';
  343. $sort_text = lang('statstore_orderamount');
  344. break;
  345. }
  346. $where = array();
  347. $searchtime_arr_tmp = explode('|',$this->search_arr['t']);
  348. foreach ((array)$searchtime_arr_tmp as $k=>$v){
  349. $searchtime_arr[] = intval($v);
  350. }
  351. //店铺分类
  352. $search_sclass = intval(input('param.search_sclass'));
  353. if ($search_sclass){
  354. $where[] = array('storeclass_id','=',$search_sclass);
  355. }
  356. $where[] = array('order_isvalid','=',1);//计入统计的有效订单
  357. $where[] = array('order_add_time','between',$searchtime_arr);
  358. //查询统计数据
  359. $field = ' store_id,store_name ';
  360. switch ($type){
  361. case 'ordernum':
  362. $field .= ' ,COUNT(*) as ordernum ';
  363. $orderby = 'ordernum desc';
  364. break;
  365. default:
  366. $type = 'orderamount';
  367. $field .= ' ,SUM(order_amount) as orderamount ';
  368. $orderby = 'orderamount desc';
  369. break;
  370. }
  371. $orderby .= ',store_id';
  372. $statlist = $stat_model->statByStatorder($where, $field, 0, $datanum, $orderby, 'store_id');
  373. foreach ((array)$statlist as $k=>$v){
  374. $statlist[$k]['sort'] = $k+1;
  375. }
  376. /**
  377. * 飙升榜
  378. */
  379. $soaring_statlist = array();//飙升榜数组
  380. //查询期间产生订单的店铺数
  381. $where = array();
  382. //店铺分类
  383. $search_sclass = intval(input('param.search_sclass'));
  384. if ($search_sclass){
  385. $where[] = array('storeclass_id','=',$search_sclass);
  386. }
  387. $where[] = array('order_isvalid','=',1);//计入统计的有效订单
  388. $where[] = array('order_add_time','between',$searchtime_arr);
  389. $field = 'COUNT(*) as countnum';
  390. $countnum = $stat_model->getoneByStatorder($where, $field);
  391. $countnum = $countnum['countnum'];
  392. if ($countnum > 0){
  393. $store_arr = array();
  394. $field = 'store_id,store_name,order_amount';
  395. for ($i=0; $i<$countnum; $i+=1000){//由于数据库底层的限制,所以每次查询1000条
  396. $order_list = array();
  397. $order_list = Db::name('statorder')->field($field)->where($where)->page($i,1000)->order('order_id')->select()->toArray();
  398. foreach ((array)$order_list as $k=>$v){
  399. if(!isset($store_arr[$v['store_id']])){
  400. $store_arr[$v['store_id']]=array();
  401. $store_arr[$v['store_id']]['orderamount'] = 0;
  402. $store_arr[$v['store_id']]['ordernum'] = 0;
  403. }
  404. $store_arr[$v['store_id']]['orderamount'] = $store_arr[$v['store_id']]['orderamount'] + $v['order_amount'];
  405. $store_arr[$v['store_id']]['ordernum'] = intval($store_arr[$v['store_id']]['ordernum']) + 1;
  406. $store_arr[$v['store_id']]['store_name'] = $v['store_name'];
  407. $store_arr[$v['store_id']]['store_id'] = $v['store_id'];
  408. }
  409. }
  410. //查询同一时间周期相比的环比数值
  411. $where = array();
  412. $stime = $searchtime_arr[0] - ($searchtime_arr[1] - $searchtime_arr[0]) - 1;
  413. $etime = $searchtime_arr[0] - 1;
  414. //店铺分类
  415. $search_sclass = intval($_REQUEST['search_sclass']);
  416. if ($search_sclass){
  417. $where[] = array('storeclass_id','=',$search_sclass);
  418. }
  419. $where[] = array('order_isvalid','=',1);//计入统计的有效订单
  420. $where[] = array('order_add_time','between',array($stime,$etime));
  421. $field = 'COUNT(*) as up_countnum';
  422. $up_countnum = $stat_model->getoneByStatorder($where, $field);
  423. $up_countnum = $up_countnum['up_countnum'];
  424. $up_store_arr = array();
  425. if ($up_countnum > 0){
  426. $field = 'store_id,store_name,order_amount';
  427. for ($i=0; $i<$up_countnum; $i+=1000){//由于数据库底层的限制,所以每次查询1000条
  428. $order_list = array();
  429. $order_list = Db::name('statorder')->field($field)->where($where)->page($i,1000)->order('store_id')->select()->toArray();
  430. foreach ((array)$order_list as $k=>$v){
  431. if(!isset($up_store_arr[$v['store_id']])){
  432. $up_store_arr[$v['store_id']]=array('orderamount'=>0,'ordernum'=>0);
  433. }
  434. $up_store_arr[$v['store_id']]['orderamount'] = $up_store_arr[$v['store_id']]['orderamount'] + $v['order_amount'];
  435. $up_store_arr[$v['store_id']]['ordernum'] = intval($up_store_arr[$v['store_id']]['ordernum']) + 1;
  436. }
  437. }
  438. }
  439. //计算环比飙升数值
  440. $soaring_arr = array();
  441. foreach ((array)$store_arr as $k=>$v){
  442. if (isset($up_store_arr[$k][$type]) && $up_store_arr[$k][$type] > 0){//上期数值大于0,则计算飙升值,否则不计入统计
  443. $soaring_arr[$k] = round((($v[$type]-$up_store_arr[$k][$type])/$up_store_arr[$k][$type]*100),2);
  444. }
  445. }
  446. arsort($soaring_arr);//降序排列数组
  447. $i = 1;
  448. //取出前10名飙升店铺
  449. foreach ((array)$soaring_arr as $k=>$v){
  450. if ($i <= $datanum){
  451. $tmp = array();
  452. $tmp['sort'] = $i;
  453. $tmp['store_name'] = $store_arr[$k]['store_name'];
  454. $tmp['store_id'] = $store_arr[$k]['store_id'];
  455. $tmp['hb'] = $v;
  456. switch ($type){
  457. case 'ordernum':
  458. $tmp['ordernum'] = $store_arr[$k]['ordernum'];
  459. break;
  460. case 'orderamount':
  461. $tmp['orderamount'] = ds_price_format($store_arr[$k]['orderamount']);
  462. break;
  463. }
  464. $soaring_statlist[] = $tmp;
  465. $i++;
  466. } else {
  467. break;
  468. }
  469. }
  470. }
  471. View::assign('soaring_statlist',$soaring_statlist);
  472. View::assign('statlist',$statlist);
  473. View::assign('sort_text',$sort_text);
  474. View::assign('stat_field',$type);
  475. echo View::fetch('store_hotrank_list');
  476. }
  477. /**
  478. * 店铺等级
  479. */
  480. public function degree(){
  481. $where = array();
  482. $field = ' count(*) as allnum,grade_id ';
  483. $stat_model = model('stat');
  484. //查询店铺分类下的店铺
  485. $search_sclass = input('param.search_sclass');
  486. if ($search_sclass > 0){
  487. $where[] = array('storeclass_id','=',$search_sclass);
  488. }
  489. $storelist = $stat_model->getNewStoreStatList($where, $field, 0, '', 0, 'grade_id');
  490. $sd_list = $stat_model->getStoreDegree();
  491. $statlist['headertitle'] = array();
  492. $statlist['data'] = array();
  493. //处理数组数据
  494. if(!empty($storelist)){
  495. foreach ($storelist as $k=>$v){
  496. $storelist[$k]['p_name'] = isset($sd_list[$v['grade_id']]) > 0 ? $sd_list[$v['grade_id']]:lang('ds_ownshop');
  497. $storelist[$k]['allnum'] = intval($v['allnum']);
  498. $statlist['headertitle'][] = isset($sd_list[$v['grade_id']]) > 0?$sd_list[$v['grade_id']]:lang('ds_ownshop');
  499. $statlist['data'][] = $v['allnum'];
  500. }
  501. $data = array(
  502. 'title'=>lang('store_grade_statis'),
  503. 'name'=>lang('store_number'),
  504. 'label_show'=>true,
  505. 'series'=>$storelist
  506. );
  507. View::assign('stat_json',getStatData_Pie($data));
  508. }
  509. $this->setAdminCurItem('degree');
  510. return View::fetch('stat_storedegree');
  511. }
  512. /**
  513. * 查看店铺列表
  514. */
  515. public function showstore(){
  516. $stat_model = model('stat');
  517. $where = array();
  518. if (in_array(input('type'),array('newbyday','newbyweek','newbymonth','storearea'))){
  519. $actionurl = (string)url('Statstore/showstore',['type'=>input('type'),'t'=>$this->search_arr['t']]);
  520. $searchtime_arr_tmp = explode('|',$this->search_arr['t']);
  521. foreach ((array)$searchtime_arr_tmp as $k=>$v){
  522. $searchtime_arr[] = intval($v);
  523. }
  524. $where[] = array('store_addtime','between',$searchtime_arr);
  525. }
  526. //商品分类
  527. $storeclass_id = intval(input('scid'));
  528. if ($storeclass_id > 0){
  529. $where[] = array('storeclass_id','=',$storeclass_id);
  530. $actionurl .="&scid=$storeclass_id";
  531. }
  532. //省份
  533. if (input('provid')){
  534. $province_id = intval(input('param.provid'));
  535. $where[] = array('province_id','=',$province_id);
  536. $actionurl .="&provid=$province_id";
  537. }
  538. if (input('exporttype') == 'excel'){
  539. $store_list = $stat_model->getNewStoreStatList($where);
  540. } else {
  541. $store_list = $stat_model->getNewStoreStatList($where, '', 10);
  542. }
  543. //店铺等级
  544. $storegrade_model = model('storegrade');
  545. $grade_list = $storegrade_model->getStoregradeList();
  546. if (!empty($grade_list)){
  547. $search_grade_list = array();
  548. foreach ($grade_list as $k => $v){
  549. $search_grade_list[$v['storegrade_id']] = $v['storegrade_name'];
  550. }
  551. }
  552. //导出Excel
  553. if (input('exporttype') == 'excel'){
  554. //导出Excel
  555. $excel_obj = new \excel\Excel();
  556. $excel_data = array();
  557. //设置样式
  558. $excel_obj->setStyle(array('id'=>'s_title','Font'=>array('FontName'=>'宋体','Size'=>'12','Bold'=>'1')));
  559. //header
  560. $excel_data[0][] = array('styleid'=>'s_title','data'=>lang('ds_store_name'));
  561. $excel_data[0][] = array('styleid'=>'s_title','data'=>lang('ds_member_name'));
  562. $excel_data[0][] = array('styleid'=>'s_title','data'=>lang('ds_seller_name'));
  563. $excel_data[0][] = array('styleid'=>'s_title','data'=>lang('stat_storedegree'));
  564. $excel_data[0][] = array('styleid'=>'s_title','data'=>lang('statstore_expire'));
  565. $excel_data[0][] = array('styleid'=>'s_title','data'=>lang('statstore_addtime'));
  566. //data
  567. foreach ($store_list as $k=>$v){
  568. $excel_data[$k+1][] = array('data'=>$v['store_name']);
  569. $excel_data[$k+1][] = array('data'=>$v['member_name']);
  570. $excel_data[$k+1][] = array('data'=>$v['seller_name']);
  571. $excel_data[$k+1][] = array('data'=>$search_grade_list[$v['grade_id']]);
  572. $excel_data[$k+1][] = array('data'=>$v['store_endtime']?date('Y-m-d', $v['store_endtime']):lang('state_no_tile_limit'));
  573. $excel_data[$k+1][] = array('data'=>date('Y-m-d', $v['store_addtime']));
  574. }
  575. $excel_data = $excel_obj->charset($excel_data,CHARSET);
  576. $excel_obj->addArray($excel_data);
  577. $excel_obj->addWorksheet($excel_obj->charset(lang('ds_new').lang('ds_store'),CHARSET));
  578. $excel_obj->generateXML($excel_obj->charset(lang('ds_new').lang('ds_store'),CHARSET).date('Y-m-d-H',TIMESTAMP));
  579. exit();
  580. }
  581. View::assign('search_grade_list', $search_grade_list);
  582. View::assign('actionurl',$actionurl);
  583. View::assign('store_list',$store_list);
  584. View::assign('show_page',$stat_model->page_info->render());
  585. $this->setAdminCurItem('showstore');
  586. return View::fetch('storelist');
  587. }
  588. /**
  589. * 销售统计
  590. */
  591. public function storesales(){
  592. if(!isset($this->search_arr['search_type'])){
  593. $this->search_arr['search_type'] = 'day';
  594. }
  595. $stat_model = model('stat');
  596. //获得搜索的开始时间和结束时间
  597. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  598. View::assign('searchtime',implode('|',$searchtime_arr));
  599. //周
  600. if(!input('param.search_time_year')) {
  601. $search_time_year = date('Y', TIMESTAMP);
  602. }else {
  603. $search_time_year = input('param.search_time_year');
  604. }
  605. if(!input('param.search_time_month')) {
  606. $search_time_month = date('m', TIMESTAMP);
  607. }else {
  608. $search_time_month = input('param.search_time_month');
  609. }
  610. if(!input('param.search_time_week')) {
  611. $search_time_week = implode('|', getWeek_SdateAndEdate(TIMESTAMP));
  612. }else {
  613. $search_time_week = input('param.search_time_week');
  614. }
  615. $current_year =$search_time_year;
  616. $current_month =$search_time_month;
  617. $current_week = $search_time_week;
  618. View::assign('current_year', $current_year);
  619. View::assign('current_month', $current_month);
  620. View::assign('current_week', $current_week);
  621. $this->setAdminCurItem('storesales');
  622. return View::fetch('stat_store_sales');
  623. }
  624. /**
  625. * 店铺销售统计列表
  626. */
  627. public function storesales_list(){
  628. $stat_model = model('stat');
  629. $searchtime_arr_tmp = explode('|',$this->search_arr['t']);
  630. foreach ((array)$searchtime_arr_tmp as $k=>$v){
  631. $searchtime_arr[] = intval($v);
  632. }
  633. $where = array();
  634. $where[] = array('order_isvalid','=',1);//计入统计的有效订单
  635. $where[] = array('order_add_time','between',$searchtime_arr);
  636. //店铺分类
  637. $search_sclass = intval(input('param.search_sclass'));
  638. if ($search_sclass){
  639. $where[]=array('storeclass_id','=',$search_sclass);
  640. }
  641. //店铺名称
  642. $where[]=array('store_name','like',"%".input('param.search_sname')."%");
  643. //查询总条数
  644. $count_arr = $stat_model->getoneByStatorder($where, 'COUNT(DISTINCT store_id) as countnum');
  645. $countnum = intval($count_arr['countnum']);
  646. //列表字段
  647. $field = " store_id,store_name,SUM(order_amount) as orderamount, COUNT(*) as ordernum, COUNT(DISTINCT buyer_id) as membernum";
  648. //排序
  649. $orderby_arr = array('membernum asc','membernum desc','ordernum asc','ordernum desc','orderamount asc','orderamount desc');
  650. if (!isset($this->search_arr['orderby'])||!in_array(trim($this->search_arr['orderby']),$orderby_arr)){
  651. $this->search_arr['orderby'] = 'membernum desc';
  652. }
  653. $orderby = trim($this->search_arr['orderby']).',store_id asc';
  654. if (isset($this->search_arr['exporttype'])&&$this->search_arr['exporttype'] == 'excel'){
  655. $statlist = $stat_model->statByStatorder($where, $field, 0, 0, $orderby, 'store_id');
  656. } else {
  657. $statlist = $stat_model->statByStatorder($where, $field, 20, 0, $orderby, 'store_id');
  658. foreach ((array)$statlist as $k=>$v){
  659. $v['view'] = "<a href='javascript:void(0);' ds_type='showtrends' data-param='{\"storeid\":\"{$v['store_id']}\"}'>走势图</a>";
  660. $statlist[$k] = $v;
  661. }
  662. }
  663. //列表header
  664. $statheader = array();
  665. $statheader[] = array('text'=>lang('ds_store_name'),'key'=>'store_name');
  666. $statheader[] = array('text'=>lang('membernum'),'key'=>'membernum','isorder'=>1);
  667. $statheader[] = array('text'=>lang('statstore_ordernum'),'key'=>'ordernum','isorder'=>1);
  668. $statheader[] = array('text'=>lang('statstore_orderamount'),'key'=>'orderamount','isorder'=>1);
  669. //导出Excel
  670. if (isset($this->search_arr['exporttype'])&&$this->search_arr['exporttype'] == 'excel'){
  671. //导出Excel
  672. $excel_obj = new \excel\Excel();
  673. $excel_data = array();
  674. //设置样式
  675. $excel_obj->setStyle(array('id'=>'s_title','Font'=>array('FontName'=>'宋体','Size'=>'12','Bold'=>'1')));
  676. //header
  677. foreach ($statheader as $k=>$v){
  678. $excel_data[0][] = array('styleid'=>'s_title','data'=>$v['text']);
  679. }
  680. //data
  681. foreach ($statlist as $k=>$v){
  682. foreach ($statheader as $h_k=>$h_v){
  683. $excel_data[$k+1][] = array('data'=>$v[$h_v['key']]);
  684. }
  685. }
  686. $excel_data = $excel_obj->charset($excel_data,CHARSET);
  687. $excel_obj->addArray($excel_data);
  688. $excel_obj->addWorksheet($excel_obj->charset(lang('store_sale_statis'),CHARSET));
  689. $excel_obj->generateXML($excel_obj->charset(lang('store_sale_statis'),CHARSET).date('Y-m-d-H',TIMESTAMP));
  690. exit();
  691. }
  692. View::assign('statlist',$statlist);
  693. View::assign('statheader',$statheader);
  694. View::assign('orderby',$this->search_arr['orderby']);
  695. View::assign('actionurl',(string)url('Statstore/storesales_list',['t'=>$this->search_arr['t'],'search_sclass'=>$search_sclass,'search_sname'=>input('param.search_sname')]));
  696. View::assign('show_page',$stat_model->page_info->render());
  697. echo View::fetch('stat_listandorder');
  698. }
  699. /**
  700. * 销售走势
  701. */
  702. public function storesales_trends(){
  703. $storeid = intval(input('param.storeid'));
  704. if ($storeid <= 0){
  705. View::assign('stat_error',lang('stat_error'));
  706. return View::fetch('salestrends');
  707. exit();
  708. }
  709. $search_type=input('param.search_type');
  710. if (!$search_type){
  711. $search_type= 'day';
  712. }
  713. $stat_model = model('stat');
  714. $where = array();
  715. $where[] = array('store_id','=',$storeid);
  716. $searchtime_arr_tmp = explode('|',$this->search_arr['t']);
  717. foreach ((array)$searchtime_arr_tmp as $k=>$v){
  718. $searchtime_arr[] = intval($v);
  719. }
  720. $where[] = array('order_isvalid','=',1);//计入统计的有效订单
  721. $where[] = array('order_add_time','between',$searchtime_arr);
  722. $field = " store_id,store_name,SUM(order_amount) as orderamount, COUNT(*) as ordernum, COUNT(DISTINCT buyer_id) as membernum";
  723. $stat_arr = array('orderamount'=>array(),'ordernum'=>array(),'membernum'=>array());
  724. $statlist = array();
  725. if($search_type == 'day'){
  726. //构造横轴数据
  727. for($i=0; $i<24; $i++){
  728. //横轴
  729. foreach ($stat_arr as $k=>$v){
  730. $stat_arr[$k]['xAxis']['categories'][] = "$i";
  731. $statlist[$k][$i] = 0;
  732. }
  733. }
  734. $field .= ' ,HOUR(FROM_UNIXTIME(order_add_time)) as timeval ';
  735. }
  736. if($search_type == 'week'){
  737. //构造横轴数据
  738. for($i=1; $i<=7; $i++){
  739. $tmp_weekarr = getSystemWeekArr();
  740. //横轴
  741. foreach ($stat_arr as $k=>$v){
  742. $stat_arr[$k]['xAxis']['categories'][] = $tmp_weekarr[$i];
  743. $statlist[$k][$i] = 0;
  744. }
  745. unset($tmp_weekarr);
  746. }
  747. $field .= ' ,WEEKDAY(FROM_UNIXTIME(order_add_time))+1 as timeval ';
  748. }
  749. if($search_type == 'month'){
  750. //计算横轴的最大量(由于每个月的天数不同)
  751. $dayofmonth = date('t',$searchtime_arr[0]);
  752. //构造横轴数据
  753. for($i=1; $i<=$dayofmonth; $i++){
  754. //横轴
  755. foreach ($stat_arr as $k=>$v){
  756. $stat_arr[$k]['xAxis']['categories'][] = $i;
  757. $statlist[$k][$i] = 0;
  758. }
  759. }
  760. $field .= ' ,day(FROM_UNIXTIME(order_add_time)) as timeval ';
  761. }
  762. //查询数据
  763. $statlist_tmp = $stat_model->statByStatorder($where, $field, 0, '');
  764. //整理统计数组
  765. $storename = '';
  766. if($statlist_tmp){
  767. foreach($statlist_tmp as $k => $v){
  768. $storename = $v['store_name'];
  769. foreach ($stat_arr as $t_k=>$t_v){
  770. if ($k == 'orderamount'){
  771. $statlist[$t_k][$v['timeval']] = round($v[$t_k],2);
  772. } else {
  773. $statlist[$t_k][$v['timeval']] = intval($v[$t_k]);
  774. }
  775. }
  776. }
  777. }
  778. foreach ($stat_arr as $k=>$v){
  779. $stat_arr[$k]['legend']['enabled'] = false;
  780. switch ($k){
  781. case 'orderamount':
  782. $caption = lang('statstore_orderamount');
  783. break;
  784. case 'ordernum':
  785. $caption = lang('statstore_ordernum');
  786. break;
  787. default:
  788. $caption = lang('membernum');
  789. break;
  790. }
  791. $stat_arr[$k]['series'][0]['name'] = $caption;
  792. $stat_arr[$k]['series'][0]['data'] = array_values($statlist[$k]);
  793. $stat_arr[$k]['title'] = $caption.lang('sale_trend');
  794. $stat_arr[$k]['yAxis'] = $caption;
  795. //得到统计图数据
  796. $stat_json[$k] = getStatData_LineLabels($stat_arr[$k]);
  797. }
  798. View::assign('storename',$storename);
  799. View::assign('stat_json',$stat_json);
  800. echo View::fetch('store_salestrends');
  801. }
  802. /**
  803. * 地区分布
  804. */
  805. public function storearea(){
  806. $stat_model = model('stat');
  807. //获得搜索的开始时间和结束时间
  808. $searchtime_arr = $stat_model->getStarttimeAndEndtime($this->search_arr);
  809. $where = array();
  810. if (trim(input('param.search_time'))){
  811. $where[]=array('store_addtime','<=',strtotime(input('param.search_time')));
  812. }
  813. $search_sclass = intval(input('param.search_sclass'));
  814. if ($search_sclass > 0){
  815. $where[]=array('storeclass_id','=',$search_sclass);
  816. }
  817. $field = ' region_id, COUNT(*) as storenum ';
  818. $statlist_tmp = $stat_model->statByStore($where, $field, 'region_id', 'region_id');
  819. // 地区
  820. $province_array = model('area')->getTopLevelAreas();
  821. //地图显示等级数组
  822. $level_arr = array(array(1,2,3),array(4,5,6),array(7,8,9),array(10,11,12));
  823. $statlist = array();
  824. $temp_list=array();
  825. foreach ((array)$statlist_tmp as $k=>$v){
  826. $v['level'] = 4;//排名
  827. foreach ($level_arr as $lk=>$lv){
  828. if (in_array($k+1,$lv)){
  829. $v['level'] = $lk;//排名
  830. }
  831. }
  832. //获取该地区的省
  833. if($v['region_id']){
  834. if(!isset($temp_list[$v['region_id']])){
  835. $temp=Db::name('area')->where('area_id='.$v['region_id'])->value('area_parent_id');
  836. if($temp){
  837. $temp_list[$v['region_id']]=$temp;
  838. }else{
  839. $temp_list[$v['region_id']]=$v['region_id'];
  840. }
  841. $index=0;
  842. while($temp && $index<4){
  843. $temp_list[$v['region_id']]=$temp;
  844. $temp_0=$temp;
  845. $temp=Db::name('area')->where('area_id='.$temp)->value('area_parent_id');
  846. if($temp){
  847. $temp_list[$temp_0]=$temp;
  848. }else{
  849. $temp_list[$temp_0]=$temp_0;
  850. }
  851. $index++;
  852. }
  853. }
  854. $province_id = $temp_list[$v['region_id']];
  855. }else{
  856. $province_id=0;
  857. }
  858. $v['sort'] = $k+1;
  859. $v['provincename'] = isset($province_array[$province_id]) ? $province_array[$province_id] : lang('other');
  860. if(!isset($statlist[$province_id])){
  861. $statlist[$province_id] = $v;
  862. }else{
  863. $statlist[$province_id]['storenum'] += $v['storenum'];
  864. }
  865. }
  866. $stat_arr = array();
  867. foreach ((array)$province_array as $k=>$v){
  868. if (isset($statlist[$k])){
  869. $stat_arr[] = array('cha'=>$k,'name'=>$v,'des'=>",店铺量:{$statlist[$k]['storenum']}",'level'=>$statlist[$k]['level']);
  870. } else {
  871. $stat_arr[] = array('cha'=>$k,'name'=>$v,'des'=>',无订单数据','level'=>4);
  872. }
  873. }
  874. $stat_json = getStatData_Map($stat_arr);
  875. View::assign('stat_json',$stat_json);
  876. View::assign('statlist',$statlist);
  877. $actionurl = (string)url('Statstore/storearea');
  878. if (trim(input('param.search_time'))){
  879. $actionurl = $actionurl.'&t=0|'.strtotime(input('param.search_time'));
  880. }
  881. if ($search_sclass > 0){
  882. $actionurl .= "&scid=$search_sclass";
  883. }
  884. View::assign('actionurl',$actionurl);
  885. $this->setAdminCurItem('storearea');
  886. return View::fetch('stat_storearea');
  887. }
  888. protected function getAdminItemList()
  889. {
  890. $menu_array = array(
  891. array('name'=>'newstore','text'=>lang('stat_newstore'),'url'=>(string)url('Statstore/newstore')),
  892. array('name'=>'hotrank','text'=>lang('stat_storehotrank'),'url'=>(string)url('Statstore/hotrank')),
  893. array('name'=>'storesales','text'=>lang('stat_storesales'),'url'=>(string)url('Statstore/storesales')),
  894. array('name'=>'degree','text'=>lang('stat_storedegree'),'url'=>(string)url('Statstore/degree')),
  895. array('name'=>'storearea','text'=>lang('stat_storearea'),'url'=>(string)url('Statstore/storearea')),
  896. );
  897. return $menu_array;
  898. }
  899. }