Charlie 9 年 前
コミット
083b6f165b

+ 1 - 1
www/protected/config/main.php

@@ -34,7 +34,7 @@ return array(
         //               'password'=>'admin',
         //               'ipFilters'=>array('127.0.0.1','::1'),
         //            ),
-        
+        'dataview',
         'o2o',
     ),
 

+ 11 - 0
www/protected/modules/dataview/DataviewModule.php

@@ -0,0 +1,11 @@
+<?php
+class DataviewModule extends CWebModule
+{
+    public function init()
+    {
+        $this->setImport(array(
+            'dataview.components.*',
+            'dataview.controllers.*',
+        ));
+    }
+}

+ 592 - 0
www/protected/modules/dataview/controllers/CouponsCountViewController.php

@@ -0,0 +1,592 @@
+<?php 
+/**
+ * 根据优惠券统计订单控制器
+ * @author zhouxuchen 2015-10-13
+ */
+class CouponsCountViewController extends AdminController {
+
+    /**
+     * 首页
+     */
+    public function actionIndex () {
+        $status_option = Coupon::$status_option;
+        $time_range = array(
+            'noSelect' => array('name' => '未选择'),
+            'Months'   => array('name' => '最近半年'),
+            'Weeks'    => array('name' => '最近一月'),
+            'Days'     => array('name' => '最近一周')
+        );
+
+        $status_filter = CommonFn::getComboboxData($status_option, 1, true, 100);
+        $time_filter = CommonFn::getComboboxData($time_range, 'noSelect', false, '');
+
+        $data = array(
+            'status_filter' => $status_filter,
+            'time_filter'   => $time_filter
+        );
+        $this->render('index', $data);
+    }
+
+    /**
+     * 显示列表
+     */
+    public function actionList () {
+        // echo json_encode(array());return;
+
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end   = Yii::app()->request->getParam('date_end', '');
+        $status     = intval(Yii::app()->request->getParam('status', 100));
+
+        if (!empty($date_start) && !empty($date_end)) {
+            $date_start = strtotime($date_start);
+            $int_start_date = intval(date('Ymd',$date_start));
+            $date_end = strtotime('+1 day', strtotime($date_end));
+            $int_end_date = intval(date('Ymd',$date_end));
+        } else {
+            $date_start = 0;
+            $int_start_date = intval(date('Ymd'));
+            $date_end = 0;
+            $int_end_date = intval(date('Ymd')) + 1;
+        }
+        $criteria = new EMongoCriteria();
+        $criteria->date('>=',$int_start_date);
+        $criteria->date('<',$int_end_date);
+        $count_list = OfflineOrderCount::model()->findAll($criteria);
+        $offline_order_sum['title'] = '线下推广用户完成首单数';
+        $offline_order_sum['value'] = 0;
+        foreach ($count_list as $offline_order_count) {
+            $offline_order_sum['value'] += $offline_order_count->count; 
+        }
+        $data = $this->getAll($date_start, $date_end, true, $status, true);
+        $total = $data['total'];
+        $data = $data['data'];
+        $offline =  array(array(
+                            'price' => 0,
+                            'final_price' => 0,
+                            'count' => $offline_order_sum['value'],
+                            'id' => '',
+                            'name' => $offline_order_sum['title'],
+                            'memo' => '',
+                            'status' => 1,
+                            'status_str' => '正常',
+                            'alias_name' => '',
+                        ));
+        $data = array_merge($offline,$data);
+        echo CommonFn::composeDatagridData($data, $total);
+    }
+
+    /**
+     * 返回数据生成柱状图
+     */
+    public function actionGetChartBar () {
+        $time_filter = Yii::app()->request->getParam('time_filter', 'noSelect');
+        $status_filter = intval(Yii::app()->request->getParam('status_filter', 100));
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end = Yii::app()->request->getParam('date_end', '');
+
+        if ($time_filter == 'noSelect') {
+            $data = array();
+        } else {
+            // 默认查询一周数据
+            if (empty($date_start) || empty($date_end)) {
+                $date_range = $this->getDateRnage($time_filter);
+                $date_start = $date_range['date_start'];
+                $date_end   = $date_range['date_end'];
+            } else {
+                $date_start = strtotime($date_start);
+                $date_end = strtotime('+1 day', strtotime($date_end));
+            }
+
+            $data = $this->getBarData($status_filter, $time_filter, $date_start, $date_end);
+        }
+
+        echo json_encode($data);
+    }
+
+    /**
+     * 返回数据生成饼状图
+     */
+    public function actionGetChartPie () {
+        $time_filter = Yii::app()->request->getParam('time_filter', 'noSelect');
+        $status_filter = intval(Yii::app()->request->getParam('status_filter', 100));
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end = Yii::app()->request->getParam('date_end', '');
+
+        // 时间范围处理
+        // 检查是否填写了时间范围
+        if (!empty($date_start) && !empty($date_end)) {
+            $date_start = strtotime($date_start);
+            $date_end = strtotime('+1 day', strtotime($date_end));
+        // 否则挑选时间范围
+        } else {
+            // 获取时间点
+            if ($time_filter != 'noSelect') {
+                $date_range = $this->getDateRnage($time_filter);
+                $date_start = $date_range['date_start'];
+                $date_end   = $date_range['date_end']; 
+            // 查询所有数据
+            } else {
+                $date_start = $date_end = 0;
+            }
+        }
+
+        $data = $this->getPieData($status_filter, $date_start, $date_end);
+        echo json_encode($data);
+    }
+
+    /**
+     * 返回数据生成单个优惠券的柱状图及折线图
+     */
+    public function actionGetChartById () {
+        $id = Yii::app()->request->getParam('id', '');
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end = Yii::app()->request->getParam('date_end', '');
+        $time_filter = Yii::app()->request->getParam('time_filter', 'noSelect');
+        $filter_week = Yii::app()->request->getParam('filter_week', 0);
+
+        if ($id == '' || $time_filter == 'noSelct') {
+            echo json_encode(array());
+            return false;
+        }
+
+        $coupon_id = new MongoId($id);
+
+        // 检查是否选择了时间范围
+        if ($time_filter != 'Days' || ($filter_week == 1 && $time_filter == 'Days')) {
+            $date_range = $this->getDateRnage($time_filter);
+            $date_start = $date_range['date_start'];
+            $date_end   = $date_range['date_end'];
+        // 否则获取具体时间
+        } else if (!empty($date_start) && !empty($date_end)) {
+            $date_start = strtotime($date_start);
+            $date_end = strtotime('+1 day', strtotime($date_end));
+        } else {
+            echo json_encode(array());
+            return false;
+        }
+        
+        $data = $this->getBarDataById($coupon_id, $time_filter, $date_start, $date_end);
+        echo json_encode($data);
+    }
+
+    /**
+     * ----------------------------------
+     *
+     *      私有方法,对数据进行整理
+     * 
+     * ----------------------------------
+     */
+
+    /**
+     * 获取所有数据的统计
+     * @param timestamp $date_start    : 开始的日期
+     * @param timestamp $date_end      : 结束的日期
+     * @param boolean   $empty_data    : 是否加入空数据
+     * @param number    $status_filter : 状态筛选,默认查询所有状态
+     * @param boolean   $pageParam     : 是否加入分页信息
+     */
+    private function getAll ($date_start = 0, $date_end = 0, $empty_data = false, $status_filter = 100, $pageParam = false) {
+        $data = array();
+        $coupons = $this->getCoupons($status_filter, $pageParam);
+
+        if ($pageParam) {
+            $data['total'] = $coupons['total'];
+            $coupons = $coupons['rows'];
+
+            if ($data['total'] == 0) {
+                return array('total' => 0, 'data' => array());
+            }
+        }        
+
+        foreach ($coupons as $key => $value) {
+            $alias_name = isset($value['alias_name']) ? $value['alias_name'] : '';
+            $data_temp = array(
+                'price'       => 0,
+                'final_price' => 0,
+                'count'       => 0,
+                'id'          => (string)$value['_id'],
+                'name'        => $value['name'].'('.$alias_name.')',
+                'memo'        => $value['memo'],
+                'status'      => $value['status'],
+                'status_str'  => $this->getStatusStr($value['status']),
+                'alias_name'  => $alias_name
+            );
+
+            $orderRows = $this->getOrderRows($value['_id'], $date_start, $date_end);
+            if (empty($orderRows)) {
+                if ($empty_data) {
+                    $data['data'][] = $data_temp;
+                }
+                continue;
+            }
+
+            foreach ($orderRows as $k => $v) {
+                $data_temp['price'] += $v['price'];
+                $data_temp['final_price'] += $v['final_price'];
+            }
+            $data_temp['count'] = count($orderRows);
+
+            $data['data'][] = $data_temp;
+        }
+
+        return $data;
+    }
+
+    /**
+     * 根据状态获取优惠券数组
+     * @param number  $status    : 状态码,默认为100(所有状态)
+     * @param boolean $pageParam : 是否加入分页信息
+     */
+    private function getCoupons ($status_filter = 100, $pageParam = false) {
+        $pageParams = CommonFn::getPageParams();
+        $criteria = $pageParam ? new EMongoCriteria($pageParams) : new EMongoCriteria();
+        if ($status_filter != 100) $criteria->status('==', $status_filter);
+        $cursor = Coupon::model()->findAll($criteria);
+        $rows = CommonFn::getRowsFromCursor($cursor);
+        $total = count($cursor);
+
+        if ($pageParam) {
+            $rows['rows'] = $rows;
+            $rows['total'] = $total;
+        }
+
+        return $rows;
+    }
+
+    /**
+     * 根据优惠券ID获取使用该优惠券的所有订单
+     * @param MongoID   $coupon_id  : 优惠券ID,来自于coupon表
+     * @param timestamp $date_start : 开始的时间,默认为0(查询所有)
+     * @param timestamp $date_end   : 结束的时间,默认为0(查询所有)
+     */
+    private function getOrderRows ($coupon_id, $date_start = 0, $date_end = 0) {
+        $criteria = new EMongoCriteria();
+        $criteria->coupon('==', $coupon_id);
+        $criteria->status('==', -1);
+        $cursor = UserCoupon::model()->findAll($criteria);
+
+        $rows = CommonFn::getRowsFromCursor($cursor);
+
+        $userCoupons = array();
+        foreach ($rows as $value) {
+            $userCoupons[] = $value['_id'];
+        }
+
+        $criteria = new EMongoCriteria();
+        $criteria->coupons('in', $userCoupons);
+        $criteria->status('>=', 1);
+
+        if ($date_start != 0 && $date_end != 0) {
+            $criteria->order_time('>=', $date_start);
+            $criteria->order_time('<', $date_end);
+        }
+
+        $criteria->sort('order_time', EMongoCriteria::SORT_ASC);
+        $cursor = ROrder::model()->findAll($criteria);
+        $rows = CommonFn::getRowsFromCursor($cursor);
+
+        return $rows;
+    }
+
+    /**
+     * 获取时间范围
+     * @return array $date_range : 时间范围数组,包括查询开始及结束的时间
+     */
+    private function getDateRnage ($time_filter) {
+        // ------ 最近一月的时间点 ------
+        if ($time_filter == 'Weeks') {
+            $date_end = strtotime('monday', time());
+            if (strtotime(date('Y-m-d', time())) == $date_end) {
+                $date_end = strtotime('+7 day', $date_end);
+            }
+            $date_start = strtotime('-35 day', $date_end);
+        // ------ 最近半年的时间点 ------
+        } else if ($time_filter == 'Months') {
+            $date_end = strtotime(date('Y-m', strtotime('+1 month', time())));
+            $date_start = strtotime(date('Y-m', strtotime('-5 month', time())));
+        // ------ 最近一周的时间点 ------
+        } else {
+            $date_end = strtotime(date('Y-m-d', strtotime('+1 day', time())));
+            $date_start = strtotime(date('Y-m-d', strtotime('-6 day', time())));
+        }
+
+        $date_range = array(
+            'date_start' => $date_start,
+            'date_end'   => $date_end
+        );
+        return $date_range;
+    }
+
+    /**
+     * 获取柱状图数据,默认显示近一周的数据
+     */
+    private function getBarData ($status_filter, $time_filter, $date_start, $date_end) {
+        // 获取优惠券数组
+        $coupons = $this->getCoupons($status_filter);
+        // 整理函数的选取
+        $parseMethod = 'parseDataBy'.$time_filter;
+
+        $data = array();
+        $coupons_arr = array();
+        foreach ($coupons as $key => $value) {
+            $orderRows = $this->getOrderRows($value['_id'], $date_start, $date_end);
+
+            // parseDataByDays()/parseDataByWeeks()/parseDataByMonths()
+            $data_temp = $this->$parseMethod($orderRows, $date_start, $date_end);
+            $alias_name = isset($value['alias_name']) ? $value['alias_name'] : '';
+            $data_temp['coupon'] = $value['name'].'('.$alias_name.')';
+            $coupons_arr[] = $value['name'].'('.$alias_name.')';
+
+            $data['content'][] = $data_temp;
+        }
+
+        $getDateArrMethod = 'get'.$time_filter.'Arr';
+        $data['date_arr'] = $this->$getDateArrMethod($date_start, $date_end);
+        $data['coupons'] = $coupons_arr;
+
+        return $data;
+    }
+
+    /**
+     * 获取饼图数据,默认显示所有数据
+     */
+    private function getPieData ($status_filter = 100, $date_start = 0, $date_end = 0) {
+        $data = array();
+        $price = array();
+        $final_price = array();
+        $count = array();
+        $coupons = array();
+
+        $data_all = $this->getAll($date_start, $date_end, true, $status_filter, false);
+        $data_all = $data_all['data'];
+        $data_temp = array();
+        foreach ($data_all as $key => $value) {
+            $data_temp['price'] = $value['price'];
+            $data_temp['final_price'] = $value['final_price'];
+            $data_temp['count'] = $value['count'];
+            $data_temp['coupon'] = $value['name'];
+
+            $coupons[] = $value['name'];
+            $data['content'][] = $data_temp;
+        }
+
+        $data['coupons'] = $coupons;
+        return $data;
+    }
+
+    /**
+     * 获取单个优惠券类型的数据,默认显示近一周的数据
+     */
+    public function getBarDataById ($coupon_id, $time_filter, $date_start, $date_end) {
+        // 整理函数的选取
+        $parseMethod = 'parseDataBy'.$time_filter;
+
+        $orderRows = $this->getOrderRows($coupon_id, $date_start, $date_end);
+        // parseDataByDays()/parseDataByWeeks()/parseDataByMonths()
+        $data['content'] = $this->$parseMethod($orderRows, $date_start, $date_end);
+        $getDateArrMethod = 'get'.$time_filter.'Arr';
+        $data['date_arr'] = $this->$getDateArrMethod($date_start, $date_end);
+
+        return $data;
+    }
+
+    /**
+     * 返回优惠券状态字符串
+     * @param number $status : 状态码
+     */
+    private function getStatusStr ($status) {
+        switch ($status) {
+            case 0:
+                return '暂停';
+                break;
+            case 1:
+                return '正常';
+                break;
+            case -1:
+                return '删除';
+                break;
+            default:
+                break;
+        }
+
+        return '未知';
+    }
+
+    /**
+     * 按照每天整理数据(一周数据)
+     */
+    private function parseDataByDays ($rows, $date_start, $date_end) {
+        $data = array();
+        $date_index = $date_start;
+        $rows_count = count($rows);
+        $rows_index = 0;
+
+        $price_arr = array();
+        $final_price_arr = array();
+        $count_arr = array();
+
+        while ($date_index < $date_end) {
+            $data_temp = array(
+                'price'       => 0,
+                'final_price' => 0,
+                'count'       => 0
+            );
+
+            while ($rows_index < $rows_count) {
+                if ($date_index <= $rows[$rows_index]['order_time']
+                    && $rows[$rows_index]['order_time'] < strtotime('+1 day', $date_index)) {
+                    $data_temp['price'] += $rows[$rows_index]['price'];
+                    $data_temp['final_price'] += $rows[$rows_index]['final_price'];
+                    $data_temp['count']++;
+                } else {
+                    break;
+                }
+
+                $rows_index++;
+            }
+
+            $price_arr[] = $data_temp['price'];
+            $final_price_arr[] = $data_temp['final_price'];
+            $count_arr[] = $data_temp['count'];
+            $date_index = strtotime('+1 day', $date_index);
+        }
+
+        $data['price'] = $price_arr;
+        $data['final_price'] = $final_price_arr;
+        $data['count'] = $count_arr;
+        return $data;
+    }
+
+    /**
+     * 按照每周整理数据(一月数据)
+     */
+    private function parseDataByWeeks ($rows, $date_start, $date_end) {
+        $rows = $this->parseDataByDays($rows, $date_start, $date_end);
+        $range = ($date_end - $date_start)/3600/24/7;
+        $data = array();
+
+        $rows_index = 0;
+        $day_count = 1;
+        $date_index = $date_start;
+
+        $price_arr = array();
+        $final_price_arr = array();
+        $count_arr = array();
+
+        for ($week_index = 0; $week_index < $range; $week_index++) {
+            $data_temp = array(
+                'price'       => 0,
+                'final_price' => 0,
+                'count'       => 0,
+            );
+
+            while ($day_count%8 != 0) {
+                $data_temp['price'] += $rows['price'][$rows_index];
+                $data_temp['final_price'] += $rows['final_price'][$rows_index];
+                $data_temp['count'] += $rows['count'][$rows_index];
+                $rows_index++;
+                $day_count++;
+            }
+
+            $price_arr[] = $data_temp['price'];
+            $final_price_arr[] = $data_temp['final_price'];
+            $count_arr[] = $data_temp['count'];
+            $day_count = 1;
+        }
+
+        $data['price'] = $price_arr;
+        $data['final_price'] = $final_price_arr;
+        $data['count'] = $count_arr;
+        return $data;
+    }
+
+    /**
+     * 按照每月整理数据(半年数据)
+     */
+    private function parseDataByMonths ($rows, $date_start, $date_end) {
+        $rows = $this->parseDataByDays($rows, $date_start, $date_end);
+
+        $range = intval(date('m', $date_end)) - intval(date('m', $date_start));
+        // 每月天数获取
+        $num_of_days = array();
+        for ($i = 0; $i < $range; $i++) {
+            $num_of_days[$i] = (strtotime('+'.($i+1).' month', $date_start) - strtotime('+'.$i.' month', $date_start))/3600/24;
+        }
+
+        $data = array();
+        $data_index = 0;
+        $day_count = 0;
+        $date_index = $date_start;
+
+        $price_arr = array();
+        $final_price_arr = array();
+        $count_arr = array();
+
+        foreach ($num_of_days as $key => $value) {
+            $day_count += $value;
+            $data_temp = array(
+                'price'       => 0,
+                'final_price' => 0,
+                'count'       => 0
+            );
+
+            while ($data_index < $day_count) {
+                $data_temp['price'] += $rows['price'][$data_index];
+                $data_temp['final_price'] += $rows['final_price'][$data_index];
+                $data_temp['count'] += $rows['count'][$data_index];
+                $data_index++;
+            }
+
+            $price_arr[] = $data_temp['price'];
+            $final_price_arr[] = $data_temp['final_price'];
+            $count_arr[] = $data_temp['count'];
+        }
+
+        $data['price'] = $price_arr;
+        $data['final_price'] = $final_price_arr;
+        $data['count'] = $count_arr;
+        return $data;
+    }
+
+    /**
+     * 获取时间点数组
+     */
+    private function getDaysArr ($date_start, $date_end) {
+        $date_arr = array();
+        $date_index = $date_start;
+        while ($date_index < $date_end) {
+            $date_arr[] = date('m-d', $date_index);
+            $date_index = strtotime('+1 day', $date_index);
+        }
+        $data['date_arr'] = $date_arr;
+
+        return $date_arr;
+    }
+
+    private function getWeeksArr ($date_start, $date_end) {
+        $week_arr = array();
+        $date_index = $date_start;
+        do {
+            $week_temp = date('m-d', $date_index);
+            $date_index = strtotime('+7 day', $date_index);
+            $week_temp .= '至'.date('m-d', strtotime('-1 day', $date_index));
+
+            $week_arr[] = $week_temp;
+        } while ($date_index < $date_end);
+
+        return $week_arr;
+    }
+
+    private function getMonthsArr ($date_start, $date_end) {
+        $month_arr = array();
+        $date_index = $date_start;
+        while ($date_index < $date_end) {
+            $month_arr[] = intval(date('m', $date_index)).'月';
+            $date_index = strtotime('+1 month', $date_index);
+        }
+
+        return $month_arr;
+    }
+
+}
+?>

