diff --git a/application/admin/controller/statistics/Dispatcher.php b/application/admin/controller/statistics/Dispatcher.php index b09288b..b756e2b 100644 --- a/application/admin/controller/statistics/Dispatcher.php +++ b/application/admin/controller/statistics/Dispatcher.php @@ -2,10 +2,12 @@ namespace app\admin\controller\statistics; +use app\admin\model\Admin; use app\admin\model\Order; use app\common\controller\Backend; use think\exception\DbException; use think\response\Json; +use function Symfony\Component\Clock\now; /** * 订单列管理 @@ -46,32 +48,76 @@ class Dispatcher extends Backend */ public function index() { - - - $this->chart(); + //$this->chart(); + $today = now()->format('Y-m-d'); + $today_end = now()->format('Y-m-d'); //设置过滤方法 $this->request->filter(['strip_tags', 'trim']); if (false === $this->request->isAjax()) { + $this->assign('daterange',$today.' - '.$today_end); + return $this->view->fetch(); } - //如果发送的来源是 Selectpage,则转发到 Selectpage - if ($this->request->request('keyField')) { - return $this->selectpage(); + + $filter = $this->request->param('filter'); + $filter = json_decode($filter,true); + + if(!empty($filter['daterange'])){ + $arr = explode(' - ',$filter['daterange']); + if(trim($arr[0])){ + $filter['start_time'] = trim($arr[0]); + } + if(trim($arr[1])){ + $filter['end_time'] = trim($arr[1]); + } } - [$where, $sort, $order, $offset, $limit] = $this->buildparams(); - $list = $this->model - ->where($where) - ->order($sort, $order) - ->paginate($limit); - $result = ['total' => $list->total(), 'rows' => $list->items()]; + + $list = $this->chart($filter,false); + + $result = array("total" => $list->total(), "rows" => $list->items()); + return json($result); } - //图表统计 - public function chart(){ - $filter = $this->request->param('filter/a',[]); + public function chartData() + { + $filter = $this->request->post(); + + if(!empty($filter['daterange'])){ + $arr = explode(' - ',$filter['daterange']); + if(trim($arr[0])){ + $filter['start_time'] = trim($arr[0]); + } + if(trim($arr[1])){ + $filter['end_time'] = trim($arr[1]).' 23:59:59'; + } + } + + $data = $this->chart($filter,true); + + + $newData = [ + ['派单员','总业绩(¥)','转化率(%)','利润率(%)','变现值'] + ]; + foreach ($data as $datum){ + $newData[] = [ + $datum['admin_user'], + $datum['performance'], + $datum['trans_rate'], + $datum['performance_rate'], + $datum['cash_value'], + ]; + } + return $newData; + } + + //图表统计 + public function chart($filter,$getAll=false){ + + + $orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID)); @@ -106,9 +152,8 @@ class Dispatcher extends Backend }else{ //按录单时间 $time_field = 'create_time'; } - $builder->whereBetween($time_field,$filter['start_time'],$filter['end_time']); + $builder->whereBetween($time_field,[$filter['start_time'],$filter['end_time']]); } - //城市 if(!empty($filter['area_id'])){ $builder->where('area_id',$filter['area_id']); @@ -117,26 +162,46 @@ class Dispatcher extends Backend if(!empty($filter['item_id'])){ $builder->where('item_id',$filter['item_id']); } - $data = $builder->group('dispatch_admin_id')->select(); + + if($getAll){ + $data = $builder->group('dispatch_admin_id')->select(); + }else{ + $data = $builder->group('dispatch_admin_id')->paginate(); + } $newData = []; - foreach ($data as $datum){ - //利润率 = 总业绩/总成效额 - $datum->performance_rate = $this->_calc($datum->performance,$datum->total); - //转化率 = 完单数 / 总订单数 - $datum->trans_rate = $this->_calc($datum->finish_num,$datum->count_num); - //变现值 = 总业绩 / 总订单数 - $datum->cash_value = $this->_calc($datum->performance,$datum->count_num,2); - //客单利润 = 总利润 / 完单数 - $datum->performance_avg = $this->_calc($datum->performance,$datum->finish_num,2); - //客单价 = 总成效额 / 完单数 - $datum->total_avg = $this->_calc($datum->total,$datum->finish_num,2); + if(!empty($data)){ + foreach ($data as &$datum){ + //利润率 = 总业绩/总成效额 + $datum->performance_rate = $this->_calc($datum->performance,$datum->total,4,true); + //转化率 = 完单数 / 总订单数 + $datum->trans_rate = $this->_calc($datum->finish_num,$datum->count_num,4,true); + //变现值 = 总业绩 / 总订单数 + $datum->cash_value = $this->_calc($datum->performance,$datum->count_num,2); + //客单利润 = 总利润 / 完单数 + $datum->performance_avg = $this->_calc($datum->performance,$datum->finish_num,2); + //客单价 = 总成效额 / 完单数 + $datum->total_avg = $this->_calc($datum->total,$datum->finish_num,2); - $newData[] = $datum->toArray(); + if(!empty($datum->dispatch_admin_id)){ + $datum->admin_user = Admin::where($datum->dispatch_admin_id)->value('nickname')??'系统'; + }else{ + $datum->admin_user = '系统'; + } + $datum->avg_time_diff = $this->_calc($datum->avg_time_diff,3600,2); + + $datum->id = $datum->dispatch_admin_id; + $newData[] = $datum->toArray(); + } } - dump($newData);exit; + if($getAll){ + return $newData; + }else{ + return $data; + } + //dump($newData);exit; } @@ -146,8 +211,14 @@ class Dispatcher extends Backend * @param $scale * @return int|string */ - private function _calc($a,$b,$scale=4){ - return $b > 0 ? bcdiv($a,$b,$scale) : 0; + private function _calc($a,$b,$scale=4,$is_percent=false){ + $val = $b > 0 ? bcdiv($a,$b,$scale) : 0; + + if($is_percent){ + + return bcmul($val,100,2); + } + return $val; } } diff --git a/application/admin/view/statistics/dispatcher/index.html b/application/admin/view/statistics/dispatcher/index.html index 25676e8..f973066 100644 --- a/application/admin/view/statistics/dispatcher/index.html +++ b/application/admin/view/statistics/dispatcher/index.html @@ -1,46 +1,66 @@
-
- {:build_heading(null,FALSE)} -
-
-
-
- - {:__('Add')} - {:__('Edit')} - {:__('Delete')} - +
+
+ + -
+ +
+
+ +
+
diff --git a/application/common/model/OrderDispatch.php b/application/common/model/OrderDispatch.php index 4de16f0..7ae55f7 100644 --- a/application/common/model/OrderDispatch.php +++ b/application/common/model/OrderDispatch.php @@ -21,6 +21,10 @@ class OrderDispatch extends Model public function getArriveImagesAttr($val) { + if (empty($val)) { + return []; + } + $images = explode(',', $val); foreach ($images as $k => $v) { $images[$k] = cdnurl($v, true); @@ -31,6 +35,10 @@ class OrderDispatch extends Model public function getImagesAttr($val) { + if (empty($val)) { + return []; + } + $images = explode(',', $val); foreach ($images as $k => $v) { $images[$k] = cdnurl($v, true); @@ -41,6 +49,10 @@ class OrderDispatch extends Model public function getImageAttr($val) { + if (empty($val)) { + return ''; + } + return cdnurl($val, true); } } diff --git a/application/config.php b/application/config.php index a92b1f1..826251f 100755 --- a/application/config.php +++ b/application/config.php @@ -218,7 +218,7 @@ return [ 'host' => Env::get('redis.redis_host'), // Redis 服务器地址 'port' => Env::get('redis.redis_port'), // Redis 端口 'password' => Env::get('redis.redis_password'), // Redis 密码,如果有的话 - 'select' => Env::get('redis.redis_db'), + 'select' => 5, ], // +---------------------------------------------------------------------- // | Cookie设置 diff --git a/application/services/WorkerService.php b/application/services/WorkerService.php index a98feb5..b053f81 100644 --- a/application/services/WorkerService.php +++ b/application/services/WorkerService.php @@ -3,9 +3,7 @@ namespace app\services; use app\common\library\Token; -use EasyWeChat\Factory; -use EasyWeChat\Kernel\Exceptions\InvalidConfigException; -use EasyWeChat\MiniProgram\Application; +use EasyWeChat\MiniApp\Application; class WorkerService extends BaseService { @@ -47,8 +45,9 @@ class WorkerService extends BaseService { $app = $this->getMiniProgramApp(); try { - $info = $app->auth->session($code); - } catch (InvalidConfigException $e) { + $utils = $app->getUtils(); + $info = $utils->codeToSession($code); + } catch (\Exception $e) { $this->apiError('登录失败', $e); } @@ -82,18 +81,31 @@ class WorkerService extends BaseService 'app_id' => config('mini_program.app_id'), 'secret' => config('mini_program.secret'), ]; - return Factory::miniProgram($config); + return new Application($config); } /** - * 解密微信手机号 + * 通过 code 获取用户手机号 + * @param string $code + * @return array + */ + private function code2PhoneNumberInfo(string $code): array + { + $app = $this->getMiniProgramApp(); + $phoneInfo = $app->getClient()->postJson('wxa/business/getuserphonenumber', ['code' => $code]); + + return $phoneInfo->toArray(); + } + + /** + * 获取用户手机号 * @param string $code * @return mixed */ public function getPhoneNumber(string $code) { - //getPhoneNumber 方法通过魔术方法 __call 获取 - $phoneInfo = $this->getMiniProgramApp()->getPhoneNumber($code); + //通过 code 获取手机号信息 + $phoneInfo = $this->code2PhoneNumberInfo($code); if (empty($phoneInfo)) { $this->apiError('获取手机号失败', 0, $phoneInfo); @@ -137,4 +149,40 @@ class WorkerService extends BaseService return true; } + + /** + * 更新师傅位置 + * @param int $workerId + * @param float $latitude + * @param float $longitude + * @return true + */ + public function updateWorkerLocation(int $workerId, float $latitude, float $longitude) + { + $worker = $this->getWorkerModel()->find($workerId); + if (empty($worker)) { + $this->apiError('更新位置失败,用户不存在'); + } + + $worker->lat = $latitude; + $worker->lng = $longitude; + $worker->location_update_time = datetime(time()); + $worker->update_time = datetime(time()); + $worker->save(); + + return true; + } } + + + + + + + + + + + + + diff --git a/application/worker/controller/Worker.php b/application/worker/controller/Worker.php index 38eecc0..5b42d65 100644 --- a/application/worker/controller/Worker.php +++ b/application/worker/controller/Worker.php @@ -77,4 +77,21 @@ class Worker extends WorkerApi { $this->success('操作成功', $this->user); } + + /** + * 更新师傅位置 + * @return void + */ + public function updateWorkerLocation() + { + $params = $this->request->request(); + $validate = $this->validate($params, \app\worker\validate\Worker::class . '.updateWorkerLocation'); + if ($validate !== true) { + $this->error($validate); + } + + $this->getWorkerService()->updateWorkerLocation($this->user['id'], $params['latitude'], $params['longitude']); + + $this->success('操作成功'); + } } diff --git a/application/worker/validate/Worker.php b/application/worker/validate/Worker.php index 43c1b06..db2a52b 100644 --- a/application/worker/validate/Worker.php +++ b/application/worker/validate/Worker.php @@ -9,6 +9,8 @@ class Worker extends Validate protected $rule = [ 'code' => 'require|max:128', 'vendor_token' => 'require|max:128', + 'latitude' => 'require|number', + 'longitude' => 'require|number', ]; protected $message = [ @@ -18,5 +20,6 @@ class Worker extends Validate protected $scene = [ 'login' => ['code'], 'bindPhoneNumber' => ['code', 'vendor_token'], + 'updateWorkerLocation' => ['latitude', 'longitude'], ]; } diff --git a/public/assets/js/backend/orders/dispatchlog.js b/public/assets/js/backend/orders/dispatchlog.js index bd77d03..94902f6 100644 --- a/public/assets/js/backend/orders/dispatchlog.js +++ b/public/assets/js/backend/orders/dispatchlog.js @@ -84,7 +84,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'id', title: __('Id')}, //{field: 'dispatch_id', title: __('Dispatch_id')}, //{field: 'worker_id', title: __('Worker_id')}, - {field: 'remark', title: __('跟进内容'), operate: 'LIKE', table: table2, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'remark', title: __('跟进内容'), operate: false, table: table1, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'images', title: __('跟进依据'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.images}, /* {field: 'need_notice', title: __('需要提醒'), searchList: {"0":__('否'),"1":__('是')}, formatter: Table.api.formatter.normal}, {field: 'notice_time', title: __('提醒时间'), operate:'RANGE', addclass:'datetimerange', autocomplete:false},*/ @@ -121,7 +121,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin //{field: 'worker_id', title: __('Worker_id')}, // {field: 'status', title: __('Status')}, {field: 'status_text', title: __('Status_text'), operate: 'LIKE'}, - {field: 'remark', title: __('Remark'), operate: 'LIKE', table: table1, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'remark', title: __('Remark'), operate: false, table: table2, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, // {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} ] diff --git a/public/assets/js/backend/statistics/dispatcher.js b/public/assets/js/backend/statistics/dispatcher.js index 572fb87..7af3b11 100644 --- a/public/assets/js/backend/statistics/dispatcher.js +++ b/public/assets/js/backend/statistics/dispatcher.js @@ -1,88 +1,185 @@ -define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts', 'echarts-theme', 'template','addtabs','moment'], function ($, undefined, Backend, Table, Form,Echarts,undefined,Template,Datatable,Moment) { var Controller = { + index: function () { - // 初始化表格参数配置 - Table.api.init({ - extend: { - index_url: 'statistics/dispatcher/index' + location.search, - add_url: 'statistics/dispatcher/add', - edit_url: 'statistics/dispatcher/edit', - del_url: 'statistics/dispatcher/del', - multi_url: 'statistics/dispatcher/multi', - import_url: 'statistics/dispatcher/import', - table: 'order', + //绑定事件 + $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { + var $targetPanel = $($(this).attr("href")); + var tabVal = $(this).data('val'); + + if (tabVal === 'second') { + // 当切换到“统计列表”时,自动刷新表格 + //$targetPanel.find(".btn-refresh").trigger("click"); + // 初始化表格参数配置 + Table.api.init(); + // 表格2 + var table2 = $("#table2"); + table2.bootstrapTable({ + url: 'statistics/dispatcher/index' + location.search, + toolbar: '#toolbar1', + sortName: 'id', + search: false, + commonSearch:true, + visible: false, + showToggle: false, + showColumns: false, + showExport: true, + searchFormVisible:true, + columns: [ + [ + //{field: 'id', title: __('Id')}, + {field: 'id', title: __('ID'),visible:false,operate: false}, + {field: 'admin_user', title: __('派单员'),operate: "LIKE"}, + {field: 'count_num', title: __('总订单数'),operate: false}, + {field: 'finish_num', title: __('完单数'),operate: false}, + {field: 'total', title: __('成效额(¥)'), operate: false}, + {field: 'performance', title: __('总业绩(¥)'), operate: false}, + {field: 'cost_total', title: __('总成本(¥)'), operate: false}, + {field: 'refund_total', title: __('退款金额(¥)'), operate: false}, + {field: 'refund_count', title: __('退款单数'), operate: false}, + + {field: 'performance_rate', title: __('利润率(%)'), operate: false}, + {field: 'trans_rate', title: __('转化率(%)'), operate: false}, + {field: 'cash_value', title: __('变现值'), operate: false}, + {field: 'performance_avg', title: __('客单利润(¥)'), operate: false}, + {field: 'total_avg', title: __('客单价(¥)'), operate: false}, + + {field: 'avg_time_diff', title: __('派单时效(小时)'), operate: false}, + + //{field: 'admin_user', title: __('派单员'),operate: "LIKE",visible:false}, + //{field: 'city_name', title: __('城市'),operate: "LIKE",visible:false}, + //{field: 'city_name', title: __('城市'),operate: "LIKE",visible:false}, + {field: 'time_by', title: __('时间维度'), visible:false,searchList: {"1":__('录单时间'),"2":__('派单时间')},defaultValue:1, formatter: Table.api.formatter.normal}, + {field: 'daterange', title: __('时间筛选'), addclass:'datetimerange', + autocomplete:false, + operate: "RANGE", + datetimeFormat: "YYYY-MM-DD", + //defaultValue:today()+' - '+today(), + data:'autocomplete="off" data-local={"format":"YYYY-MM-DD"}', + visible:false}, + + // {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ] + }); + // 为表格2绑定事件 + Table.api.bindevent(table2); } + }); - var table = $("#table"); - // 初始化表格 - table.bootstrapTable({ - url: $.fn.bootstrapTable.defaults.extend.index_url, - pk: 'id', - sortName: 'id', - fixedColumns: true, - fixedRightNumber: 1, - columns: [ - [ - {checkbox: true}, - {field: 'id', title: __('Id')}, - {field: 'order_no', title: __('Order_no'), operate: 'LIKE'}, - {field: 'customer', title: __('Customer'), operate: 'LIKE'}, - {field: 'tel', title: __('Tel'), operate: 'LIKE'}, - {field: 'status', title: __('Status'), searchList: {"0":__('Status 0'),"10":__('Status 10'),"20":__('Status 20'),"30":__('Status 30'),"40":__('Status 40'),"50":__('Status 50'),"60":__('Status 60'),"-10":__('Status -10')}, formatter: Table.api.formatter.status}, - {field: 'area_id', title: __('Area_id'), operate: 'LIKE'}, - {field: 'address', title: __('Address'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, - {field: 'lng', title: __('Lng'), operate:'BETWEEN'}, - {field: 'lat', title: __('Lat'), operate:'BETWEEN'}, - {field: 'work_tel_id', title: __('Work_tel_id')}, - {field: 'source_shop', title: __('Source_shop'), operate: 'LIKE'}, - {field: 'source', title: __('Source')}, - {field: 'source_uid', title: __('Source_uid'), operate: 'LIKE'}, - {field: 'item_id', title: __('Item_id')}, - {field: 'item_title', title: __('Item_title'), operate: 'LIKE'}, - {field: 'detail', title: __('Detail'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, - {field: 'remark', title: __('Remark'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, - {field: 'images', title: __('Images'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.images}, - {field: 'plan_time', title: __('Plan_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, - {field: 'admin_id', title: __('Admin_id')}, - {field: 'coupon_id', title: __('Coupon_id')}, - {field: 'total', title: __('Total'), operate:'BETWEEN'}, - {field: 'online_amount', title: __('Online_amount'), operate:'BETWEEN'}, - {field: 'offline_amount', title: __('Offline_amount'), operate:'BETWEEN'}, - {field: 'online_amount_last', title: __('Online_amount_last'), operate:'BETWEEN'}, - {field: 'offline_amount_type', title: __('Offline_amount_type'), searchList: {"1":__('Offline_amount_type 1'),"2":__('Offline_amount_type 2')}, formatter: Table.api.formatter.normal}, - {field: 'discount_amount', title: __('Discount_amount'), operate:'BETWEEN'}, - {field: 'refund_amount', title: __('Refund_amount'), operate:'BETWEEN'}, - {field: 'worker_refund_amount', title: __('Worker_refund_amount'), operate:'BETWEEN'}, - {field: 'real_amount', title: __('Real_amount'), operate:'BETWEEN'}, - {field: 'cost', title: __('Cost'), operate:'BETWEEN'}, - {field: 'material_cost', title: __('Material_cost'), operate:'BETWEEN'}, - {field: 'performance', title: __('Performance'), operate:'BETWEEN'}, - {field: 'cancel_reason_id', title: __('Cancel_reason_id')}, - {field: 'cancel_detail', title: __('Cancel_detail'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, - {field: 'audit_remark', title: __('Audit_remark'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, - {field: 'audit_admin_id', title: __('Audit_admin_id')}, - {field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, - {field: 'update_time', title: __('Update_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, - {field: 'delete_time', title: __('Delete_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, - {field: 'dispatch_type', title: __('Dispatch_type')}, - {field: 'receive_type', title: __('Receive_type')}, - {field: 'revisit_id', title: __('Revisit_id')}, - {field: 'dispatch_admin_id', title: __('Dispatch_admin_id')}, - {field: 'dispatch_admin_user', title: __('Dispatch_admin_user'), operate: 'LIKE'}, - {field: 'dispatch_time', title: __('Dispatch_time'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, - {field: 'aftersale_id', title: __('Aftersale_id')}, - {field: 'amount_images', title: __('Amount_images'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.images}, - {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} - ] - ] + + // 触发 tab 后发起 ajax 获取图表数据 + $('ul.nav-tabs li.active a[data-toggle="tab"]').on("shown.bs.tab", function () { + getChartData(); }); - // 为表格绑定事件 - Table.api.bindevent(table); + + function getChartData(){ + // 获取单选框选中的值 + var timeBy = $('input[name="filter[time_by]"]:checked').val(); + + // 获取日期范围值 + var daterange = $('#daterange').val(); + + // 构建查询参数 + var params = { + 'time_by': timeBy, + 'daterange': daterange + }; + + $.ajax({ + url: "statistics/dispatcher/chartData", // + type: "POST", + dataType: "json", + data:params, + success: function (response) { + // 数据结构 + // response = { + // source: [ + // ['产品销售', '2015', '2016', '2017'], + // ['风扇', 43.3, 85.8, 93.7], + // ... + // ] + // } + + var barChart = Echarts.init(document.getElementById('bar-chart'), 'walden'); + var option = { + legend: {}, + tooltip: {}, + dataset: { + source: response + }, + xAxis: { type: 'category' }, + yAxis: {}, + series: [ + { type: 'bar' }, + { type: 'bar' }, + { type: 'bar' }, + { type: 'bar' } + ] + }; + barChart.setOption(option); + }, + error: function () { + console.error("图表数据加载失败"); + } + }); + } + + + + + var form = $("#chart-filter"); + var ranges = {}; + ranges[__('Today')] = [Moment().startOf('day'), Moment().endOf('day')]; + ranges[__('Yesterday')] = [Moment().subtract(1, 'days').startOf('day'), Moment().subtract(1, 'days').endOf('day')]; + ranges[__('Last 7 Days')] = [Moment().subtract(6, 'days').startOf('day'), Moment().endOf('day')]; + ranges[__('Last 30 Days')] = [Moment().subtract(29, 'days').startOf('day'), Moment().endOf('day')]; + ranges[__('This Month')] = [Moment().startOf('month'), Moment().endOf('month')]; + ranges[__('Last Month')] = [Moment().subtract(1, 'month').startOf('month'), Moment().subtract(1, 'month').endOf('month')]; + ranges[__('今年')] = [Moment().startOf('year'), Moment().endOf('year')]; + var options = { + timePicker: false, + autoUpdateInput: false, + timePickerSeconds: true, + timePicker24Hour: true, + autoApply: true, + locale: { + format: 'YYYY-MM-DD', + customRangeLabel: __("Custom Range"), + applyLabel: __("Apply"), + cancelLabel: __("Clear"), + }, + ranges: ranges, + }; + var callback = function (start, end) { + $(this.element).val(start.format(options.locale.format) + " - " + end.format(options.locale.format)); + }; + require(['bootstrap-daterangepicker'], function () { + $(".datetimerange", form).each(function () { + $(this).on('apply.daterangepicker', function (ev, picker) { + callback.call(picker, picker.startDate, picker.endDate); + var label = picker.chosenLabel; + $(picker.element).data('label', label).trigger("change"); + }); + $(this).on('cancel.daterangepicker', function (ev, picker) { + $(this).val(''); + }); + $(this).daterangepicker($.extend({}, options), callback); + }); + }); + + // 手动触发一次激活 tab 的 shown.bs.tab + getChartData(); + // 绑定查询按钮的点击事件 + $('#filter-btn').on('click', function() { + getChartData(); + }); }, + add: function () { Controller.api.bindevent(); },