123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- <?php
- namespace app\admin\controller\workorder;
- use app\common\controller\Backend;
- use think\Db;
- /**
- * 工单管理
- *
- * @icon fa fa-circle-o
- */
- class Statistics extends Backend
- {
- /**
- * 模型对象
- * @var \app\admin\model\workorder\Statistics
- */
- public function _initialize()
- {
- parent::_initialize();
- }
- public function index()
- {
- if ($this->request->isAjax()) {
- $this->success('', null, $this->dateOrderTrend());
- }
- // 沟通处理中
- $pending_wo_total = Db::name('workorder_orders')
- ->where('status', 'in', '2,3')
- ->where('deletetime', null)
- ->count('id');
- // 未结单
- $open_wo_total = Db::name('workorder_orders')
- ->where('status', 'in', '0,1,2,3')
- ->where('deletetime', null)
- ->count('id');
- // 待分派
- $assign_wo_total = Db::name('workorder_orders')->where('status', '0')->where('deletetime', null)->count('id');
- // 解决率和满意度
- $evaluate = Db::name('workorder_evaluate')
- ->alias('e')
- ->field('e.stars,e.solved')
- ->join('workorder_orders o', 'o.id=e.order_id')
- ->where('o.deletetime', null)
- ->select();
- $not_evaluated = Db::name('workorder_orders')->where('status', '4')->where('deletetime', null)->count('id');
- $solved_temp = [0, 0];
- $stars_temp = [0, 0, 0, 0, 0];
- foreach ($evaluate as $index => $item) {
- if ($item['solved'] == 0) {
- $solved_temp[0]++;
- } else {
- $solved_temp[1]++;
- }
- $stars_temp[($item['stars'] - 1)]++;
- }
- if ($solved_temp[0] > 0) {
- $solved[] = [
- 'value' => $solved_temp[0],
- 'name' => __('unresolved')
- ];
- }
- if ($solved_temp[1] > 0) {
- $solved[] = [
- 'value' => $solved_temp[1],
- 'name' => __('resolved')
- ];
- }
- for ($i = 0; $i < 5; $i++) {
- if ($stars_temp[$i] > 0) {
- $stars[] = [
- 'value' => $stars_temp[$i],
- 'name' => __('star ' . $i)
- ];
- }
- }
- if ($not_evaluated > 0) {
- $stars[] = [
- 'value' => $not_evaluated,
- 'name' => __('Not evaluated')
- ];
- $solved[] = [
- 'value' => $not_evaluated,
- 'name' => __('Not evaluated')
- ];
- }
- if (!isset($stars)) {
- $stars[] = [
- 'value' => 0,
- 'name' => __('No data available')
- ];
- }
- if (!isset($solved)) {
- $solved[] = [
- 'value' => 0,
- 'name' => __('No data available')
- ];
- }
- $average_time['solution'] = Db::name('workorder_time_statistics')
- ->alias('s')
- ->join('workorder_orders o', 'o.id=s.order_id')
- ->where('o.deletetime', null)
- ->where('s.type', 0)
- ->where('s.time_consum', '>', 0)
- ->avg('s.time_consum');
- $average_time['response'] = Db::name('workorder_time_statistics')
- ->alias('s')
- ->join('workorder_orders o', 'o.id=s.order_id')
- ->where('o.deletetime', null)
- ->where('s.type', 'in', '1,2')
- ->where('s.time_consum', '>', 0)
- ->avg('s.time_consum');
- $average_time['first_response'] = Db::name('workorder_time_statistics')
- ->alias('s')
- ->join('workorder_orders o', 'o.id=s.order_id')
- ->where('o.deletetime', null)
- ->where('s.type', 2)
- ->where('s.time_consum', '>', 0)
- ->avg('s.time_consum');
- foreach ($average_time as $key => $value) {
- if ($value) {
- $h = floor($value / 3600);
- $m = ceil(($value % 3600) / 60);
- $average_time[$key] = [
- 'value' => __('%s hour %s minute', [$h, $m]),
- 'progress' => ceil($h . '.' . $m)
- ];
- $average_time[$key]['progress'] = ($average_time[$key]['progress'] > 100) ? 100 : $average_time[$key]['progress'];
- } else {
- $average_time[$key] = [
- 'value' => __('No data'),
- 'progress' => 0
- ];
- }
- }
- $prefix = config('database.prefix');
- // 类别工单量TOP10
- $sql = "SELECT wc.id,wc.name,
- (SELECT count(id) FROM {$prefix}workorder_orders wo WHERE wo.category_id=wc.id AND wo.deletetime IS NULL) as order_quantity
- FROM {$prefix}workorder_category wc WHERE wc.pid>0 AND wc.deletetime IS NULL ORDER BY order_quantity DESC";
- $workorder_category_top10 = Db::query($sql);
- $order_quantity_sum = array_sum(array_map(function ($val) {
- return $val['order_quantity'];
- }, $workorder_category_top10));
- foreach ($workorder_category_top10 as $index => $item) {
- if ($index <= 9) {
- if ($item['order_quantity'] > 0) {
- $workorder_category_top10[$index]['progress'] = round(($item['order_quantity'] / $order_quantity_sum) * 100, 2);
- } else {
- $workorder_category_top10[$index]['progress'] = 0;
- }
- } else {
- unset($workorder_category_top10[$index]);
- }
- }
- $workorder_engineers_top10 = Db::name('workorder_engineers')
- ->field('id,title,work_order_quantity')
- ->where('deletetime', null)
- ->where('status', '1')
- ->order('work_order_quantity desc')
- ->limit(10)
- ->select();
- $avg_response_time_top10 = Db::name('workorder_engineers')
- ->field('id,title,avg_response_time')
- ->where('deletetime', null)
- ->where('status', '1')
- ->order('avg_response_time desc')
- ->limit(10)
- ->select();
- foreach ($avg_response_time_top10 as $index => $item) {
- if ($item['avg_response_time'] > 0) {
- $h = floor($item['avg_response_time'] / 3600);
- $m = ceil(($item['avg_response_time'] % 3600) / 60);
- $avg_response_time_top10[$index]['avg_response_time'] = __('%s hour %s minute', [$h, $m]);
- } else {
- $avg_response_time_top10[$index]['avg_response_time'] = __('No data');
- }
- }
- $this->view->assign([
- 'wo_total' => Db::name('workorder_orders')->where('deletetime', null)->count('id'),
- 'pending_wo_total' => $pending_wo_total,
- 'open_wo_total' => $open_wo_total,
- 'assign_wo_total' => $assign_wo_total,
- 'average_time' => $average_time,
- 'workorder_category_top10' => $workorder_category_top10,
- 'workorder_engineers_top10' => $workorder_engineers_top10,
- 'avg_response_time_top10' => $avg_response_time_top10
- ]);
- $this->assignconfig([
- 'orderTrend' => $this->dateOrderTrend(),
- 'solved' => $solved,
- 'stars' => $stars
- ]);
- return $this->view->fetch();
- }
- /**
- * 日期范围内的订单趋势
- */
- public function dateOrderTrend()
- {
- $date = $this->request->request('date');
- if ($date) {
- $date = explode(' - ', $date);
- $date = array_map("strtotime", $date);
- } else {
- $date[0] = \fast\Date::unixtime('day', -6);
- $date[1] = \fast\Date::unixtime('day', 0, 'end');
- }
- if ($date[0] >= $date[1]) {
- $this->error(__('The start time must be less than the end time'));
- }
- $orders = Db::name('workorder_orders')
- ->field("id,createtime")
- ->where('deletetime', null)
- ->where('createtime', 'BETWEEN', implode(',', $date))
- ->order('createtime asc')
- ->select();
- $temp = [];
- $columns = [];
- $data = [];
- if (($date[1] - $date[0]) <= 86400) {
- // 时间数组准备
- for ($i = 0; $i <= 23; $i++) {
- $temp[($i < 10 ? '0' . $i : $i) . ':00'] = 0;
- }
- // 累计各个时间的订单量
- foreach ($orders as $index => $item) {
- $createtime = date('H', $item['createtime']) . ':00';
- $temp[$createtime]++;
- }
- } else {
- // 日期数组准备
- do {
- $temp[date('Y-m-d', $date[0])] = 0;
- $date[0] = $date[0] + 86400;
- } while ($date[0] < $date[1]);
- // 累计各个日期的订单量
- foreach ($orders as $index => $item) {
- $createtime = date('Y-m-d', $item['createtime']);
- $temp[$createtime]++;
- }
- }
- foreach ($temp as $index => $item) {
- $columns[] = $index;
- $data[] = $item;
- }
- return [
- 'columns' => $columns,
- 'data' => $data,
- 'sum' => array_sum($data)
- ];
- }
- }
|