+ 491 - 0
www/protected/modules/dataview/controllers/ROrderCountViewController.php

@@ -0,0 +1,491 @@
+<?php 
+/**
+ * o2o订单统计控制器
+ * @author zhouxuchen 2015-10-10
+ */
+class ROrderCountViewController extends AdminController {
+
+    /**
+     * 首页
+     */
+    public function actionIndex () {
+        $filter_data = ROrder::$order_filter;
+        $filter = CommonFn::getComboboxData($filter_data, 1, false);
+
+        $time_range = array(
+            'noSelect' => array('name' => '未选择'),
+            'Months'   => array('name' => '最近半年'),
+            'Weeks'    => array('name' => '最近一月'),
+            'Days'     => array('name' => '最近一周')
+        );
+        $filter_time = CommonFn::getComboboxData($time_range, 'noSelect', false, '');
+
+        $this->render('index', array(
+            'filter' => $filter,
+            'filter_time' => $filter_time
+        ));
+    }
+
+    /**
+     * 显示列表
+     */
+    public function actionList () {
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end   = Yii::app()->request->getParam('date_end', '');
+        $filter     = Yii::app()->request->getParam('filter', 0);
+
+        if (!empty($date_start) && !empty($date_end)) {
+            $date_start = strtotime($date_start);
+            $date_end = strtotime('+1 day', strtotime($date_end));
+        } else {
+            $date_start = 0;
+            $date_end   = 0;
+        }
+
+        $data = $this->getAll($date_start, $date_end, $filter, true);
+        echo json_encode($data);
+    }
+
+    /**
+     * 返回数据生成柱状图
+     */
+    public function actionGetChartBar () {
+        $filter = intval(Yii::app()->request->getParam('filter', 0));
+        $filter_time = Yii::app()->request->getParam('filter_time', 'noSelect');
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end = Yii::app()->request->getParam('date_end', '');
+
+        if ($filter == 0 || $filter_time == 'noSelect') {
+            $data = array();
+        } else {
+            // 默认查询一周数据
+            if (empty($date_start) || empty($date_end)) {
+                $date_range = $this->getDateRnage($filter_time);
+                $date_start = $date_range['date_start'];
+                $date_end   = $date_range['date_end'];
+            } else {
+                $date_start = strtotime($date_start);
+                $date_end   = strtotime('+1 day', strtotime($date_end));
+            }
+
+            $data = $this->getBarData($filter, $filter_time, $date_start, $date_end);
+        }
+        
+        echo json_encode($data);
+    }
+
+    /**
+     * 返回数据生成饼状图
+     */
+    public function actionGetChartPie () {
+        $filter = intval(Yii::app()->request->getParam('filter', 0));
+        $filter_time = Yii::app()->request->getParam('filter_time', 'Days');
+        $date_start = Yii::app()->request->getParam('date_start', '');
+        $date_end = Yii::app()->request->getParam('date_end', '');
+
+        if ($filter == 0) {
+            $data = array();
+        } else {
+            // 检查是否填写了时间范围
+            if (!empty($date_start) && !empty($date_end)) {
+                $date_start = strtotime($date_start);
+                $date_end = strtotime('+1 day', strtotime($date_end));
+            // 否则挑选时间范围
+            } else {
+                // 若选择了时间范围则获取时间点
+                if ($filter_time != 'noSelect') {
+                    $date_range = $this->getDateRnage($filter_time);
+                    $date_start = $date_range['date_start'];
+                    $date_end   = $date_range['date_end']; 
+                // 否则查询所有数据
+                } else {
+                    $date_start = $date_end = 0;
+                }
+            }
+
+            $data = $this->getPieData($filter, $date_start, $date_end);
+        }
+
+        echo json_encode($data);
+    }
+
+    /**
+     * ----------------------------------
+     *
+     *      私有方法,对数据进行整理
+     * 
+     * ----------------------------------
+     */
+
+    /**
+     * 获取所有数据的统计
+     * @param timestamp $date_start : 开始的日期
+     * @param timestamp $date_end   : 结束的日期
+     * @param number    $filter     : 选择筛选的条件(来源、服务、状态)
+     * @param boolean   $empty_data : 是否合并空数据
+     */
+    private function getAll ($date_start = 0, $date_end = 0, $filter = 0, $empty_data = false) {
+        if ($filter == 0) {
+            return array();
+        }
+
+        // 筛选条件的获取
+        $orderFilterContent = $this->getOrderFilterContent();
+        $filter_name = $orderFilterContent[$filter]['name'];
+        $filter_content = $orderFilterContent[$filter]['content'];
+
+        $data = array();
+        // 遍历筛选条件下的所有条目
+        foreach ($filter_content as $key => $value) {
+            $criteria = new EMongoCriteria();
+            // 若键值类似'number'(引号内为整型数字),php会自动将键值转换为整型
+            // 该处对此种情况进行处理,进行强制类型转换
+            $criteria->{$filter_name} = $filter == 2 ? (string)$key : $key;
+            // 状态筛选
+            if ($filter != 3) {
+                $criteria->status('>', 0);
+            }
+            if ($date_start != 0 && $date_end != 0) {
+                $criteria->order_time('>=', $date_start);
+                $criteria->order_time('<', $date_end);
+            }
+
+            $cursor = ROrder::model()->findAll($criteria);
+            $rows = CommonFn::getRowsFromCursor($cursor);
+
+            $data_temp = array(
+                'price'        => 0,
+                'ori_price'    => 0,
+                'count'        => 0,
+                'filter'       => $filter,
+                'filter_name'  => $filter_name,
+                'filter_index' => $key,
+                'filter_str'   => $value,
+            );
+
+            // 查询数据为空时的处理
+            if (empty($rows)) {
+                if ($empty_data) {
+                    $data[] = $data_temp;
+                }
+                continue;
+            }
+            
+            foreach ($rows as $k => $v) {
+                $data_temp['price'] += $v['final_price'];
+                $data_temp['ori_price'] += $v['price'];
+            }
+            $data_temp['count'] = count($rows);
+
+            $data[] = $data_temp;
+        }
+
+        return $data;
+    }
+
+    /**
+     * 获取时间范围
+     * @return array $date_range : 时间范围数组,包括查询开始及结束的时间
+     */
+    private function getDateRnage ($filter_time) {
+        // ------ 最近一月的时间点 ------
+        if ($filter_time == 'Weeks') {
+            $date_end = strtotime('monday', time());
+            if (strtotime(date('Y-m-d', time())) == $date_end) {
+                $date_end = strtotime('+7 day', $date_end);
+            }
+            $date_start = strtotime('-35 day', $date_end);
+        // ------ 最近半年的时间点 ------
+        } else if ($filter_time == 'Months') {
+            $date_end = strtotime(date('Y-m', strtotime('+1 month', time())));
+            $date_start = strtotime(date('Y-m', strtotime('-5 month', time())));
+        // ------ 最近一周的时间点 ------
+        } else {
+            $date_end = strtotime(date('Y-m-d', strtotime('+1 day', time())));
+            $date_start = strtotime(date('Y-m-d', strtotime('-6 day', time())));
+        }
+
+        $date_range = array(
+            'date_start' => $date_start,
+            'date_end'   => $date_end
+        );
+        return $date_range;
+    }
+
+    /**
+     * 获取柱状图数据,默认显示最近一周的数据
+     * @param number $filter      : 筛选条件
+     * @param string $filter_time : 时间范围
+     */
+    private function getBarData ($filter, $filter_time = 'Days', $date_start = 0, $date_end = 0) {
+        if ($date_start == 0 || $date_end == 0) {
+            $date_end = strtotime(date('Y-m-d', strtotime('+1 day', time())));
+            $date_start = strtotime(date('Y-m-d', strtotime('-6 day', time())));
+        }
+
+        // 筛选条件字典的获取
+        $orderFilterContent = $this->getOrderFilterContent();
+        $filter_name = $orderFilterContent[$filter]['name'];
+        $filter_content = $orderFilterContent[$filter]['content'];
+
+        // 整理函数的选取
+        $parseMethod = 'parseDataBy'.$filter_time;
+
+        $data = array();
+        $filter_arr = array();
+        foreach ($filter_content as $key => $value) {
+            $criteria = new EMongoCriteria();
+            $criteria->{$filter_name} = $filter == 2 ? (string)$key : $key;
+            $criteria->order_time('>=', $date_start);
+            $criteria->order_time('<', $date_end);
+            // 状态筛选
+            if ($filter != 3) {
+                $criteria->status('>', 0);
+            }
+            // 防止数据库内时间的混乱
+            $criteria->sort('order_time', EMongoCriteria::SORT_ASC);
+
+            $cursor = ROrder::model()->findAll($criteria);
+            $rows = CommonFn::getRowsFromCursor($cursor);
+
+            // parseDataByDays()/parseDataByWeeks()/parseDataByMonths()
+            $data_temp = $this->$parseMethod($rows, $date_start, $date_end);
+            $data_temp['filter'] = $value;
+            $filter_arr[] = $value;
+
+            $data['content'][] = $data_temp;
+        }
+        $getDateArrMethod = 'get'.$filter_time.'Arr';
+        $data['date_arr'] = $this->$getDateArrMethod($date_start, $date_end);
+        $data['filter_arr'] = $filter_arr;
+
+        return $data;
+    }
+
+    /**
+     * 获取饼图数据
+     */
+    private function getPieData ($filter, $date_start = 0, $date_end = 0) {
+        $data = array();
+        $price = array();
+        $count = array();
+        $filter_arr = array();
+
+        $data_all = $this->getAll($date_start, $date_end, $filter, true);
+        $data_temp = array();
+        foreach ($data_all as $key => $value) {
+            $data_temp['price'] = $value['price'];
+            $data_temp['count'] = $value['count'];
+            $data_temp['filter'] = $value['filter_str'];
+
+            $filter_arr[] = $value['filter_str'];
+            $data['content'][] = $data_temp;
+        }
+
+        $data['filter_arr'] = $filter_arr;
+        return $data;
+    }
+
+    /**
+     * 按照每天整理数据(一周数据)
+     */
+    private function parseDataByDays ($rows, $date_start, $date_end) {
+        $data = array();
+        $date_index = $date_start;
+        $rows_count = count($rows);
+        $rows_index = 0;
+
+        $price_arr = array();
+        $count_arr = array();
+
+        while ($date_index < $date_end) {
+            $data_temp = array(
+                'price' => 0,
+                'count' => 0
+            );
+
+            while ($rows_index < $rows_count) {
+                if ($date_index <= $rows[$rows_index]['order_time']
+                    && $rows[$rows_index]['order_time'] < strtotime('+1 day', $date_index)) {
+                    $data_temp['price'] += $rows[$rows_index]['final_price'];
+                    $data_temp['count']++;
+                } else {
+                    break;
+                }
+
+                $rows_index++;
+            }
+
+            $price_arr[] = $data_temp['price'];
+            $count_arr[] = $data_temp['count'];
+            $date_index = strtotime('+1 day', $date_index);
+        }
+
+        $data['price'] = $price_arr;
+        $data['count'] = $count_arr;
+        return $data;
+    }
+
+    /**
+     * 按照每周整理数据(一月数据)
+     */
+    private function parseDataByWeeks ($rows, $date_start, $date_end) {
+        $rows = $this->parseDataByDays($rows, $date_start, $date_end);
+        $range = ($date_end - $date_start)/3600/24/7;
+        $data = array();
+
+        $rows_index = 0;
+        $day_count = 1;
+        $date_index = $date_start;
+
+        $price_arr = array();
+        $count_arr = array();
+
+        for ($week_index = 0; $week_index < $range; $week_index++) {
+            $data_temp = array(
+                'price' => 0,
+                'count' => 0,
+            );
+
+            while ($day_count%8 != 0) {
+                $data_temp['price'] += $rows['price'][$rows_index];
+                $data_temp['count'] += $rows['count'][$rows_index];
+                $rows_index++;
+                $day_count++;
+            }
+
+            $price_arr[] = $data_temp['price'];
+            $count_arr[] = $data_temp['count'];
+            $day_count = 1;
+        }
+
+        $data['price'] = $price_arr;
+        $data['count'] = $count_arr;
+        return $data;
+    }
+
+    /**
+     * 按照每月整理数据(半年数据)
+     */
+    private function parseDataByMonths ($rows, $date_start, $date_end) {
+        $rows = $this->parseDataByDays($rows, $date_start, $date_end);
+
+        $range = intval(date('m', $date_end)) - intval(date('m', $date_start));
+        // 每月天数获取
+        $num_of_days = array();
+        for ($i = 0; $i < $range; $i++) {
+            $num_of_days[$i] = (strtotime('+'.($i+1).' month', $date_start) - strtotime('+'.$i.' month', $date_start))/3600/24;
+        }
+
+        $data = array();
+        $data_index = 0;
+        $day_count = 0;
+        $date_index = $date_start;
+
+        $price_arr = array();
+        $count_arr = array();
+
+        foreach ($num_of_days as $key => $value) {
+            $day_count += $value;
+            $data_temp = array(
+                'price' => 0,
+                'count' => 0
+            );
+
+            while ($data_index < $day_count) {
+                $data_temp['price'] += $rows['price'][$data_index];
+                $data_temp['count'] += $rows['count'][$data_index];
+                $data_index++;
+            }
+
+            $price_arr[] = $data_temp['price'];
+            $count_arr[] = $data_temp['count'];
+        }
+
+        $data['price'] = $price_arr;
+        $data['count'] = $count_arr;
+        return $data;
+    }
+
+    /**
+     * 获取时间点数组
+     */
+    private function getDaysArr ($date_start, $date_end) {
+        $date_arr = array();
+        $date_index = $date_start;
+        while ($date_index < $date_end) {
+            $date_arr[] = date('m-d', $date_index);
+            $date_index = strtotime('+1 day', $date_index);
+        }
+        $data['date_arr'] = $date_arr;
+
+        return $date_arr;
+    }
+
+    private function getWeeksArr ($date_start, $date_end) {
+        $week_arr = array();
+        $date_index = $date_start;
+        do {
+            $week_temp = date('m-d', $date_index);
+            $date_index = strtotime('+7 day', $date_index);
+            $week_temp .= '至'.date('m-d', strtotime('-1 day', $date_index));
+
+            $week_arr[] = $week_temp;
+        } while ($date_index < $date_end);
+
+        return $week_arr;
+    }
+
+    private function getMonthsArr ($date_start, $date_end) {
+        $month_arr = array();
+        $date_index = $date_start;
+        while ($date_index < $date_end) {
+            $month_arr[] = intval(date('m', $date_index)).'月';
+            $date_index = strtotime('+1 month', $date_index);
+        }
+
+        return $month_arr;
+    }
+
+    /**
+     * 整理订单筛选内容
+     */
+    private function getOrderFilterContent () {
+        $channel = array();
+        $channel_data = ROrder::$channel_option;
+        foreach ($channel_data as $key => $value) {
+            $channel[$key] = $value['name'];
+        }
+
+        $type = array();
+        $type_data = Yii::app()->params['o2o_service'];
+        foreach ($type_data as $key => $value) {
+            $type[$key] = $value['name'];
+        }
+
+        $status = array();
+        $status_data = ROrder::$status_option;
+        foreach ($status_data as $key => $value) {
+            $status[$key] = $value['name'];
+        }
+
+        $data = array(
+            1 => array(
+                'name'    => 'channel',
+                'content' => $channel,
+            ),
+            2 => array(
+                'name'    => 'type',
+                'content' => $type,
+            ),
+            3 => array(
+                'name'    => 'status',
+                'content' => $status,
+            ),
+        );
+
+        return $data;
+    }
+
+}
+?>

