CouponsCountViewController.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. <?php
  2. /**
  3. * 根据优惠券统计订单控制器
  4. * @author 2015-10-13
  5. */
  6. class CouponsCountViewController extends AdminController {
  7. /**
  8. * 首页
  9. */
  10. public function actionIndex () {
  11. $status_option = Coupon::$status_option;
  12. $time_range = array(
  13. 'noSelect' => array('name' => '未选择'),
  14. 'Months' => array('name' => '最近半年'),
  15. 'Weeks' => array('name' => '最近一月'),
  16. 'Days' => array('name' => '最近一周')
  17. );
  18. $status_filter = CommonFn::getComboboxData($status_option, 1, true, 100);
  19. $time_filter = CommonFn::getComboboxData($time_range, 'noSelect', false, '');
  20. $data = array(
  21. 'status_filter' => $status_filter,
  22. 'time_filter' => $time_filter
  23. );
  24. $this->render('index', $data);
  25. }
  26. /**
  27. * 显示列表
  28. */
  29. public function actionList () {
  30. // echo json_encode(array());return;
  31. $date_start = Yii::app()->request->getParam('date_start', '');
  32. $date_end = Yii::app()->request->getParam('date_end', '');
  33. $status = intval(Yii::app()->request->getParam('status', 100));
  34. if (!empty($date_start) && !empty($date_end)) {
  35. $date_start = strtotime($date_start);
  36. $int_start_date = intval(date('Ymd',$date_start));
  37. $date_end = strtotime('+1 day', strtotime($date_end));
  38. $int_end_date = intval(date('Ymd',$date_end));
  39. } else {
  40. $date_start = 0;
  41. $int_start_date = intval(date('Ymd'));
  42. $date_end = 0;
  43. $int_end_date = intval(date('Ymd')) + 1;
  44. }
  45. $criteria = new EMongoCriteria();
  46. $criteria->date('>=',$int_start_date);
  47. $criteria->date('<',$int_end_date);
  48. $count_list = OfflineOrderCount::model()->findAll($criteria);
  49. $offline_order_sum['title'] = '线下推广用户完成首单数';
  50. $offline_order_sum['value'] = 0;
  51. foreach ($count_list as $offline_order_count) {
  52. $offline_order_sum['value'] += $offline_order_count->count;
  53. }
  54. $data = $this->getAll($date_start, $date_end, true, $status, true);
  55. $total = $data['total'];
  56. $data = $data['data'];
  57. $offline = array(array(
  58. 'price' => 0,
  59. 'final_price' => 0,
  60. 'count' => $offline_order_sum['value'],
  61. 'id' => '',
  62. 'name' => $offline_order_sum['title'],
  63. 'memo' => '',
  64. 'status' => 1,
  65. 'status_str' => '正常',
  66. 'alias_name' => '',
  67. ));
  68. $data = array_merge($offline,$data);
  69. echo CommonFn::composeDatagridData($data, $total);
  70. }
  71. /**
  72. * 返回数据生成柱状图
  73. */
  74. public function actionGetChartBar () {
  75. $time_filter = Yii::app()->request->getParam('time_filter', 'noSelect');
  76. $status_filter = intval(Yii::app()->request->getParam('status_filter', 100));
  77. $date_start = Yii::app()->request->getParam('date_start', '');
  78. $date_end = Yii::app()->request->getParam('date_end', '');
  79. if ($time_filter == 'noSelect') {
  80. $data = array();
  81. } else {
  82. // 默认查询一周数据
  83. if (empty($date_start) || empty($date_end)) {
  84. $date_range = $this->getDateRnage($time_filter);
  85. $date_start = $date_range['date_start'];
  86. $date_end = $date_range['date_end'];
  87. } else {
  88. $date_start = strtotime($date_start);
  89. $date_end = strtotime('+1 day', strtotime($date_end));
  90. }
  91. $data = $this->getBarData($status_filter, $time_filter, $date_start, $date_end);
  92. }
  93. echo json_encode($data);
  94. }
  95. /**
  96. * 返回数据生成饼状图
  97. */
  98. public function actionGetChartPie () {
  99. $time_filter = Yii::app()->request->getParam('time_filter', 'noSelect');
  100. $status_filter = intval(Yii::app()->request->getParam('status_filter', 100));
  101. $date_start = Yii::app()->request->getParam('date_start', '');
  102. $date_end = Yii::app()->request->getParam('date_end', '');
  103. // 时间范围处理
  104. // 检查是否填写了时间范围
  105. if (!empty($date_start) && !empty($date_end)) {
  106. $date_start = strtotime($date_start);
  107. $date_end = strtotime('+1 day', strtotime($date_end));
  108. // 否则挑选时间范围
  109. } else {
  110. // 获取时间点
  111. if ($time_filter != 'noSelect') {
  112. $date_range = $this->getDateRnage($time_filter);
  113. $date_start = $date_range['date_start'];
  114. $date_end = $date_range['date_end'];
  115. // 查询所有数据
  116. } else {
  117. $date_start = $date_end = 0;
  118. }
  119. }
  120. $data = $this->getPieData($status_filter, $date_start, $date_end);
  121. echo json_encode($data);
  122. }
  123. /**
  124. * 返回数据生成单个优惠券的柱状图及折线图
  125. */
  126. public function actionGetChartById () {
  127. $id = Yii::app()->request->getParam('id', '');
  128. $date_start = Yii::app()->request->getParam('date_start', '');
  129. $date_end = Yii::app()->request->getParam('date_end', '');
  130. $time_filter = Yii::app()->request->getParam('time_filter', 'noSelect');
  131. $filter_week = Yii::app()->request->getParam('filter_week', 0);
  132. if ($id == '' || $time_filter == 'noSelct') {
  133. echo json_encode(array());
  134. return false;
  135. }
  136. $coupon_id = new MongoId($id);
  137. // 检查是否选择了时间范围
  138. if ($time_filter != 'Days' || ($filter_week == 1 && $time_filter == 'Days')) {
  139. $date_range = $this->getDateRnage($time_filter);
  140. $date_start = $date_range['date_start'];
  141. $date_end = $date_range['date_end'];
  142. // 否则获取具体时间
  143. } else if (!empty($date_start) && !empty($date_end)) {
  144. $date_start = strtotime($date_start);
  145. $date_end = strtotime('+1 day', strtotime($date_end));
  146. } else {
  147. echo json_encode(array());
  148. return false;
  149. }
  150. $data = $this->getBarDataById($coupon_id, $time_filter, $date_start, $date_end);
  151. echo json_encode($data);
  152. }
  153. /**
  154. * ----------------------------------
  155. *
  156. * 私有方法,对数据进行整理
  157. *
  158. * ----------------------------------
  159. */
  160. /**
  161. * 获取所有数据的统计
  162. * @param timestamp $date_start : 开始的日期
  163. * @param timestamp $date_end : 结束的日期
  164. * @param boolean $empty_data : 是否加入空数据
  165. * @param number $status_filter : 状态筛选,默认查询所有状态
  166. * @param boolean $pageParam : 是否加入分页信息
  167. */
  168. private function getAll ($date_start = 0, $date_end = 0, $empty_data = false, $status_filter = 100, $pageParam = false) {
  169. $data = array();
  170. $coupons = $this->getCoupons($status_filter, $pageParam);
  171. if ($pageParam) {
  172. $data['total'] = $coupons['total'];
  173. $coupons = $coupons['rows'];
  174. if ($data['total'] == 0) {
  175. return array('total' => 0, 'data' => array());
  176. }
  177. }
  178. foreach ($coupons as $key => $value) {
  179. $alias_name = isset($value['alias_name']) ? $value['alias_name'] : '';
  180. $data_temp = array(
  181. 'price' => 0,
  182. 'final_price' => 0,
  183. 'count' => 0,
  184. 'id' => (string)$value['_id'],
  185. 'name' => $value['name'].'('.$alias_name.')',
  186. 'memo' => $value['memo'],
  187. 'status' => $value['status'],
  188. 'status_str' => $this->getStatusStr($value['status']),
  189. 'alias_name' => $alias_name
  190. );
  191. $orderRows = $this->getOrderRows($value['_id'], $date_start, $date_end);
  192. if (empty($orderRows)) {
  193. if ($empty_data) {
  194. $data['data'][] = $data_temp;
  195. }
  196. continue;
  197. }
  198. foreach ($orderRows as $k => $v) {
  199. $data_temp['price'] += $v['price'];
  200. $data_temp['final_price'] += $v['final_price'];
  201. }
  202. $data_temp['count'] = count($orderRows);
  203. $data['data'][] = $data_temp;
  204. }
  205. return $data;
  206. }
  207. /**
  208. * 根据状态获取优惠券数组
  209. * @param number $status : 状态码,默认为100(所有状态)
  210. * @param boolean $pageParam : 是否加入分页信息
  211. */
  212. private function getCoupons ($status_filter = 100, $pageParam = false) {
  213. $pageParams = CommonFn::getPageParams();
  214. $criteria = $pageParam ? new EMongoCriteria($pageParams) : new EMongoCriteria();
  215. if ($status_filter != 100) $criteria->status('==', $status_filter);
  216. $cursor = Coupon::model()->findAll($criteria);
  217. $rows = CommonFn::getRowsFromCursor($cursor);
  218. $total = count($cursor);
  219. if ($pageParam) {
  220. $rows['rows'] = $rows;
  221. $rows['total'] = $total;
  222. }
  223. return $rows;
  224. }
  225. /**
  226. * 根据优惠券ID获取使用该优惠券的所有订单
  227. * @param MongoID $coupon_id : 优惠券ID,来自于coupon表
  228. * @param timestamp $date_start : 开始的时间,默认为0(查询所有)
  229. * @param timestamp $date_end : 结束的时间,默认为0(查询所有)
  230. */
  231. private function getOrderRows ($coupon_id, $date_start = 0, $date_end = 0) {
  232. $criteria = new EMongoCriteria();
  233. $criteria->coupon('==', $coupon_id);
  234. $criteria->status('==', -1);
  235. $cursor = UserCoupon::model()->findAll($criteria);
  236. $rows = CommonFn::getRowsFromCursor($cursor);
  237. $userCoupons = array();
  238. foreach ($rows as $value) {
  239. $userCoupons[] = $value['_id'];
  240. }
  241. $criteria = new EMongoCriteria();
  242. $criteria->coupons('in', $userCoupons);
  243. $criteria->status('>=', 1);
  244. if ($date_start != 0 && $date_end != 0) {
  245. $criteria->order_time('>=', $date_start);
  246. $criteria->order_time('<', $date_end);
  247. }
  248. $criteria->sort('order_time', EMongoCriteria::SORT_ASC);
  249. $cursor = ROrder::model()->findAll($criteria);
  250. $rows = CommonFn::getRowsFromCursor($cursor);
  251. return $rows;
  252. }
  253. /**
  254. * 获取时间范围
  255. * @return array $date_range : 时间范围数组,包括查询开始及结束的时间
  256. */
  257. private function getDateRnage ($time_filter) {
  258. // ------ 最近一月的时间点 ------
  259. if ($time_filter == 'Weeks') {
  260. $date_end = strtotime('monday', time());
  261. if (strtotime(date('Y-m-d', time())) == $date_end) {
  262. $date_end = strtotime('+7 day', $date_end);
  263. }
  264. $date_start = strtotime('-35 day', $date_end);
  265. // ------ 最近半年的时间点 ------
  266. } else if ($time_filter == 'Months') {
  267. $date_end = strtotime(date('Y-m', strtotime('+1 month', time())));
  268. $date_start = strtotime(date('Y-m', strtotime('-5 month', time())));
  269. // ------ 最近一周的时间点 ------
  270. } else {
  271. $date_end = strtotime(date('Y-m-d', strtotime('+1 day', time())));
  272. $date_start = strtotime(date('Y-m-d', strtotime('-6 day', time())));
  273. }
  274. $date_range = array(
  275. 'date_start' => $date_start,
  276. 'date_end' => $date_end
  277. );
  278. return $date_range;
  279. }
  280. /**
  281. * 获取柱状图数据,默认显示近一周的数据
  282. */
  283. private function getBarData ($status_filter, $time_filter, $date_start, $date_end) {
  284. // 获取优惠券数组
  285. $coupons = $this->getCoupons($status_filter);
  286. // 整理函数的选取
  287. $parseMethod = 'parseDataBy'.$time_filter;
  288. $data = array();
  289. $coupons_arr = array();
  290. foreach ($coupons as $key => $value) {
  291. $orderRows = $this->getOrderRows($value['_id'], $date_start, $date_end);
  292. // parseDataByDays()/parseDataByWeeks()/parseDataByMonths()
  293. $data_temp = $this->$parseMethod($orderRows, $date_start, $date_end);
  294. $alias_name = isset($value['alias_name']) ? $value['alias_name'] : '';
  295. $data_temp['coupon'] = $value['name'].'('.$alias_name.')';
  296. $coupons_arr[] = $value['name'].'('.$alias_name.')';
  297. $data['content'][] = $data_temp;
  298. }
  299. $getDateArrMethod = 'get'.$time_filter.'Arr';
  300. $data['date_arr'] = $this->$getDateArrMethod($date_start, $date_end);
  301. $data['coupons'] = $coupons_arr;
  302. return $data;
  303. }
  304. /**
  305. * 获取饼图数据,默认显示所有数据
  306. */
  307. private function getPieData ($status_filter = 100, $date_start = 0, $date_end = 0) {
  308. $data = array();
  309. $price = array();
  310. $final_price = array();
  311. $count = array();
  312. $coupons = array();
  313. $data_all = $this->getAll($date_start, $date_end, true, $status_filter, false);
  314. $data_all = $data_all['data'];
  315. $data_temp = array();
  316. foreach ($data_all as $key => $value) {
  317. $data_temp['price'] = $value['price'];
  318. $data_temp['final_price'] = $value['final_price'];
  319. $data_temp['count'] = $value['count'];
  320. $data_temp['coupon'] = $value['name'];
  321. $coupons[] = $value['name'];
  322. $data['content'][] = $data_temp;
  323. }
  324. $data['coupons'] = $coupons;
  325. return $data;
  326. }
  327. /**
  328. * 获取单个优惠券类型的数据,默认显示近一周的数据
  329. */
  330. public function getBarDataById ($coupon_id, $time_filter, $date_start, $date_end) {
  331. // 整理函数的选取
  332. $parseMethod = 'parseDataBy'.$time_filter;
  333. $orderRows = $this->getOrderRows($coupon_id, $date_start, $date_end);
  334. // parseDataByDays()/parseDataByWeeks()/parseDataByMonths()
  335. $data['content'] = $this->$parseMethod($orderRows, $date_start, $date_end);
  336. $getDateArrMethod = 'get'.$time_filter.'Arr';
  337. $data['date_arr'] = $this->$getDateArrMethod($date_start, $date_end);
  338. return $data;
  339. }
  340. /**
  341. * 返回优惠券状态字符串
  342. * @param number $status : 状态码
  343. */
  344. private function getStatusStr ($status) {
  345. switch ($status) {
  346. case 0:
  347. return '暂停';
  348. break;
  349. case 1:
  350. return '正常';
  351. break;
  352. case -1:
  353. return '删除';
  354. break;
  355. default:
  356. break;
  357. }
  358. return '未知';
  359. }
  360. /**
  361. * 按照每天整理数据(一周数据)
  362. */
  363. private function parseDataByDays ($rows, $date_start, $date_end) {
  364. $data = array();
  365. $date_index = $date_start;
  366. $rows_count = count($rows);
  367. $rows_index = 0;
  368. $price_arr = array();
  369. $final_price_arr = array();
  370. $count_arr = array();
  371. while ($date_index < $date_end) {
  372. $data_temp = array(
  373. 'price' => 0,
  374. 'final_price' => 0,
  375. 'count' => 0
  376. );
  377. while ($rows_index < $rows_count) {
  378. if ($date_index <= $rows[$rows_index]['order_time']
  379. && $rows[$rows_index]['order_time'] < strtotime('+1 day', $date_index)) {
  380. $data_temp['price'] += $rows[$rows_index]['price'];
  381. $data_temp['final_price'] += $rows[$rows_index]['final_price'];
  382. $data_temp['count']++;
  383. } else {
  384. break;
  385. }
  386. $rows_index++;
  387. }
  388. $price_arr[] = $data_temp['price'];
  389. $final_price_arr[] = $data_temp['final_price'];
  390. $count_arr[] = $data_temp['count'];
  391. $date_index = strtotime('+1 day', $date_index);
  392. }
  393. $data['price'] = $price_arr;
  394. $data['final_price'] = $final_price_arr;
  395. $data['count'] = $count_arr;
  396. return $data;
  397. }
  398. /**
  399. * 按照每周整理数据(一月数据)
  400. */
  401. private function parseDataByWeeks ($rows, $date_start, $date_end) {
  402. $rows = $this->parseDataByDays($rows, $date_start, $date_end);
  403. $range = ($date_end - $date_start)/3600/24/7;
  404. $data = array();
  405. $rows_index = 0;
  406. $day_count = 1;
  407. $date_index = $date_start;
  408. $price_arr = array();
  409. $final_price_arr = array();
  410. $count_arr = array();
  411. for ($week_index = 0; $week_index < $range; $week_index++) {
  412. $data_temp = array(
  413. 'price' => 0,
  414. 'final_price' => 0,
  415. 'count' => 0,
  416. );
  417. while ($day_count%8 != 0) {
  418. $data_temp['price'] += $rows['price'][$rows_index];
  419. $data_temp['final_price'] += $rows['final_price'][$rows_index];
  420. $data_temp['count'] += $rows['count'][$rows_index];
  421. $rows_index++;
  422. $day_count++;
  423. }
  424. $price_arr[] = $data_temp['price'];
  425. $final_price_arr[] = $data_temp['final_price'];
  426. $count_arr[] = $data_temp['count'];
  427. $day_count = 1;
  428. }
  429. $data['price'] = $price_arr;
  430. $data['final_price'] = $final_price_arr;
  431. $data['count'] = $count_arr;
  432. return $data;
  433. }
  434. /**
  435. * 按照每月整理数据(半年数据)
  436. */
  437. private function parseDataByMonths ($rows, $date_start, $date_end) {
  438. $rows = $this->parseDataByDays($rows, $date_start, $date_end);
  439. $range = intval(date('m', $date_end)) - intval(date('m', $date_start));
  440. // 每月天数获取
  441. $num_of_days = array();
  442. for ($i = 0; $i < $range; $i++) {
  443. $num_of_days[$i] = (strtotime('+'.($i+1).' month', $date_start) - strtotime('+'.$i.' month', $date_start))/3600/24;
  444. }
  445. $data = array();
  446. $data_index = 0;
  447. $day_count = 0;
  448. $date_index = $date_start;
  449. $price_arr = array();
  450. $final_price_arr = array();
  451. $count_arr = array();
  452. foreach ($num_of_days as $key => $value) {
  453. $day_count += $value;
  454. $data_temp = array(
  455. 'price' => 0,
  456. 'final_price' => 0,
  457. 'count' => 0
  458. );
  459. while ($data_index < $day_count) {
  460. $data_temp['price'] += $rows['price'][$data_index];
  461. $data_temp['final_price'] += $rows['final_price'][$data_index];
  462. $data_temp['count'] += $rows['count'][$data_index];
  463. $data_index++;
  464. }
  465. $price_arr[] = $data_temp['price'];
  466. $final_price_arr[] = $data_temp['final_price'];
  467. $count_arr[] = $data_temp['count'];
  468. }
  469. $data['price'] = $price_arr;
  470. $data['final_price'] = $final_price_arr;
  471. $data['count'] = $count_arr;
  472. return $data;
  473. }
  474. /**
  475. * 获取时间点数组
  476. */
  477. private function getDaysArr ($date_start, $date_end) {
  478. $date_arr = array();
  479. $date_index = $date_start;
  480. while ($date_index < $date_end) {
  481. $date_arr[] = date('m-d', $date_index);
  482. $date_index = strtotime('+1 day', $date_index);
  483. }
  484. $data['date_arr'] = $date_arr;
  485. return $date_arr;
  486. }
  487. private function getWeeksArr ($date_start, $date_end) {
  488. $week_arr = array();
  489. $date_index = $date_start;
  490. do {
  491. $week_temp = date('m-d', $date_index);
  492. $date_index = strtotime('+7 day', $date_index);
  493. $week_temp .= '至'.date('m-d', strtotime('-1 day', $date_index));
  494. $week_arr[] = $week_temp;
  495. } while ($date_index < $date_end);
  496. return $week_arr;
  497. }
  498. private function getMonthsArr ($date_start, $date_end) {
  499. $month_arr = array();
  500. $date_index = $date_start;
  501. while ($date_index < $date_end) {
  502. $month_arr[] = intval(date('m', $date_index)).'月';
  503. $date_index = strtotime('+1 month', $date_index);
  504. }
  505. return $month_arr;
  506. }
  507. }
  508. ?>