Statstore.php 43 KB

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