Browse Source

预报到统计优化

master
Hjj 5 hours ago
parent
commit
de69d178be
  1. 154
      app/Admin/Controllers/UserFollowOverviewController.php
  2. 2
      app/Admin/Controllers/UserFollowRecordController.php
  3. 60
      app/Admin/Metrics/Examples/Follow/AllColleges.php
  4. 143
      app/Admin/Metrics/Examples/Follow/AllCollegesCharts.php
  5. 149
      app/Admin/Metrics/Examples/Follow/AllCollegesFollowCharts.php
  6. 123
      app/Admin/Repositories/UserFollowOverview.php

154
app/Admin/Controllers/UserFollowOverviewController.php

@ -2,121 +2,101 @@ @@ -2,121 +2,101 @@
namespace App\Admin\Controllers;
use App\Admin\Metrics\Examples\Follow\AllEnrollCollege;
use App\Admin\Metrics\Examples\Follow\AllEnrollSpeciality;
use App\Admin\Metrics\Examples\Follow\AllNewFollowCollege;
use App\Admin\Metrics\Examples\Follow\AllNewFollowSpeciality;
use App\Http\Controllers\Controller;
use App\Admin\Metrics\Examples\Follow\AllColleges;
use App\Admin\Metrics\Examples\Follow\AllCollegesCharts;
use App\Admin\Repositories\UserFollowOverview;
use App\Models\AdminFollowShow;
use App\Models\SecondaryCollege;
use App\Models\Speciality;
use App\Models\UserFollowStatus;
use App\Models\UsersMember;
use Dcat\Admin\Admin;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Widgets\Card;
use Illuminate\Http\Request;
class UserFollowOverviewController extends Controller
class UserFollowOverviewController extends AdminController
{
public $showInfo;
// 回访状态
public $followStatusList = [];
// 回访状态选项框默认值
public $lastElement;
// 学院select选项
public $secondaryCollegeList = [];
// 专业select选项
public $specialityList = [];
public $title = '回访统计';
public function index(Content $content): Content
{
$this->showInfo = AdminFollowShow::query()->where(['user_id' => Admin::user()['id']])->first();
$this->followStatusList = UserFollowStatus::query()->orderByDesc('id')->pluck('name', 'id')->toArray();
$this->lastElement = array_slice($this->followStatusList, -1, 1, true);
$this->secondaryCollegeList = SecondaryCollege::query()->whereIn('id', $this->showInfo['secondary_college_id'] ?? [])->pluck("name", "id");
$list = Speciality::query()->whereIn("id", $this->showInfo['speciality_id'] ?? [])->get()->toArray();
foreach ($list as $item) {
$college = SecondaryCollege::query()->where("id", $item["secondary_college_id"])->first();
$this->specialityList[$item["id"]] = $item["speciality_name"] . "({$college->name})";
}
return $content
->header('新生数据概览')
->description('各项数据统计详情')
->body(function (Row $row) {
->header('数据概览')
->body(function ($row) {
$row->column(12, function (Column $column) {
$getData = [
'secondary_college_id' => request()->get('secondary_college_id', ''),
'speciality_id' => request()->get('speciality_id', ''),
'follow_id' => request()->get('follow_id', ''),
];
if (empty($getData['secondary_college_id'])) {
$getData['secondary_college_id'] = $this->showInfo['secondary_college_id'] ?? "";
}
$column->row(function (Row $row) use ($getData) {
$row->column(12, $this->table($getData));
});
$column->row(function (Row $row) use ($getData) {
$row->column(4, new AllEnrollCollege($getData));
$row->column(4, new AllNewFollowCollege($getData));
$column->row(function (Row $row) {
$row->column(6, Card::make('各学院新生录取统计', AllCollegesCharts::make()));
$row->column(6, new AllColleges(['title' => '全校新生录取人数', 'collagesId' => 0]));
});
$column->row(function (Row $row) use ($getData) {
$row->column(4, new AllEnrollSpeciality($getData));
$row->column(4, new AllNewFollowSpeciality($getData));
});
Admin::script(<<<JS
var table = document.getElementsByClassName("data-table")
for (var i = 0; i < table.length; i++) {
table[i].style.display = "none";
}
JS
);
});
});
})
->body($this->grid());
}
protected function table($getData): Grid
protected function grid(): Grid
{
return Grid::make(new UsersMember(), function (Grid $grid) use ($getData) {
// 禁用
$grid->disableToolbar();
// 禁用
$grid->disablePagination();
// 禁用操作
return Grid::make(new UserFollowOverview(), function (Grid $grid) {
$grid->disableCreateButton();
$grid->disableActions();
// 禁用批量操作
$grid->disableBatchActions();
// 禁用行选择
$grid->disableRefreshButton();
$grid->disableRowSelector();
// 禁用创建
$grid->disableCreateButton();
$grid->filter(function (Grid\Filter $filter) {
$grid->disableToolbar();
$grid->paginate(10);
$followStatus = UserFollowStatus::query()->get()->toArray();
$showInfo = AdminFollowShow::query()->where(['user_id' => Admin::user()['id']])->first();
$collegeAll = SecondaryCollege::query()->whereIn('id', $showInfo['secondary_college_id'] ?? [])->pluck("name", "id")->toArray();
$grid->combine('总录取', ['enroll_number', 'enroll_man_student', 'enroll_girl_student']);
$grid->combine('未联系', ['out_number', 'out_man_student', 'out_girl_student']);
foreach ($followStatus as $k => $v) {
$grid->combine($v['name'], ["total_number{$v['id']}", "man_student{$v['id']}", "girl_student{$v['id']}"]);
}
$grid->column('secondary_college_id', '二级学院');
$grid->column('speciality_name', '专业');
$grid->column('enroll_number', '总人数');
$grid->column('enroll_man_student', '男生');
$grid->column('enroll_girl_student', '女生');
$grid->column('out_number', '总人数');
$grid->column('out_man_student', '男生');
$grid->column('out_girl_student', '女生');
foreach ($followStatus as $k => $v) {
$grid->column("total_number{$v['id']}", '总人数');
$grid->column("man_student{$v['id']}", '男生');
$grid->column("girl_student{$v['id']}", '女生');
}
$grid->filter(function (Grid\Filter $filter) use ($collegeAll, $showInfo) {
$filter->panel();
$filter->expand();
$filter->equal('secondary_college_id', '学院')
->select($this->secondaryCollegeList)
$filter->equal('secondary_college_id', '二级学院')
->select($collegeAll)
->load('speciality_id', '/api/getSpecialityList')
->ignore()
->width(2);
->width(3)
->ignore();
$filter->equal('speciality_id', '专业')
->select($this->specialityList)
->ignore()
->width(3);
$filter->equal('follow_id', '回访状态')
->select($this->followStatusList)
->ignore()
->width(2);
->select(function () use ($showInfo) {
$list = Speciality::query()->whereIn('id', $showInfo['speciality_id'] ?? [])->get()->toArray();
if (empty($list)) {
return [];
}
$select = [];
foreach ($list as $item) {
$college = SecondaryCollege::query()->where("id", $item["secondary_college_id"])->first();
$select[$item["id"]] = $item["speciality_name"] . "({$college->name})";
}
return $select;
})
->width(3)
->ignore();
});
});
}

2
app/Admin/Controllers/UserFollowRecordController.php

@ -4,8 +4,6 @@ namespace App\Admin\Controllers; @@ -4,8 +4,6 @@ namespace App\Admin\Controllers;
use App\Admin\Actions\Form\Follow\EditEnrollStatusForm;
use App\Admin\Actions\Form\Follow\FollowRecordForm;
use App\Admin\Renderable\UserFamilyMeberTable;
use App\Admin\Renderable\UserFamilyTable;
use App\Models\AdminFollowShow;
use App\Models\AdmissionNewStudents;
use App\Models\SecondaryCollege;

60
app/Admin/Metrics/Examples/Follow/AllColleges.php

@ -2,12 +2,23 @@ @@ -2,12 +2,23 @@
namespace App\Admin\Metrics\Examples\Follow;
use App\Models\SecondaryCollege;
use App\Models\AdmissionNewStudents;
use App\Models\Speciality;
use App\Models\UsersMember;
use Dcat\Admin\Widgets\Metrics\Round;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class AllColleges extends Round
{
public $allData;
// 构造方法参数必须设置默认值
public function __construct($data)
{
$this->allData = $data;
parent::__construct();
}
/**
* 初始化卡片内容
*/
@ -15,27 +26,38 @@ class AllColleges extends Round @@ -15,27 +26,38 @@ class AllColleges extends Round
{
parent::init();
$this->title('全校录取人数');
$this->chartLabels(['男生', '女生']);
$this->title($this->allData['title']);
// 图表数据
$this->withChart([0, 0]);
// 新生数据
$studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
$all = UsersMember::query()
->where(['enroll_status' => '1'])
->whereIn("idcard", $studentsIds)
->when($this->allData['collagesId'],function ($query) {
$specialityIds = Speciality::query()->where("secondary_college_id", $this->allData['collagesId'])->pluck('id')->toArray();
$query->whereIn('speciality_id', $specialityIds);
})
->select('sex', DB::raw('count(*) as total'))
->groupBy('sex')
->pluck('total', 'sex')
->toArray();
// 总数
$this->chartTotal('全部', 344);
// 总人数
$total = array_sum($all);
// 男生
$man = $all[1] ?? 0;
// 女生
$girl = $all[2] ?? 0;
// $this->dropdown($data);
}
/**
* 处理请求
* @param Request $request
* @return void
*/
public function handle(Request $request)
{
$manPercent = $total != 0 ? number_format(($man / $total) * 100) : 0;
$girlPercent = $total != 0 ? number_format(($girl / $total) * 100) : 0;
// 卡片内容
$this->withContent(0, 0, 0);
$this->withContent($total, $man, $girl)->height('220px');
$this->chartLabels(['男生', '女生']);
// 图表数据
$this->withChart([$manPercent, $girlPercent]);
// 总数
$this->chartTotal('全部', $total);
}
/**

143
app/Admin/Metrics/Examples/Follow/AllCollegesCharts.php

@ -0,0 +1,143 @@ @@ -0,0 +1,143 @@
<?php
namespace App\Admin\Metrics\Examples\Follow;
use App\Models\AdmissionNewStudents;
use App\Models\CompletedOfflineStep;
use App\Models\Config;
use App\Models\OfflineStep;
use App\Models\SecondaryCollege;
use App\Models\Speciality;
use App\Models\UsersMember;
use Dcat\Admin\Support\JavaScript;
use Dcat\Admin\Widgets\ApexCharts\Chart;
use Illuminate\Support\Facades\DB;
class AllCollegesCharts extends Chart
{
//各二级学院女生报道率
public function __construct($containerSelector = null, $options = [])
{
parent::__construct($containerSelector, $options);
$this->setUpOptions();
}
//初始化方法,主要是调用$this->options()方法,执行整个option的初始化操作。
protected function setUpOptions()
{
$this->options([
"chart"=>[
"height"=>300, //高度
"type"=>"bar", //chart 类型
],
]);
$data = [[
"name" => "总人数",
"data" => [],
"tooltip" => [
[
"name" => "男生",
"data" => [],
"color" => '#ff6b6b'
],
[
"name" => "女生",
"data" => [],
"color"=>"#a21919"
]
],
]];
$label = [];
// 执行你的数据查询逻辑
//取出当前年份
$config = Config::query()->where([
"unique_identification" => "annual_session"
])->first();
//二级学院
$list = SecondaryCollege::query()->where([
"status" => SecondaryCollege::STATUS_YES
])->get(["id", "name"])->toArray();
//不为空时
if(!empty($list)){
// 新生数据
$studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
foreach($list as $key => $item){
$all = UsersMember::query()
->whereIn("idcard", $studentsIds)
->where("enroll_status", 1)
->where(function ($query)use($item) {
$specialityIds = Speciality::query()->where("secondary_college_id", $item['id'])->pluck('id')->toArray();
$query->whereIn('speciality_id', $specialityIds);
})
->select('sex', DB::raw('count(*) as total'))
->groupBy('sex')
->pluck('total', 'sex')
->toArray();
$list[$key]["registering"] = array_sum($all);
$list[$key]["studentsNum"] = $all[1] ?? 0;
$list[$key]["completedOfflineStep"] = $all[2] ?? 0;
}
foreach($list as $item){
array_push($label, $item["name"]);
if(!empty($item["registering"])){
array_push($data[0]["data"], $item["registering"]);
array_push($data[0]['tooltip'][0]['data'], $item["studentsNum"]);
array_push($data[0]['tooltip'][1]['data'], $item["completedOfflineStep"]);
}else{
array_push($data[0]["data"], 0);
array_push($data[0]['tooltip'][0]['data'], 0);
array_push($data[0]['tooltip'][1]['data'], 0);
}
}
}
$this->option("series",$data);
$this->option("labels",$label);
$this->option("yaxis",["max" => 2000]); //Y轴最大值
$tooltipCustomFunction = <<<JS
function({ series, seriesIndex, dataPointIndex, w }) {
let newStr = "";
w.config.series[0].tooltip.forEach(item=>{
newStr += `<div style="display: flex;padding: 0 10px;align-items: center;margin-top: 8px;">
<div style="width:12px;height:12px;border-radius:50%;background-color: \${item.color};margin-right: 10px;">
</div>
<div style="font-size: 12px;">
\${item.name}: \${item.data[dataPointIndex]}
</div>
</div>`
})
return `
<div style=' border: 1px solid #e3e3e3; background: rgba(255, 255, 255, 0.96); border-radius: 5px; box-shadow: 2px 2px 6px -4px #999; font-size: 14px;'>
<div style='padding:6px;background: #ECEFF1;border-bottom: 1px solid #ddd;font-size:12px;'>\${w.config.labels[dataPointIndex]}</div>
<div style="display: flex;padding: 0 10px;align-items: center; margin-top: 8px;">
<div style="width:12px;height:12px;border-radius:50%;background-color: rgb(0, 143, 251);margin-right: 10px;">
</div>
<div style="font-size: 12px;">
\${w.config.series[0].name}: \${w.config.series[0].data[dataPointIndex]}
</div>
</div>
\${newStr}
</div>
`;
}
JS;
$this->option('tooltip.custom', JavaScript::make($tooltipCustomFunction));
}
}

149
app/Admin/Metrics/Examples/Follow/AllCollegesFollowCharts.php

@ -0,0 +1,149 @@ @@ -0,0 +1,149 @@
<?php
namespace App\Admin\Metrics\Examples\Follow;
use App\Models\AdmissionNewStudents;
use App\Models\Config;
use App\Models\SecondaryCollege;
use App\Models\Speciality;
use App\Models\UserFollowStatus;
use App\Models\UsersMember;
use Dcat\Admin\Support\JavaScript;
use Dcat\Admin\Widgets\ApexCharts\Chart;
use Illuminate\Support\Facades\DB;
class AllCollegesFollowCharts extends Chart
{
//各二级学院女生报道率
public function __construct($containerSelector = null, $options = [])
{
parent::__construct($containerSelector, $options);
$this->setUpOptions();
}
//初始化方法,主要是调用$this->options()方法,执行整个option的初始化操作。
protected function setUpOptions()
{
$this->options([
"chart"=>[
"height"=>300, //高度
"type"=>"bar", //chart 类型
],
]);
$followStatus = UserFollowStatus::query()
->addSelect(DB::raw('\'虚拟字段\' as data'))
->addSelect(DB::raw('\'颜色\' as color'))
->select(['id', 'name'])
->get()
->toArray();
$data = [[
"name" => "总人数",
"data" => [],
"tooltip" => [
[
"name" => "男生",
"data" => [],
"color" => ''
],
[
"name" => "女生",
"data" => [],
"color"=>""
]
],
]];
$label = [];
// 执行你的数据查询逻辑
//取出当前年份
$config = Config::query()->where([
"unique_identification" => "annual_session"
])->first();
//二级学院
$list = SecondaryCollege::query()->where([
"status" => SecondaryCollege::STATUS_YES
])->get(["id", "name"])->toArray();
//不为空时
if(!empty($list)){
// 新生数据
$studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
foreach($list as $key => $item){
$all = UsersMember::query()
->whereIn("idcard", $studentsIds)
->where("enroll_status", 1)
->where(function ($query)use($item) {
$specialityIds = Speciality::query()->where("secondary_college_id", $item['id'])->pluck('id')->toArray();
$query->whereIn('speciality_id', $specialityIds);
})
->select('sex', DB::raw('count(*) as total'))
->groupBy('sex')
->pluck('total', 'sex')
->toArray();
$list[$key]["registering"] = array_sum($all);
$list[$key]["studentsNum"] = $all[1] ?? 0;
$list[$key]["completedOfflineStep"] = $all[2] ?? 0;
}
foreach($list as $item){
array_push($label, $item["name"]);
if(!empty($item["registering"])){
array_push($data[0]["data"], $item["registering"]);
array_push($data[0]['tooltip'][0]['data'], $item["studentsNum"]);
array_push($data[0]['tooltip'][1]['data'], $item["completedOfflineStep"]);
}else{
array_push($data[0]["data"], 0);
array_push($data[0]['tooltip'][0]['data'], 0);
array_push($data[0]['tooltip'][1]['data'], 0);
}
}
}
$this->option("series",$data);
$this->option("labels",$label);
$this->option("yaxis",["max" => 2000]); //Y轴最大值
$tooltipCustomFunction = <<<JS
function({ series, seriesIndex, dataPointIndex, w }) {
let newStr = "";
w.config.series[0].tooltip.forEach(item=>{
newStr += `<div style="display: flex;padding: 0 10px;align-items: center;margin-top: 8px;">
<div style="width:12px;height:12px;border-radius:50%;background-color: \${item.color};margin-right: 10px;">
</div>
<div style="font-size: 12px;">
\${item.name}: \${item.data[dataPointIndex]}
</div>
</div>`
})
return `
<div style=' border: 1px solid #e3e3e3; background: rgba(255, 255, 255, 0.96); border-radius: 5px; box-shadow: 2px 2px 6px -4px #999; font-size: 14px;'>
<div style='padding:6px;background: #ECEFF1;border-bottom: 1px solid #ddd;font-size:12px;'>\${w.config.labels[dataPointIndex]}</div>
<div style="display: flex;padding: 0 10px;align-items: center; margin-top: 8px;">
<div style="width:12px;height:12px;border-radius:50%;background-color: rgb(0, 143, 251);margin-right: 10px;">
</div>
<div style="font-size: 12px;">
\${w.config.series[0].name}: \${w.config.series[0].data[dataPointIndex]}
</div>
</div>
\${newStr}
</div>
`;
}
JS;
$this->option('tooltip.custom', JavaScript::make($tooltipCustomFunction));
}
}

123
app/Admin/Repositories/UserFollowOverview.php

@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
<?php
namespace App\Admin\Repositories;
use App\Models\AdminFollowShow;
use App\Models\AdmissionNewStudents;
use App\Models\SecondaryCollege;
use App\Models\Speciality;
use App\Models\Speciality as Model;
use App\Models\UserFollowRecord;
use App\Models\UserFollowStatus;
use App\Models\UsersMember;
use Dcat\Admin\Admin;
use Dcat\Admin\Grid;
use Dcat\Admin\Repositories\EloquentRepository;
use Illuminate\Support\Facades\DB;
class UserFollowOverview extends EloquentRepository
{
/**
* Model.
* @var string
*/
protected $eloquentClass = Model::class;
public function get(Grid\Model $model)
{
$secondary_college_id = $model->filter()->input('secondary_college_id');
$speciality_id = $model->filter()->input('speciality_id');
// 获取每页显示行数
$perPage = $model->getPerPage();
$table1 = UsersMember::query()->getModel()->getTable();
$table2 = UserFollowRecord::query()->getModel()->getTable();
$showInfo = AdminFollowShow::query()->where(['user_id' => Admin::user()['id']])->first();
// 新生数据
$studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
// 回访状态
$followStatus = UserFollowStatus::query()->get()->toArray();
$collegesName = SecondaryCollege::query()->pluck('name', 'id')->toArray();
$all = Model::query()
->where(function ($query) use ($showInfo) {
if ($showInfo) {
if ($showInfo['type'] == '1') {
$query->whereIn('secondary_college_id', $showInfo['secondary_college_id'] ?? []);
} else {
$query->whereIn('id', $showInfo['speciality_id'] ?? []);
}
} else {
$query->where('id', 0);
}
})
->when($secondary_college_id, function ($query) use ($secondary_college_id) {
$query->where('secondary_college_id', $secondary_college_id);
})
->when($speciality_id, function ($query) use ($speciality_id) {
$query->where('id', $speciality_id);
})
->orderByDesc('id')
->paginate($perPage)
->toArray();
foreach ($all['data'] as $key => $value) {
$all['data'][$key]["secondary_college_id"] = $collegesName[$value['secondary_college_id']] ?? null;
// 各专业录取人数
$enroll_all = UsersMember::query()
->where(['enroll_status' => '1'])
->whereIn("idcard", $studentsIds)
->where('speciality_id', $value['id'])
->select('sex', DB::raw('count(*) as total'))
->groupBy('sex')
->pluck('total', 'sex')
->toArray();
$all['data'][$key]["enroll_number"] = array_sum($enroll_all);
$all['data'][$key]["enroll_man_student"] = $enroll_all[1] ?? 0;
$all['data'][$key]["enroll_girl_student"] = $enroll_all[2] ?? 0;
$all['data'][$key]["out_number"] = array_sum($enroll_all);
$all['data'][$key]["out_man_student"] = $enroll_all[1] ?? 0;
$all['data'][$key]["out_girl_student"] = $enroll_all[2] ?? 0;
$total = DB::table("{$table2} as aa")
->leftJoin("{$table1} as bb", function ($join) {
$join->on("aa.unique_number", "=", "bb.unique_number");
})
->where(['aa.is_abandon' => '1', 'bb.speciality_id' => $value['id']])
->whereIn('bb.idcard', $studentsIds)
->select('aa.follow_id', 'bb.sex', DB::raw('COUNT(*) as total'))
->groupBy('aa.follow_id', 'bb.sex')
->groupBy("bb.sex")
->get()
->toArray();
$totalData = [];
foreach ($total as $key2 => $value2) {
$totalData["{$value2->follow_id}{$value2->sex}"] = $value2->total;
}
foreach ($followStatus as $key3 => $value3) {
$followId = $value3['id'];
$man = 1;
$girl = 2;
$all['data'][$key]["total_number{$followId}"] = ($totalData["{$followId}{$man}"] ?? 0) + ($totalData["{$followId}{$girl}"] ?? 0);
$all['data'][$key]["man_student{$followId}"] = $totalData["{$followId}{$man}"] ?? 0;
$all['data'][$key]["girl_student{$followId}"] = $totalData["{$followId}{$girl}"] ?? 0;
$all['data'][$key]["out_number"] -= $all['data'][$key]["total_number{$followId}"];
$all['data'][$key]["out_man_student"] -= $all['data'][$key]["man_student{$followId}"];
$all['data'][$key]["out_girl_student"] -= $all['data'][$key]["girl_student{$followId}"];
}
}
return $model->makePaginator(
$all['total'] ?? 0, // 传入总记录数
$all['data'] ?? [] // 传入数据二维数组
);
}
}
Loading…
Cancel
Save