+ 726 - 0
www/protected/modules/dataview/views/couponsCountView/index.php

@@ -0,0 +1,726 @@
+<style>
+    .f_label {width: 90px;}
+    .accordion-body {padding: 0;}
+    .options {
+        display: inline-block;
+        border: 1px solid #e5e5e5;
+        background: #fff;
+        color: #000;
+        padding: 3px 6px;
+        text-decoration: none;
+    }
+</style>
+<div id="main">
+<div region="west" border="false" id="west_panel" style="width: 460px;">
+    <table id="dg_content"></table>
+    <div id="tb_content">
+        <div class="tb_line">
+            <div style="padding: 2px 0px 1px 0px;">
+                <span class="tb_label">开始</span>
+                <input id="date_start" type="text" value="<?php echo date('Y-m-d', time()); ?>" style="width: 100px"/>
+                <span class="tb_label">结束</span>
+                <input id="date_end" type="text" value="<?php echo date('Y-m-d', time()); ?>"style="width: 100px"/>
+            </div>
+            <div style="padding: 1px 0px 1px 0px;">
+                <span class="tb_label">状态</span>
+                <input id="status_filter_datagrid" type="text" style="width: 100px" />
+                <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="search_content();return false;">查询</a>
+            </div>
+            <div style="padding: 1px 0px 2px 0px;">
+                <span id="time_filter_id_span" style="display:none;">
+                    <span class="tb_label">范围</span>
+                    <input id="time_filter_id" type="text" style="width: 100px;"/>
+                </span>
+                <a href="#" id="showSetFilterTimeIdBtn" class='easyui-linkbutton' iconCls="icon-filter" plain="true" onclick="showSetFilterTimeId();return false;">打开时间范围选取</a>
+                <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="getChartById();return false;">获取单个优惠券统计</a>
+            </div>
+        </div>
+    </div>
+</div>
+<div region="center" title="统计图表">
+<div class="easyui-layout detail_layout">
+<div data-options="region:'center'" class="detail_center">
+<div class="detail_main">
+    <div id="getEchart">
+        <p>
+            <input id="status_filter_echart" type="text" style="width: 100px;" />
+            <span id="time_filter_span">
+                <input id="time_filter" style="width:180px;"/>
+            </span>
+            <span id="date_range_span" style="display:none;">
+                <input id="date_start_echart" style="width: 100px" />
+                <input id="date_end_echart" style="width: 100px" />
+            </span>
+            <span id="loading" style="display:none;">正在查询,请稍等</span>
+        </p>
+        <p>
+            <a href="#" class='easyui-linkbutton' iconCls="icon-filter" plain="true" onclick="showSetDateRange();return false;">选择具体日期</a>
+            <a href="#" class='easyui-linkbutton' iconCls="icon-filter" plain="true" onclick="showSetFilterTime();return false;">选择时间范围</a>
+            <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="getChartBar();return false;">获取柱状图</a>
+            <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="getChartPie();return false;">获取饼状图</a>
+        </p>
+    </div>
+    <form id="content_form">
+        <input id="coupon_id" type="hidden" name="id" />
+    </form>
+    <div data-options="region:'center'" class="detail_center">
+        <div class="detail_main">
+            <div id="echart_by_id" style="display:none;width:700px;height:450px;"></div>
+            <div style="padding: 0px 0px 8px 0;">
+                <span id="echart_price_title" style="display:none;">优惠券统计图</span>
+                <span id="echart_price_sub" style="display:none;">&nbsp;根据折后价格统计</span>
+            </div>
+            <div id="echart_price" style="display:none;height:450px;width:1000px"></div>
+            <div style="padding: 0px 0px 8px 0;">
+                <span id="echart_count_title" style="display:none;">优惠券统计图</span>
+                <span id="echart_count_sub" style="display:none;">&nbsp;根据使用数量统计</span>
+            </div>
+            <div id="echart_count" style="display:none;height:450px;width:1000px"></div>
+        </div>
+    </div>
+</div>
+</div>
+</div>
+</div>
+</div>
+
+<script src="http://echarts.baidu.com/build/dist/echarts.js"></script>
+<script type="text/javascript">
+var w_width = $(window).width();
+var w_height = $(window).height();
+
+var module_router = site_root + '/index.php?r=dataview/couponsCountView';
+
+var jq_content_form = $('#content_form');
+var jq_dg_content =$('#dg_content');
+var jq_date_start = $('#date_start');
+var jq_date_end = $('#date_end');
+var jq_date_start_echart = $('#date_start_echart');
+var jq_date_end_echart = $('#date_end_echart');
+var jq_time_filter = $('#time_filter');
+var jq_time_filter_id = $('#time_filter_id');
+var jq_status_filter_datagrid = $('#status_filter_datagrid');
+var jq_status_filter_echart = $('#status_filter_echart');
+
+var time_filter = <?php echo json_encode($time_filter); ?>;
+var status_filter = <?php echo json_encode($status_filter); ?>;
+
+var show_time_filter = 0;
+
+// 载入echarts配置
+require.config({
+    paths : {
+        echarts: 'http://echarts.baidu.com/build/dist'
+    }
+});
+
+$(function(){
+    var p_width = parseInt(w_width / 2);
+    if (p_width < 520){
+        p_width = 520;
+    }
+
+    jq_date_start.datebox({});
+    jq_date_end.datebox({});
+
+    jq_date_start_echart.datebox({});
+    jq_date_end_echart.datebox({});
+
+    jq_status_filter_datagrid.combobox({
+        width    : 100,
+        data     : status_filter,
+        editable : false,
+        onSelect : function () {
+            search_content();
+        }
+    });
+
+    jq_time_filter.combobox({
+        width    : 180,
+        data     : time_filter,
+        editable : false
+    });
+
+    jq_status_filter_echart.combobox({
+        width    : 100,
+        data     : status_filter,
+        editable : false
+    });
+
+    jq_time_filter_id.combobox({
+        width    : 100,
+        data     : time_filter,
+        editable : false
+    });
+
+    jq_time_filter_id.combobox('setValue', 'Days');
+
+    $('#main').css({width: w_width - 25, height: w_height - 18}).layout();
+
+    jq_dg_content.datagrid({
+        url: module_router + '/list',
+        title: '订单统计',
+        width: 450,
+        height: w_height - 18,
+        fitColumns: true,
+        autoRowHeight: true,
+        striped: true,
+        toolbar: '#tb_content',
+        singleSelect: true,
+        selectOnCheck: false,
+        checkOnSelect: false,
+        pagination: true,
+        pageList: [20, 30, 50],
+        pageSize: 20,
+        nowrap: false,
+        idField: 'id',
+        sortName: 'price',
+        sortOrder: 'desc',
+        queryParams: $.extend(
+            get_param_obj(),
+            {
+                date_start : jq_date_start.datebox('getValue'),
+                date_end   : jq_date_end.datebox('getValue'),
+                status     : 1
+            }
+        ),
+        frozenColumns:[],
+        columns:[[
+            {field: 'name', title: '分类', width: 50},
+            {field: 'alias_name', title: '别名', width: 20},
+            {field: 'price', title: '原价', width: 30},
+            {field: 'final_price', title: '折后', width: 30},
+            {field: 'count', title: '数量', width: 30},
+            {field: 'status_str', title: '状态', width: 15}
+        ]],
+
+        onSelect: function (index, row) {
+            var data = $.extend({}, row);
+            jq_content_form.form('load', data);
+        },
+
+        onLoadSuccess: function(){
+            $(this).datagrid('clearChecked');
+            jq_content_form.form('clear');
+        }
+    });
+});
+
+function search_content () {
+    var date_start = jq_date_start.datebox('getValue');
+    var date_end = jq_date_end.datebox('getValue');
+    var status = jq_status_filter_datagrid.combobox('getValue');
+
+    jq_dg_content.datagrid({
+        pageNum : 1,
+        queryParams : {
+            date_start : date_start,
+            date_end   : date_end,
+            status     : status
+        }
+    });
+}
+
+function showSetDateRange () {
+    jq_time_filter.combobox('setValue', 'Days');
+    jq_date_start_echart.datebox('setValue', '');
+    jq_date_end_echart.datebox('setValue', '');
+
+    $('#time_filter_span').css({'display':'none'});
+    $('#date_range_span').css({'display':'inline-block'});
+}
+
+function showSetFilterTime () {
+    jq_date_start_echart.datebox('setValue', '');
+    jq_date_end_echart.datebox('setValue', '');
+    jq_time_filter.combobox('setValue', 'noSelect');
+    
+    $('#time_filter_span').css({'display':'inline-block'});
+    $('#date_range_span').css({'display':'none'});
+}
+
+function getChartBar () {
+    var time_filter = jq_time_filter.combobox('getValue');
+    var status_filter_echart = jq_status_filter_echart.combobox('getValue');
+    var date_start = jq_date_start_echart.datebox('getValue');
+    var date_end = jq_date_end_echart.datebox('getValue');
+
+    if (time_filter == 'noSelect') {
+        alert('请选择时间范围!');
+        return false;
+    }
+
+    $('#loading').fadeIn('slow', function(){});
+
+    $('#echart_price').show();
+    $('#echart_count').show();
+    $('#echart_by_id').hide();
+
+    $.post(
+        module_router + '/getChartBar',
+        {
+            time_filter   : time_filter,
+            status_filter : status_filter_echart,
+            date_start    : date_start,
+            date_end      : date_end
+        },
+        function (data, status) {
+            $('#loading').fadeOut('slow', function(){});
+            var data = jQuery.parseJSON(data);
+            showChartBar(data);
+        }
+    );
+}
+
+function showChartBar (data) {
+    $('#echart_price_title').css({'display':'inline-block', 'font-size':'18px', 'font-weight':'bold'});
+    $('#echart_count_title').css({'display':'inline-block', 'font-size':'18px', 'font-weight':'bold'});
+    $('#echart_price_sub').css({'display':'inline-block', 'font-size':'14px', 'color':'#CCCCCC'});
+    $('#echart_count_sub').css({'display':'inline-block', 'font-size':'14px', 'color':'#CCCCCC'});
+
+    require(
+        [
+            'echarts',
+            'echarts/chart/line',
+            'echarts/chart/bar'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_price'));
+            var option = {
+                tooltip : {
+                    trigger: 'axis'
+                },
+                legend: {
+                    orient  : 'vertical',
+                    x       : 'left',
+                    data    : data['coupons']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {show: true, type: ['bar', 'line']},
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                grid : {
+                    x: 330
+                },
+                calculable : true,
+                xAxis : [
+                    {
+                        type : 'category',
+                        data : data['date_arr']
+                    }
+                ],
+                yAxis : [
+                    {
+                        type : 'value',
+                        name : '价格',
+                        axisLabel : {
+                            formatter: '{value} 元'
+                        }
+
+                    }
+                ],
+                series : (function(){
+                    var series = [];
+
+                    for (var key in data.content) {
+
+                        var item_price = {
+                            name : data['content'][key]['coupon'],
+                            type : 'bar',
+                            data : data['content'][key]['final_price']
+                        }
+
+                        series.push(item_price);
+                    }
+
+                    return series;
+                })()
+            };
+            material_chart.setOption(option);
+        }
+    );
+
+    require(
+        [
+            'echarts',
+            'echarts/chart/line',
+            'echarts/chart/bar'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_count'));
+            var option = {
+                tooltip : {
+                    trigger: 'axis'
+                },
+                legend: {
+                    orient : 'vertical',
+                    x      : 'left',
+                    data   : data['coupons']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {show: true, type: ['bar', 'line']},
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                grid : {
+                    x: 330
+                },
+                calculable : true,
+                xAxis : [
+                    {
+                        type : 'category',
+                        data : data['date_arr']
+                    }
+                ],
+                yAxis : [
+                    {
+                        type : 'value',
+                        name : '数量',
+                        axisLabel : {
+                            formatter: '{value} 单'
+                        }
+
+                    }
+                ],
+                series : (function(){
+                    var series = [];
+
+                    for (var key in data.content) {
+                        var item_count = {
+                            name : data['content'][key]['coupon'],
+                            type : 'line',
+                            data : data['content'][key]['count']
+                        };
+
+                        series.push(item_count);
+                    }
+
+                    return series;
+                })()
+            };
+            material_chart.setOption(option);
+        }
+    );
+}
+
+function getChartPie () {
+    var time_filter = jq_time_filter.combobox('getValue');
+    var status_filter_echart = jq_status_filter_echart.combobox('getValue');
+    var date_start = jq_date_start_echart.datebox('getValue');
+    var date_end = jq_date_end_echart.datebox('getValue');
+
+    if (time_filter == 'noSelect') {
+        alert('请选择时间范围!');
+        return false;
+    }
+
+    $('#loading').fadeIn('slow', function () {});
+
+    $('#echart_price').show();
+    $('#echart_count').show();
+    $('#echart_by_id').hide();
+
+    $.post(
+        module_router + '/getChartPie',
+        {
+            time_filter   : time_filter,
+            status_filter : status_filter_echart,
+            date_start    : date_start,
+            date_end      : date_end
+        },
+        function (data, status) {
+            $('#loading').fadeOut('slow', function(){});
+            var data = jQuery.parseJSON(data);
+            showChartPie(data);
+        }
+    );
+}
+
+function showChartPie (data) {
+    $('#echart_price_title').css({'display':'inline-block', 'font-size':'18px', 'font-weight':'bold'});
+    $('#echart_count_title').css({'display':'inline-block', 'font-size':'18px', 'font-weight':'bold'});
+    $('#echart_price_sub').css({'display':'inline-block', 'font-size':'14px', 'color':'#CCCCCC'});
+    $('#echart_count_sub').css({'display':'inline-block', 'font-size':'14px', 'color':'#CCCCCC'});
+
+    require(
+        [
+            'echarts',
+            'echarts/chart/pie',
+            'echarts/chart/funnel'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_price'));
+
+            option = {
+                tooltip : {
+                    trigger: 'item',
+                    formatter: "{a} <br/>{b} : {c} ({d}%)"
+                },
+                legend: {
+                    orient : 'vertical',
+                    x : 'left',
+                    data: data['coupons']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {
+                            show: true, 
+                            type: ['pie', 'funnel'],
+                            option: {
+                                funnel: {
+                                    x: '25%',
+                                    width: '50%',
+                                    funnelAlign: 'left',
+                                    max: 1548
+                                }
+                            }
+                        },
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                // grid : {
+                //     x: 330
+                // },
+                calculable : true,
+                series : [
+                    {
+                        name:'价格分布',
+                        type:'pie',
+                        radius : '55%',
+                        center: ['50%', '60%'],
+                        data : (function () {
+                            var pie_data = [];
+                            for (key in data.content) {
+                                var item = {
+                                    name  : data['content'][key]['coupon'],
+                                    value : data['content'][key]['final_price']
+                                };
+
+                                pie_data.push(item);
+                            }
+
+                            return pie_data;
+                        })()
+                    }
+                ]
+            };material_chart.setOption(option);
+        }
+    );
+
+    require(
+        [
+            'echarts',
+            'echarts/chart/pie',
+            'echarts/chart/funnel'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_count'));
+
+            option = {
+                tooltip : {
+                    trigger: 'item',
+                    formatter: "{a} <br/>{b} : {c} ({d}%)"
+                },
+                legend: {
+                    orient : 'vertical',
+                    x : 'left',
+                    data: data['coupons']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {
+                            show: true, 
+                            type: ['pie', 'funnel'],
+                            option: {
+                                funnel: {
+                                    x: '25%',
+                                    width: '50%',
+                                    funnelAlign: 'left',
+                                    max: 1548
+                                }
+                            }
+                        },
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                // grid : {
+                //     x: 330
+                // },
+                calculable : true,
+                series : [
+                    {
+                        name:'数量分布',
+                        type:'pie',
+                        radius : '55%',
+                        center: ['50%', '60%'],
+                        data : (function () {
+                            var pie_data = [];
+                            for (key in data.content) {
+                                var item = {
+                                    name  : data['content'][key]['coupon'],
+                                    value : data['content'][key]['count']
+                                };
+
+                                pie_data.push(item);
+                            }
+
+                            return pie_data;
+                        })()
+                    }
+                ]
+            };material_chart.setOption(option);
+        }
+    );
+}
+
+function showSetFilterTimeId () {
+    if (show_time_filter == 0) {
+        $('#time_filter_id_span').show();
+        $('#time_filter_id').combobox('setValue', 'noSelect');
+        $('#showSetFilterTimeIdBtn span span:first-child').html('关闭时间范围选取');
+        show_time_filter = 1;
+    } else {
+        $('#time_filter_id_span').hide();
+        $('#time_filter_id').combobox('setValue', 'Days');
+        $('#showSetFilterTimeIdBtn span span:first-child').html('打开时间范围选取');
+        show_time_filter = 0;
+    }
+}
+
+function getChartById () {
+    var id = $('#coupon_id').val();
+    var date_start = jq_date_start.combobox('getValue');
+    var date_end = jq_date_end.combobox('getValue');
+    var time_filter = jq_time_filter_id.combobox('getValue');
+
+    if (id == '') {
+        alert('请先选择优惠券!');
+        return false;
+    }
+
+    if (time_filter == 'noSelect' || (show_time_filter == 0 && time_filter == 'Days' && (date_start == '' || date_end == ''))) {
+        alert('请选择时间范围!');
+        return false;
+    }
+
+
+    $('#loading').fadeIn('slow', function () {});
+
+    $('#echart_price').hide();
+    $('#echart_count').hide();
+    $('#echart_by_id').show();
+    $('#echart_price_title').hide();
+    $('#echart_price_sub').hide();
+    $('#echart_count_title').hide();
+    $('#echart_count_sub').hide();
+
+    $.post(
+        module_router + '/getChartById',
+        {
+            id : id,
+            date_start : date_start,
+            date_end : date_end,
+            time_filter : time_filter,
+            filter_week : show_time_filter
+        },
+        function (data, status) {
+            $('#loading').fadeOut('slow', function(){});
+            var data = jQuery.parseJSON(data);
+            showChartById(data);
+        }
+    );
+}
+
+function showChartById (data) {
+    require(
+        [
+            'echarts',
+            'echarts/chart/line',
+            'echarts/chart/bar'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_by_id'));
+            var option = {
+                tooltip : {
+                    trigger: 'axis'
+                },
+                legend: {
+                    y    : 'bottom',
+                    data : ['原价', '折后价', '数量']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {show: true, type: ['bar', 'line']},
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                calculable : true,
+                xAxis : [
+                    {
+                        type : 'category',
+                        data : data['date_arr']
+                    }
+                ],
+                yAxis : [
+                    {
+                        type : 'value',
+                        name : '价格',
+                        axisLabel : {
+                            formatter: '{value} 元'
+                        }
+                    },
+                    {
+                        type : 'value',
+                        name : '数量',
+                        axisLabel : {
+                            formatter: '{value} 单'
+                        }
+                    }
+                ],
+                series : [
+                    {
+                        name : '原价',
+                        type : 'line',
+                        data : data['content']['price']
+                    },
+                    {
+                        name : '折后价',
+                        type : 'line',
+                        data : data['content']['final_price']
+                    },
+                    {
+                        name : '数量',
+                        type : 'bar',
+                        data : data['content']['count'],
+                        yAxisIndex : 1
+                    }
+                ]
+            };
+            material_chart.setOption(option);
+        }
+    );
+}
+</script>

+ 537 - 0
www/protected/modules/dataview/views/rOrderCountView/index.php

@@ -0,0 +1,537 @@
+<style>
+    .f_label {width: 90px;}
+    .accordion-body {padding: 0;}
+    .options {
+        display: inline-block;
+        border: 1px solid #e5e5e5;
+        background: #fff;
+        color: #000;
+        padding: 3px 6px;
+        text-decoration: none;
+    }
+</style>
+<div id="main">
+<div region="west" border="false" id="west_panel" style="width: 430px;">
+    <table id="dg_content"></table>
+    <div id="tb_content">
+        <div class="tb_line">
+            <p>
+                <span class="tb_label">开始</span>
+                <input type="text" id="date_start" value="<?php echo date('Y-m-d', time()); ?>" style="width: 100px;"/>
+                <span class="tb_label">结束</span>
+                <input type="text" id="date_end" value="<?php echo date('Y-m-d', time()); ?>" style="width: 100px;"/>
+                <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="search_content();return false;">查询</a>
+            </p>
+            <p>
+                <span class="tb_label">筛选</span>
+                <input id="filter_list" />
+            </p>
+        </div>
+    </div>
+</div>
+<div region="center" title="统计图表">
+<div class="easyui-layout detail_layout">
+<div data-options="region:'center'" class="detail_center">
+<div class="detail_main">
+    <form id="content_form">
+        <div id="getEChart">
+            <p>
+                <input id="filter_echart">
+                <span id="filter_time_span">
+                    <input id="filter_time">
+                </span>
+                <span id='date_range_span' style="display:none;">
+                    <input id="date_start_echart" style="width: 100px" />
+                    <input id="date_end_echart" style="width: 100px" />
+                </span>
+                <span id="loading" style="display:none;">正在查询,请稍等</span>
+            </p>
+            <p>
+                <a href="#" class='easyui-linkbutton' iconCls="icon-filter" plain="true" onclick="showSetDateRange();return false;">选择具体日期</a>
+                <a href="#" class='easyui-linkbutton' iconCls="icon-filter" plain="true" onclick="showSetFilterTime();return false;">选择时间范围</a>
+                <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="getChartBar();return false;">获取柱状图</a>
+                <a href="#" class='easyui-linkbutton' iconCls="icon-search" plain="true" onclick="getChartPie();return false;">获取饼状图</a>
+            </p>
+        </div>
+    </form>
+    <div data-options="region:'center'" class="detail_center">
+        <div class="detail_main">
+            <div></div>
+            <div id="echart_price" style="height:450px;width:720px"></div>
+            <div id="echart_count" style="height:450px;width:720px"></div>
+        </div>
+    </div>
+</div>
+</div>
+</div>
+</div>
+</div>
+
+<script src="http://echarts.baidu.com/build/dist/echarts.js"></script>
+<script type="text/javascript">
+var w_width = $(window).width();
+var w_height = $(window).height();
+
+var module_router = site_root + '/index.php?r=dataview/rOrderCountView';
+
+var jq_content_form = $('#content_form');
+var jq_dg_content =$('#dg_content');
+var jq_date_start = $('#date_start');
+var jq_date_end = $('#date_end');
+var jq_date_start_echart = $('#date_start_echart');
+var jq_date_end_echart = $('#date_end_echart');
+var jq_filter_list = $('#filter_list');
+var jq_filter_echart = $('#filter_echart');
+var jq_filter_time = $('#filter_time');
+
+var filter = <?php echo json_encode($filter); ?>;
+var filter_time = <?php echo json_encode($filter_time); ?>;
+
+// 载入echarts配置
+require.config({
+    paths : {
+        echarts: 'http://echarts.baidu.com/build/dist'
+    }
+});
+
+$(function(){
+    var p_width = parseInt(w_width / 2);
+    if (p_width < 520){
+        p_width = 520;
+    }
+
+    jq_date_start.datebox({});
+    jq_date_end.datebox({});
+
+    jq_date_start_echart.datebox({});
+    jq_date_end_echart.datebox({});
+
+    jq_filter_list.combobox({
+        width: 100,
+        data: filter,
+        editable: false,
+        onSelect: function () {
+            search_content();
+        }
+    });
+
+    jq_filter_echart.combobox({
+        width: 100,
+        data: filter,
+        editable: false
+    });
+
+    jq_filter_time.combobox({
+        width: 200,
+        data: filter_time,
+        editable: false
+    })
+
+    $('#main').css({width: w_width - 25, height: w_height - 18}).layout();
+
+    jq_dg_content.datagrid({
+        url: module_router + '/list',
+        title: '订单统计',
+        width: 420,
+        height: w_height - 18,
+        fitColumns: true,
+        autoRowHeight: true,
+        striped: true,
+        toolbar: '#tb_content',
+        singleSelect: true,
+        selectOnCheck: false,
+        checkOnSelect: false,
+        pagination: false,
+        nowrap: false,
+        idField: 'filter_index',
+        sortName: 'count',
+        sortOrder: 'desc',
+        queryParams: get_param_obj(),
+        frozenColumns:[],
+        columns:[[
+            {field: 'filter_str', title: '分类', width: 30},
+            {field: 'ori_price', title: '原价', width:30},
+            {field: 'price', title: '折后', width: 30},
+            {field: 'count', title: '数量', width: 30}
+        ]],
+
+        queryParams: {
+            date_start : jq_date_start.datebox('getValue'),
+            date_end   : jq_date_end.datebox('getValue'),
+            filter     : 1
+        },
+
+        onSelect: function (index, row) {
+            var data = $.extend({}, row);
+            jq_content_form.form('load', data);
+        }
+    });
+});
+
+function search_content () {
+    var date_start = jq_date_start.datebox('getValue');
+    var date_end = jq_date_end.datebox('getValue');
+    var filter_list = jq_filter_list.combobox('getValue');
+
+    jq_dg_content.datagrid({
+        pageNum: 1,
+        queryParams: {
+            filter: filter_list,
+            date_start: date_start,
+            date_end: date_end
+        }
+    });
+}
+
+function showSetDateRange () {
+    jq_filter_time.combobox('setValue', 'Days');
+    jq_date_start_echart.datebox('setValue', '');
+    jq_date_end_echart.datebox('setValue', '');
+
+    $('#filter_time_span').css({'display':'none'});
+    $('#date_range_span').css({'display':'inline-block'});
+}
+
+function showSetFilterTime () {
+    jq_date_start_echart.datebox('setValue', '');
+    jq_date_end_echart.datebox('setValue', '');
+
+    $('#filter_time_span').css({'display':'inline-block'});
+    $('#date_range_span').css({'display':'none'});
+}
+
+function getChartBar () {
+    var filter_echart = jq_filter_echart.combobox('getValue');
+    var filter_time = jq_filter_time.combobox('getValue');
+    var date_start_echart = jq_date_start_echart.combobox('getValue');
+    var date_end_echart = jq_date_end_echart.combobox('getValue');
+
+    $('#loading').fadeIn('slow', function () {});
+
+    $.post(
+        module_router + '/getChartBar',
+        {
+            filter      : filter_echart,
+            filter_time : filter_time,
+            date_start  : date_start_echart,
+            date_end    : date_end_echart
+        },
+        function (data, status) {
+            $('#loading').fadeOut('slow', function () {});
+            var data = jQuery.parseJSON(data);
+            showChartBar(data);
+        }
+    );
+}
+
+function getChartPie () {
+    var date_start_echart = jq_date_start_echart.combobox('getValue');
+    var date_end_echart = jq_date_end_echart.combobox('getValue');
+    var filter_echart = jq_filter_echart.combobox('getValue');
+    var filter_time = jq_filter_time.combobox('getValue');
+
+    $('#loading').fadeIn('slow', function () {});
+
+    $.post(
+        module_router + '/getChartPie',
+        {
+            date_start  : date_start_echart,
+            date_end    : date_end_echart,
+            filter      : filter_echart,
+            filter_time : filter_time
+        },
+        function (data, status) {
+            $('#loading').fadeOut('slow', function () {});
+            var data = jQuery.parseJSON(data);
+            showChartPie(data);
+        }
+    );
+}
+
+function showChartBar (data) {
+    require(
+        [
+            'echarts',
+            'echarts/chart/line',
+            'echarts/chart/bar'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_price'));
+            var option = {
+                title : {
+                    text: '订单价格统计',
+                    subtext: ''
+                },
+                tooltip : {
+                    trigger: 'axis'
+                },
+                legend: {
+                    y    : 'bottom',
+                    data : data['filter_arr']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {show: true, type: ['bar', 'line']},
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                grid : {
+                    y2 : '18%'
+                },
+                calculable : true,
+                xAxis : [
+                    {
+                        type : 'category',
+                        data : data['date_arr']
+                    }
+                ],
+                yAxis : [
+                    {
+                        type : 'value',
+                        name : '价格',
+                        axisLabel : {
+                            formatter: '{value} 元'
+                        }
+
+                    }
+                ],
+                series : (function(){
+                    var series = [];
+
+                    for (var key in data.content) {
+
+                        var item_price = {
+                            name : data['content'][key]['filter'],
+                            type : 'bar',
+                            data : data['content'][key]['price']
+                        }
+
+                        series.push(item_price);
+                    }
+
+                    return series;
+                })()
+            };
+            material_chart.setOption(option);
+        }
+    );
+
+    require(
+        [
+            'echarts',
+            'echarts/chart/line',
+            'echarts/chart/bar'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_count'));
+            var option = {
+                title : {
+                    text: '订单数量统计',
+                    subtext: ''
+                },
+                tooltip : {
+                    trigger: 'axis'
+                },
+                legend: {
+                    y    : 'bottom',
+                    data : data['filter_arr']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {show: true, type: ['bar', 'line']},
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                grid : {
+                    y2 : '18%'
+                },
+                calculable : true,
+                xAxis : [
+                    {
+                        type : 'category',
+                        data : data['date_arr']
+                    }
+                ],
+                yAxis : [
+                    {
+                        type : 'value',
+                        name : '数量',
+                        axisLabel : {
+                            formatter: '{value} 单'
+                        }
+
+                    }
+                ],
+                series : (function(){
+                    var series = [];
+
+                    for (var key in data.content) {
+                        var item_count = {
+                            name : data['content'][key]['filter'],
+                            type : 'line',
+                            data : data['content'][key]['count']
+                        };
+
+                        series.push(item_count);
+                    }
+
+                    return series;
+                })()
+            };
+            material_chart.setOption(option);
+        }
+    );
+}
+
+function showChartPie (data) {
+    require(
+        [
+            'echarts',
+            'echarts/chart/pie',
+            'echarts/chart/funnel'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_price'));
+
+            option = {
+                title : {
+                    text: '订单价格分部',
+                    subtext: ''
+                },
+                tooltip : {
+                    trigger: 'item',
+                    formatter: "{a} <br/>{b} : {c} ({d}%)"
+                },
+                legend: {
+                    orient : 'vertical',
+                    x : 'left',
+                    y : 'bottom',
+                    data: data['filter_arr']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {
+                            show: true, 
+                            type: ['pie', 'funnel'],
+                            option: {
+                                funnel: {
+                                    x: '25%',
+                                    width: '50%',
+                                    funnelAlign: 'left',
+                                    max: 1548
+                                }
+                            }
+                        },
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                calculable : true,
+                series : [
+                    {
+                        name:'价格分布',
+                        type:'pie',
+                        radius : '55%',
+                        center: ['50%', '60%'],
+                        data : (function () {
+                            var pie_data = [];
+                            for (key in data.content) {
+                                var item = {
+                                    name  : data['content'][key]['filter'],
+                                    value : data['content'][key]['price'],
+                                };
+
+                                pie_data.push(item);
+                            }
+
+                            return pie_data;
+                        })()
+                    }
+                ]
+            };material_chart.setOption(option);
+        }
+    );
+
+    require(
+        [
+            'echarts',
+            'echarts/chart/pie',
+            'echarts/chart/funnel'
+        ],
+        function (ec) {
+            var material_chart = ec.init(document.getElementById('echart_count'));
+
+            option = {
+                title : {
+                    text: '订单数量分部',
+                    subtext: ''
+                },
+                tooltip : {
+                    trigger: 'item',
+                    formatter: "{a} <br/>{b} : {c} ({d}%)"
+                },
+                legend: {
+                    orient : 'vertical',
+                    x : 'left',
+                    y : 'bottom',
+                    data: data['filter_arr']
+                },
+                toolbox: {
+                    show : true,
+                    feature : {
+                        mark : {show: true},
+                        dataView : {show: true, readOnly: false},
+                        magicType : {
+                            show: true, 
+                            type: ['pie', 'funnel'],
+                            option: {
+                                funnel: {
+                                    x: '25%',
+                                    width: '50%',
+                                    funnelAlign: 'left',
+                                    max: 1548
+                                }
+                            }
+                        },
+                        restore : {show: true},
+                        saveAsImage : {show: true}
+                    }
+                },
+                calculable : true,
+                series : [
+                    {
+                        name:'数量分布',
+                        type:'pie',
+                        radius : '55%',
+                        center: ['50%', '60%'],
+                        data : (function () {
+                            var pie_data = [];
+                            for (key in data.content) {
+                                var item = {
+                                    name  : data['content'][key]['filter'],
+                                    value : data['content'][key]['count'],
+                                };
+
+                                pie_data.push(item);
+                            }
+
+                            return pie_data;
+                        })()
+                    }
+                ]
+            };material_chart.setOption(option);
+        }
+    );
+}
+</script>