From f17fa1612cfd43f350f3962bdc123af97341fb11 Mon Sep 17 00:00:00 2001
From: Hjj <126586545@qq.com>
Date: Wed, 25 Jun 2025 21:31:34 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=94=9F=E9=A2=84=E6=8A=A5=E5=88=B0?=
=?UTF-8?q?=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Form/Follow/EditEnrollStatusForm.php | 31 +++
.../Form/Follow/FollowAdminShowForm.php | 83 ++++++++
.../Actions/Form/Follow/FollowRecordForm.php | 43 ++++
.../Controllers/AdminFollowShowController.php | 66 ++++++
.../UserFollowOverviewController.php | 141 +++++++++++++
.../UserFollowRecordController.php | 197 ++++++++++++++++++
.../UserFollowStatusController.php | 62 ++++++
.../Metrics/Examples/Follow/AllColleges.php | 98 +++++++++
.../Examples/Follow/AllEnrollCollege.php | 135 ++++++++++++
.../Examples/Follow/AllEnrollSpeciality.php | 149 +++++++++++++
.../Examples/Follow/AllNewFollowCollege.php | 147 +++++++++++++
.../Follow/AllNewFollowSpeciality.php | 131 ++++++++++++
.../Metrics/Examples/Follow/Allspeciality.php | 99 +++++++++
app/Admin/routes.php | 12 +-
app/Models/AdminFollowShow.php | 18 ++
app/Models/UserFollowRecord.php | 14 ++
app/Models/UserFollowStatus.php | 14 ++
17 files changed, 1438 insertions(+), 2 deletions(-)
create mode 100644 app/Admin/Actions/Form/Follow/EditEnrollStatusForm.php
create mode 100644 app/Admin/Actions/Form/Follow/FollowAdminShowForm.php
create mode 100644 app/Admin/Actions/Form/Follow/FollowRecordForm.php
create mode 100644 app/Admin/Controllers/AdminFollowShowController.php
create mode 100644 app/Admin/Controllers/UserFollowOverviewController.php
create mode 100644 app/Admin/Controllers/UserFollowRecordController.php
create mode 100644 app/Admin/Controllers/UserFollowStatusController.php
create mode 100644 app/Admin/Metrics/Examples/Follow/AllColleges.php
create mode 100644 app/Admin/Metrics/Examples/Follow/AllEnrollCollege.php
create mode 100644 app/Admin/Metrics/Examples/Follow/AllEnrollSpeciality.php
create mode 100644 app/Admin/Metrics/Examples/Follow/AllNewFollowCollege.php
create mode 100644 app/Admin/Metrics/Examples/Follow/AllNewFollowSpeciality.php
create mode 100644 app/Admin/Metrics/Examples/Follow/Allspeciality.php
create mode 100644 app/Models/AdminFollowShow.php
create mode 100644 app/Models/UserFollowRecord.php
create mode 100644 app/Models/UserFollowStatus.php
diff --git a/app/Admin/Actions/Form/Follow/EditEnrollStatusForm.php b/app/Admin/Actions/Form/Follow/EditEnrollStatusForm.php
new file mode 100644
index 0000000..e3dc7b0
--- /dev/null
+++ b/app/Admin/Actions/Form/Follow/EditEnrollStatusForm.php
@@ -0,0 +1,31 @@
+payload['unique_number'];
+ $editSql = UsersMember::query()->where(['unique_number' => $unique_number])->update($input);
+ if (!$editSql) {
+ return $this->response()->error('修改录取状态失败');
+ }
+
+ return $this->response()->success('修改录取状态成功')->refresh();
+ }
+
+
+ public function form(): void
+ {
+ $this->select("enroll_status", "录取状态")->options(['1' => '已录取', '2' => '取消录取'])->default($unique_number = $this->payload['enroll_status'])->required();
+ }
+}
diff --git a/app/Admin/Actions/Form/Follow/FollowAdminShowForm.php b/app/Admin/Actions/Form/Follow/FollowAdminShowForm.php
new file mode 100644
index 0000000..296c9db
--- /dev/null
+++ b/app/Admin/Actions/Form/Follow/FollowAdminShowForm.php
@@ -0,0 +1,83 @@
+payload['user_id'];
+ $data = array_filter($input);
+ $data['updated_at'] = date('Y-m-d H:i:s', time());
+
+ if (AdminFollowShow::query()->where('user_id', $user_id)->exists()) {
+ if ($data['type'] == '1') {
+ $data['speciality_id'] = [];
+ } else {
+ $data['secondary_college_id'] = [];
+ }
+ $sql = AdminFollowShow::query()->where('user_id', $user_id)->update($data);
+ } else {
+ $data['user_id'] = $user_id;
+ $data['created_at'] = date('Y-m-d H:i:s', time());
+ $sql = AdminFollowShow::query()->insert($data);
+ }
+
+ if (!$sql) {
+ return $this->response()->error('绑定数据失败');
+ }
+
+ return $this->response()->success('绑定数据成功')->refresh();
+ }
+
+
+ public function form(): void
+ {
+ $user_id = $this->payload['user_id'];
+
+ $info = AdminFollowShow::query()->where('user_id', $user_id)->first();
+
+ $this->select("type", "类型")
+ ->options([1 => '二级学院', 2 => '专业'])
+ ->default($info['type'] ?? '')
+ ->when('=', 1, function (Form $form) use ($info) {
+ $this->multipleSelect("secondary_college_id", "二级学院")
+ ->options(function () {
+ return SecondaryCollege::query()->pluck("name", "id");
+ })
+ ->default($info['secondary_college_id'] ?? '')
+ ->saving(function ($value) {
+ return json_encode($value);
+ });
+ })
+ ->when('=', 2, function (Form $form) use ($info) {
+ $this->multipleSelect("speciality_id", "专业")
+ ->options(function () {
+ $list = Speciality::query()->where("status", Speciality::STATUS_YES)->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;
+ })
+ ->default($info['speciality_id'] ?? '')
+ ->saving(function ($value) {
+ return json_encode($value);
+ });
+ })
+ ->required();
+ }
+}
diff --git a/app/Admin/Actions/Form/Follow/FollowRecordForm.php b/app/Admin/Actions/Form/Follow/FollowRecordForm.php
new file mode 100644
index 0000000..b86ee10
--- /dev/null
+++ b/app/Admin/Actions/Form/Follow/FollowRecordForm.php
@@ -0,0 +1,43 @@
+payload['unique_number'];
+
+ UserFollowRecord::query()->where(['unique_number' => $unique_number, 'is_abandon' => '1'])->update(['is_abandon' => '2', 'updated_at' => date('Y-m-d H:i:s', time())]);
+ $addSql = UserFollowRecord::query()->insert([
+ 'unique_number' => $unique_number,
+ 'follow_id' => $input['status'],
+ 'theme' => $input['theme'],
+ 'follow_time' => $input['follow_time'],
+ 'user_id' => \Admin::user()['id'],
+ 'created_at' => date('Y-m-d H:i:s', time()),
+ 'updated_at' => date('Y-m-d H:i:s', time())
+ ]);
+ if (!$addSql) {
+ return $this->response()->error('新增回访记录失败');
+ }
+
+ return $this->response()->success('新增回访记录成功')->refresh();
+ }
+
+
+ public function form(): void
+ {
+ $this->select("status", "回访状态")->options(UserFollowStatus::query()->orderByDesc('id')->pluck('name', 'id'))->required();
+ $this->textarea("theme", "回访内容")->required();
+ $this->datetime("follow_time", '回访时间')->required();
+ }
+}
diff --git a/app/Admin/Controllers/AdminFollowShowController.php b/app/Admin/Controllers/AdminFollowShowController.php
new file mode 100644
index 0000000..0ecabbe
--- /dev/null
+++ b/app/Admin/Controllers/AdminFollowShowController.php
@@ -0,0 +1,66 @@
+column('id')->sortable();
+ $grid->column('username');
+ $grid->column('name');
+ $grid->column('roles')->pluck('name')->label('primary', 3);
+ $grid->column('展示的数据')->display(function () {
+ $info = AdminFollowShow::query()->where(['user_id' => $this['id']])->first();
+ if (!$info) {
+ return "";
+ } else if ($info['type'] == '1') {
+ return SecondaryCollege::query()->whereIn('id', $info['secondary_college_id'])->pluck("name", "id")->toArray();
+ } else if ($info['type'] == '2') {
+ $list = Speciality::query()->whereIn('id', $info['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;
+ }
+ })->label('primary');
+
+ $grid->filter(function (Grid\Filter $filter) {
+ $filter->panel();
+ $filter->expand();
+ $filter->equal('username')->width(2);
+ $filter->equal('name')->width(2);
+ });
+ $grid->disableCreateButton();
+ $grid->disableViewButton();
+ $grid->disableEditButton();
+ $grid->disableDeleteButton();
+
+ $grid->actions(function (Grid\Displayers\Actions $actions) {
+ $actions->append(Modal::make()
+ ->xl()
+ ->title('绑定数据')
+ ->button(' 绑定数据 ')
+ ->body(FollowAdminShowForm::make()->payload(['user_id' => $actions->row['id']])));
+ });
+ });
+ }
+}
diff --git a/app/Admin/Controllers/UserFollowOverviewController.php b/app/Admin/Controllers/UserFollowOverviewController.php
new file mode 100644
index 0000000..bf9f095
--- /dev/null
+++ b/app/Admin/Controllers/UserFollowOverviewController.php
@@ -0,0 +1,141 @@
+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) {
+ $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) use ($getData) {
+ $row->column(4, new AllEnrollSpeciality($getData));
+ $row->column(4, new AllNewFollowSpeciality($getData));
+ });
+
+ Admin::script(<<disableToolbar();
+ // 禁用
+ $grid->disablePagination();
+ // 禁用操作
+ $grid->disableActions();
+ // 禁用批量操作
+ $grid->disableBatchActions();
+ // 禁用行选择
+ $grid->disableRowSelector();
+ // 禁用创建
+ $grid->disableCreateButton();
+
+ $grid->filter(function (Grid\Filter $filter) {
+ $filter->panel();
+ $filter->expand();
+
+ $filter->equal('secondary_college_id', '学院')
+ ->select($this->secondaryCollegeList)
+ ->load('speciality_id', '/api/getSpecialityList')
+ ->ignore()
+ ->width(2);
+ $filter->equal('speciality_id', '专业')
+ ->select($this->specialityList)
+ ->ignore()
+ ->width(3);
+ $filter->equal('follow_id', '回访状态')
+ ->select($this->followStatusList)
+ ->ignore()
+ ->width(2);
+ });
+ });
+ }
+
+
+ /**
+ * @desc 二级联动:学院下面的专业数据
+ * @author 何鸠鸠
+ */
+ public function getSpecialityList(Request $request): array
+ {
+ $provinceId = $request->get('q');
+
+ $list = Speciality::query()->where("secondary_college_id", $provinceId)->get()->toArray();
+ $select = [];
+ foreach ($list as $item) {
+ $college = SecondaryCollege::query()->where("id", $item["secondary_college_id"])->first();
+ $select[] = ['id' => $item["id"], 'text' => $item["speciality_name"] . "({$college->name})"];
+ }
+ return $select;
+ }
+}
diff --git a/app/Admin/Controllers/UserFollowRecordController.php b/app/Admin/Controllers/UserFollowRecordController.php
new file mode 100644
index 0000000..06457a0
--- /dev/null
+++ b/app/Admin/Controllers/UserFollowRecordController.php
@@ -0,0 +1,197 @@
+model()->with(['followRecordHasOne']);
+
+ $showInfo = AdminFollowShow::query()->where(['user_id' => Admin::user()['id']])->first();
+ $followList = UserFollowStatus::query()->pluck('name', 'id')->toArray();
+ $followList[0] = '未联系';
+
+ // 设置学生类型默认值
+ $req = request()->merge(['identity' => !empty(request()->get('identity', 1)) ? request()->get('identity', 1) : 1]);
+ // 显示该显示的数据
+ $speciality_id = [];
+ if ($showInfo) {
+ if ($showInfo['type'] == '1') {
+ $speciality_id = Speciality::query()->whereIn("secondary_college_id", $showInfo['secondary_college_id'])->pluck('id')->toArray();;
+ } else {
+ $speciality_id = $showInfo['speciality_id'];
+ }
+ }
+ $grid->model()->whereIn('speciality_id', $speciality_id);
+
+ $grid->column('id')->sortable();
+ $grid->column('identity', '学生类型')->display(function () {
+ $iden = PublicServices::getInstance()->checkIsNewOldStudent($this->idcard);
+ return $iden == 1 ? "新生" : "老生";
+ });
+ $grid->column('mobile', '手机');
+ $grid->column('unique_number', '用户唯一识别码');
+ $grid->column('name', '姓名');
+ $grid->column('idcard', '身份证');
+ $grid->column('sex', '性别')->display(function () {
+ return $this->sex == 0 ? "未知" : ($this->sex == 1 ? "男" : "女");
+ });
+ $grid->column('secondary_college_id', '二级学院')->display(function () {
+ $info = Speciality::query()->where("id", $this->speciality_id)->first();
+ if (!empty($info)) {
+ $secondaryInfo = SecondaryCollege::query()->where("id", $info->secondary_college_id)->first();
+ if (!empty($secondaryInfo)) {
+ return $secondaryInfo->name;
+ }
+ }
+ })->help("未显示学院时请检查是否已经分配专业");
+ $grid->column('speciality_id', '专业')->display(function () {
+ $info = Speciality::where("id", $this->speciality_id)->first();
+ if (!empty($info)) {
+ return $info->speciality_name;
+ }
+ })->help("未显示专业时请检查是否已经分配专业");
+ $grid->column('status', '状态')->using([1 => "正常", 2 => "禁用"]);
+ $grid->column('enroll_status', "录取状态")->using(['1' => '已录取', '2' => '取消录取']);
+ $grid->column('followRecordHasOne.follow_id', "回访状态")->display(function ($val) {
+ return (int)$val;
+ })->using($followList)->expand(function () use ($followList) {
+ $titles = ['ID', '回访状态', '回访状态', '回访时间', '用户ID'];
+ $data = UserFollowRecord::query()
+ ->where(['unique_number' => $this['unique_number']])
+ ->orderByDesc('id')
+ ->get(['id', 'follow_id', 'theme', 'follow_time', 'user_id'])
+ ->map(function ($val) use ($followList) {
+ $val->follow_id = $followList[$val->follow_id] ?? '';
+ return $val;
+ })
+ ->toArray();
+ return Table::make($titles, $data);
+ });
+ $grid->column('is_test', " 测试账号 ")->display(function () {
+ if ($this->is_test == UsersMember::IS_TEST_YES) {
+ return "是";
+ }
+ return "";
+ })->help("为测试账号时则不受系统开放时间限制");
+ $grid->column('create_time', '注册时间')->display(function () {
+ if (!empty($this->create_time)) {
+ return date("Y-m-d H:i:s", $this->create_time);
+ }
+ })->sortable();
+
+ $grid->filter(function (Grid\Filter $filter) use ($followList, $showInfo) {
+ $filter->panel();
+ $filter->expand();
+ $filter->equal('id', 'ID')->width(2);
+ $filter->equal('mobile', '手机')->width(2);
+ $filter->equal('name', '姓名')->width(2);
+ $filter->equal('idcard', '身份证')->width(2);
+ $filter->equal('enroll_status', '录取状态')->select(['1' => '已录取', '2' => '取消录取'])->width(2);
+ $filter->where('follow_status', function ($query) {
+ $table1 = UsersMember::query()->getModel()->getTable();
+ $table2 = UserFollowRecord::query()->getModel()->getTable();
+ $all = DB::table("{$table1} as aa")
+ ->leftJoin("{$table2} as bb", function ($join) {
+ $join->on("aa.unique_number", "=", "bb.unique_number")->where(["bb.is_abandon" => "1"]);
+ })
+ ->where(function ($query) {
+ if ($this->input == 0) {
+ $query->whereNull("bb.id");
+ } else {
+ $query->where(["bb.follow_id" => $this->input]);
+ }
+ })
+ ->pluck('aa.unique_number')
+ ->toArray();
+ $query->whereIn('unique_number', $all);
+ }, '回访状态')->select($followList)->width(2);
+ $filter->where("identity", function ($query) {
+ $studentsIds = AdmissionNewStudents::query()->where([
+ "is_new_student" => $this->input
+ ])->get()->toArray();
+ if (!empty($studentsIds)) {
+ $studentsIds = array_column($studentsIds, "idCard");
+ }
+
+ $query->whereIn('idcard', $studentsIds);
+ }, '学生类型')->select([
+ "1" => "新生",
+ "2" => "老生"
+ ])->default("1")->width(2);
+ $filter->where("secondary_college_id", function ($query) {
+
+ $specialityIds = Speciality::query()->where("secondary_college_id", $this->input)->get()->toArray();
+ if (!empty($specialityIds)) {
+ $specialityIds = array_column($specialityIds, "id");
+ }
+
+ $query->whereIn('speciality_id', $specialityIds);
+
+ }, '二级学院')->select(function () use ($showInfo) {
+ return SecondaryCollege::query()->whereIn('id', $showInfo['secondary_college_id'] ?? [])->pluck("name", "id")->toArray();
+ })->load('speciality_id', '/api/getSpecialityList')->width(3);
+ $filter->equal('speciality_id', '专业')->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);
+ $filter->between('create_time', '注册时间')->datetime()->toTimestamp()->width(3);
+ });
+
+ $grid->withBorder();
+ $grid->disableCreateButton();
+ $grid->disableEditButton();
+ $grid->disableViewButton();
+ $grid->disableDeleteButton();
+ $grid->actions(function (Grid\Displayers\Actions $actions) {
+ if (Admin::user()->isRole('fuDaoYuan') || Admin::user()->isRole('administrator') || Admin::user()->isRole('System')) {
+ $actions->append(Modal::make()
+ ->xl()
+ ->title('新增回访记录')
+ ->button(' 新增回访记录 ')
+ ->body(FollowRecordForm::make()->payload(['unique_number' => $actions->row['unique_number']])));
+ }
+ if (Admin::user()->isRole('AdmissionOffice') || Admin::user()->isRole('administrator') || Admin::user()->isRole('System')) {
+ $actions->append(Modal::make()
+ ->xl()
+ ->title('修改录取状态')
+ ->button(' 修改录取状态 ')
+ ->body(EditEnrollStatusForm::make()->payload(['unique_number' => $actions->row['unique_number'], 'enroll_status' => $this['enroll_status']])));
+ }
+ });
+ });
+ }
+}
diff --git a/app/Admin/Controllers/UserFollowStatusController.php b/app/Admin/Controllers/UserFollowStatusController.php
new file mode 100644
index 0000000..ff6c862
--- /dev/null
+++ b/app/Admin/Controllers/UserFollowStatusController.php
@@ -0,0 +1,62 @@
+model()->orderByDesc('id');
+
+ $grid->column('id')->sortable();
+ $grid->column('name', '名称');
+ $grid->column('created_at');
+ $grid->column('updated_at')->sortable();
+
+ $grid->disableViewButton();
+ });
+ }
+
+ /**
+ * Make a show builder.
+ *
+ * @param mixed $id
+ *
+ * @return Show
+ */
+ protected function detail($id)
+ {
+ return Show::make($id, new UserFollowStatus(), function (Show $show) {
+ $show->field('id');
+ $show->field('name');
+ $show->field('created_at');
+ $show->field('updated_at');
+ });
+ }
+
+ /**
+ * Make a form builder.
+ *
+ * @return Form
+ */
+ protected function form()
+ {
+ return Form::make(new UserFollowStatus(), function (Form $form) {
+ $form->display('id');
+ $form->text('name');
+
+ $form->display('created_at');
+ $form->display('updated_at');
+ });
+ }
+}
diff --git a/app/Admin/Metrics/Examples/Follow/AllColleges.php b/app/Admin/Metrics/Examples/Follow/AllColleges.php
new file mode 100644
index 0000000..af4d10e
--- /dev/null
+++ b/app/Admin/Metrics/Examples/Follow/AllColleges.php
@@ -0,0 +1,98 @@
+title('全校录取人数');
+ $this->chartLabels(['男生', '女生']);
+
+ // 图表数据
+ $this->withChart([0, 0]);
+
+ // 总数
+ $this->chartTotal('全部', 344);
+
+// $this->dropdown($data);
+ }
+
+ /**
+ * 处理请求
+ * @param Request $request
+ * @return void
+ */
+ public function handle(Request $request)
+ {
+ // 卡片内容
+ $this->withContent(0, 0, 0);
+ }
+
+ /**
+ * 设置图表数据.
+ * @param array $data
+ * @return $this
+ */
+ public function withChart(array $data): AllColleges
+ {
+ return $this->chart([
+ 'series' => $data,
+ ]);
+ }
+
+ /**
+ * 卡片内容.
+ * @param int $finished
+ * @param int $pending
+ * @param int $rejected
+ * @return $this
+ */
+ public function withContent(int $finished, int $pending, int $rejected): AllColleges
+ {
+ return $this->content(
+ <<
+
+
+
+ 全部
+
+
+ {$finished}
+
+
+
+
+
+
+ 男生
+
+
+ {$pending}
+
+
+
+
+
+
+ 女生
+
+
+ {$rejected}
+
+
+
+HTML
+ );
+ }
+}
diff --git a/app/Admin/Metrics/Examples/Follow/AllEnrollCollege.php b/app/Admin/Metrics/Examples/Follow/AllEnrollCollege.php
new file mode 100644
index 0000000..ec27f15
--- /dev/null
+++ b/app/Admin/Metrics/Examples/Follow/AllEnrollCollege.php
@@ -0,0 +1,135 @@
+data = $data;
+
+ parent::__construct();
+ }
+
+
+ /**
+ * 初始化卡片内容
+ */
+ protected function init()
+ {
+ parent::init();
+
+ $this->title('各院总录取统计');
+ if (is_string($this->data['secondary_college_id']) && !empty($this->data['secondary_college_id'])) {
+ $this->subTitle(SecondaryCollege::query()->where('id', $this->data['secondary_college_id'])->value('name'));
+ } else {
+ $this->subTitle("当前学院:全校");
+ }
+
+ // 新生数据
+ $studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
+ $all = UsersMember::query()
+ ->whereIn("idcard", $studentsIds)
+ ->where(function ($query) {
+ if (is_array($this->data['secondary_college_id'])) {
+ $ids = $this->data['secondary_college_id'];
+ } else {
+ $ids = explode(',', $this->data['secondary_college_id']);
+ }
+
+ $specialityIds = Speciality::query()->whereIn("secondary_college_id", array_filter($ids))->pluck('id')->toArray();
+ $query->whereIn('speciality_id', $specialityIds);
+ })
+ ->select('sex', DB::raw('count(*) as total'))
+ ->groupBy('sex')
+ ->pluck('total', 'sex')
+ ->toArray();
+
+ // 总人数
+ $total = array_sum($all);
+ // 男生
+ $man = $all[1] ?? 0;
+ // 女生
+ $girl = $all[2] ?? 0;
+
+ $this->chartLabels(['总人数', '男生', '女生']);
+ $this->withContent($total, $man, $girl)->height('220px');
+ }
+
+
+ /**
+ * 设置图表数据.
+ *
+ * @param array $data
+ *
+ * @return $this
+ */
+ public function withChart(array $data)
+ {
+ return $this->chart([
+ 'series' => $data,
+ ]);
+ }
+
+
+ /**
+ * 卡片内容.
+ *
+ * @param int $finished
+ * @param int $pending
+ * @param int $rejected
+ *
+ * @return $this
+ */
+ public function withContent($finished, $pending, $rejected)
+ {
+ return $this->content(
+ <<
+
+
+
+ 总人数
+
+
+ {$finished}
+
+
+
+
+
+
+ 男生
+
+
+ {$pending}
+
+
+
+
+
+
+ 女生
+
+
+ {$rejected}
+
+
+
+HTML
+ );
+ }
+}
+
diff --git a/app/Admin/Metrics/Examples/Follow/AllEnrollSpeciality.php b/app/Admin/Metrics/Examples/Follow/AllEnrollSpeciality.php
new file mode 100644
index 0000000..ddf0951
--- /dev/null
+++ b/app/Admin/Metrics/Examples/Follow/AllEnrollSpeciality.php
@@ -0,0 +1,149 @@
+data = $data;
+
+ parent::__construct();
+ }
+
+
+ /**
+ * 初始化卡片内容
+ */
+ protected function init()
+ {
+ parent::init();
+
+ $this->title('各专业录取统计');
+ if (!empty($this->data['speciality_id'])) {
+ $specialityInfo = Speciality::query()->where('id', $this->data['speciality_id'])->first(['speciality_name', 'secondary_college_id']);
+ $name = "";
+ if ($specialityInfo) {
+ $name .= $specialityInfo['speciality_name'];
+ $collegeName = SecondaryCollege::query()->where('id', $specialityInfo['secondary_college_id'])->value('name');
+ if ($collegeName) {
+ $name .= "({$collegeName})";
+ }
+ }
+ } else {
+ $name = "当前专业:无";
+ }
+ $this->subTitle($name);
+
+ // 新生数据
+ $studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
+ $all = UsersMember::query()
+ ->where(['enroll_status' => '1'])
+ ->whereIn("idcard", $studentsIds)
+ ->where('speciality_id', $this->data['speciality_id'])
+ ->select('sex', DB::raw('count(*) as total'))
+ ->groupBy('sex')
+ ->pluck('total', 'sex')
+ ->toArray();
+
+ // 总人数
+ $total = array_sum($all);
+ // 男生
+ $man = $all[1] ?? 0;
+ // 女生
+ $girl = $all[2] ?? 0;
+
+ $this->chartLabels(['总人数', '男生', '女生']);
+ $this->withContent($total, $man, $girl);
+ }
+
+
+ /**
+ * 设置图表数据.
+ *
+ * @param array $data
+ *
+ * @return $this
+ */
+ public function withChart(array $data)
+ {
+ return $this->chart([
+ 'series' => $data,
+ ]);
+ }
+
+
+ /**
+ * @param int $percent
+ *
+ * @return $this
+ */
+ public function up($percent)
+ {
+ return $this->footer(
+ " {$percent}人 为当前年份已导入新生人数"
+ );
+ }
+
+ /**
+ * 卡片内容.
+ *
+ * @param int $finished
+ * @param int $pending
+ * @param int $rejected
+ *
+ * @return $this
+ */
+ public function withContent($finished, $pending, $rejected)
+ {
+ return $this->content(
+ <<
+
+
+
+ 总人数
+
+
+ {$finished}
+
+
+
+
+
+
+ 男生
+
+
+ {$pending}
+
+
+
+
+
+
+ 女生
+
+
+ {$rejected}
+
+
+
+HTML
+ );
+ }
+}
+
diff --git a/app/Admin/Metrics/Examples/Follow/AllNewFollowCollege.php b/app/Admin/Metrics/Examples/Follow/AllNewFollowCollege.php
new file mode 100644
index 0000000..214dc64
--- /dev/null
+++ b/app/Admin/Metrics/Examples/Follow/AllNewFollowCollege.php
@@ -0,0 +1,147 @@
+data = $data;
+
+ parent::__construct();
+ }
+
+ /**
+ * 初始化卡片内容
+ */
+ protected function init()
+ {
+ parent::init();
+
+ $this->title('各院最新回访结果');
+ if (empty($this->data['follow_id'])) {
+ $this->subTitle('当前回访状态:未联系');
+ } else {
+ $this->subTitle('当前回访状态:' . UserFollowStatus::query()->where(['id' => $this->data['follow_id']])->value('name'));
+ }
+ $this->chartLabels(['女生', '男生']);
+ $table1 = UsersMember::query()->getModel()->getTable();
+ $table2 = UserFollowRecord::query()->getModel()->getTable();
+
+ // 新生数据
+ $studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
+ $all = DB::table("{$table1} as aa")
+ ->leftJoin("{$table2} as bb", function ($join) {
+ $join->on("aa.unique_number", "=", "bb.unique_number")->where(["bb.is_abandon" => "1"]);
+ })
+ ->whereIn("aa.idcard", $studentsIds)
+ ->where(function ($query) {
+ if (is_array($this->data['secondary_college_id'])) {
+ $ids = $this->data['secondary_college_id'];
+ } else {
+ $ids = explode(',', $this->data['secondary_college_id']);
+ }
+
+ $specialityIds = Speciality::query()->whereIn("secondary_college_id", array_filter($ids))->pluck('id')->toArray();
+ $query->whereIn('speciality_id', $specialityIds);
+ })
+ ->where(function ($query) {
+ if (empty($this->data['follow_id'])) {
+ $query->whereNull("bb.id");
+ } else {
+ $query->where(["bb.follow_id" => $this->data['follow_id']]);
+ }
+ })
+ ->select('aa.sex', DB::raw('count(*) as total'))
+ ->groupBy('aa.sex')
+ ->pluck('total', 'sex')
+ ->toArray();
+
+ // 总人数
+ $total = array_sum($all);
+ // 男生
+ $man = $all[1] ?? 0;
+ // 女生
+ $girl = $all[2] ?? 0;
+
+ // 图表数据
+ $this->withChart([$man, $girl]);
+ // 总数
+ $this->chartTotal('总人数', $girl + $man);
+ // 卡片内容
+ $this->withContent($girl + $man, $man, $girl)->height('220px');
+ }
+
+
+ /**
+ * 设置图表数据.
+ * @param array $data
+ * @return $this
+ */
+ public function withChart(array $data)
+ {
+ $this->chartColors(['#586cb1', '#dda451', '#ea5455']);
+ return $this->chart([
+ 'series' => $data,
+ ]);
+ }
+
+
+ /**
+ * 卡片内容.
+ * @param int $finished
+ * @param int $pending
+ * @param int $rejected
+ * @return $this
+ */
+ public function withContent($finished, $pending, $rejected)
+ {
+ return $this->content(
+ <<
+
+
+
+ 总人数
+
+
+ {$finished}
+
+
+
+
+
+
+ 男生
+
+
+ {$pending}
+
+
+
+
+
+
+ 女生
+
+
+ {$rejected}
+
+
+
+HTML
+ );
+ }
+}
diff --git a/app/Admin/Metrics/Examples/Follow/AllNewFollowSpeciality.php b/app/Admin/Metrics/Examples/Follow/AllNewFollowSpeciality.php
new file mode 100644
index 0000000..c97618b
--- /dev/null
+++ b/app/Admin/Metrics/Examples/Follow/AllNewFollowSpeciality.php
@@ -0,0 +1,131 @@
+data = $data;
+
+ parent::__construct();
+ }
+
+ /**
+ * 初始化卡片内容
+ */
+ protected function init()
+ {
+ parent::init();
+
+ $this->title('各专业最新回访结果');
+ if (empty($this->data['follow_id'])) {
+ $this->subTitle('当前回访状态:未联系');
+ } else {
+ $this->subTitle('当前回访状态:' . UserFollowStatus::query()->where(['id' => $this->data['follow_id']])->value('name'));
+ }
+ $this->chartLabels(['女生', '男生']);
+ $table1 = UsersMember::query()->getModel()->getTable();
+ $table2 = UserFollowRecord::query()->getModel()->getTable();
+
+ // 新生数据
+ $studentsIds = AdmissionNewStudents::query()->where(["is_new_student" => "1"])->pluck('idCard')->toArray();
+ $all = DB::table("{$table1} as aa")
+ ->leftJoin("{$table2} as bb", function ($join) {
+ $join->on("aa.unique_number", "=", "bb.unique_number")->where("bb.is_abandon", "=", "1");
+ })
+ ->whereIn("aa.idcard", $studentsIds)
+ ->where(['bb.follow_id' => $this->data['follow_id']])
+ ->where(['aa.speciality_id' => $this->data['speciality_id']])
+ ->select('sex', DB::raw('count(*) as total'))
+ ->groupBy('sex')
+ ->pluck('total', 'sex')
+ ->toArray();
+
+ // 总人数
+ $total = array_sum($all);
+ // 男生
+ $man = $all[1] ?? 0;
+ // 女生
+ $girl = $all[2] ?? 0;
+
+ // 图表数据
+ $this->withChart([$man, $girl]);
+ // 总数
+ $this->chartTotal('总人数', $total);
+ // 卡片内容
+ $this->withContent($total, $man, $girl);
+ }
+
+
+ /**
+ * 设置图表数据.
+ * @param array $data
+ * @return $this
+ */
+ public function withChart(array $data)
+ {
+ $this->chartColors(['#586cb1', '#dda451', '#ea5455']);
+ return $this->chart([
+ 'series' => $data,
+ ]);
+ }
+
+ /**
+ * 卡片内容.
+ * @param int $finished
+ * @param int $pending
+ * @param int $rejected
+ * @return $this
+ */
+ public function withContent($finished, $pending, $rejected)
+ {
+ return $this->content(
+ <<
+
+
+
+ 总人数
+
+
+ {$finished}
+
+
+
+
+
+
+ 男生
+
+
+ {$pending}
+
+
+
+
+
+
+ 女生
+
+
+ {$rejected}
+
+
+
+HTML
+ );
+ }
+}
diff --git a/app/Admin/Metrics/Examples/Follow/Allspeciality.php b/app/Admin/Metrics/Examples/Follow/Allspeciality.php
new file mode 100644
index 0000000..60ab02c
--- /dev/null
+++ b/app/Admin/Metrics/Examples/Follow/Allspeciality.php
@@ -0,0 +1,99 @@
+title('各专业录取人数');
+ $this->chartLabels(['男生', '女生']);
+
+ // 图表数据
+ $this->withChart([0, 0]);
+
+ // 总数
+ $this->chartTotal('全部', 0);
+
+// $this->dropdown($data);
+ }
+
+ /**
+ * 处理请求
+ * @param Request $request
+ * @return void
+ */
+ public function handle(Request $request)
+ {
+ // 卡片内容
+ $this->withContent(0, 0, 0);
+ }
+
+ /**
+ * 设置图表数据.
+ * @param array $data
+ * @return $this
+ */
+ public function withChart(array $data): Allspeciality
+ {
+ return $this->chart([
+ 'series' => $data,
+ ]);
+ }
+
+ /**
+ * 卡片内容.
+ * @param int $finished
+ * @param int $pending
+ * @param int $rejected
+ * @return $this
+ */
+ public function withContent(int $finished, int $pending, int $rejected): Allspeciality
+ {
+ return $this->content(
+ <<
+
+
+
+ 全部
+
+
+ {$finished}
+
+
+
+
+
+
+ 男生
+
+
+ {$pending}
+
+
+
+
+
+
+ 女生
+
+
+ {$rejected}
+
+
+
+HTML
+ );
+ }
+}
diff --git a/app/Admin/routes.php b/app/Admin/routes.php
index d361019..fbd8167 100644
--- a/app/Admin/routes.php
+++ b/app/Admin/routes.php
@@ -7,8 +7,8 @@ use Dcat\Admin\Admin;
Admin::routes();
Route::group([
- 'prefix' => config('admin.route.prefix'),
- 'namespace' => config('admin.route.namespace'),
+ 'prefix' => config('admin.route.prefix'),
+ 'namespace' => config('admin.route.namespace'),
'middleware' => config('admin.route.middleware'),
], function (Router $router) {
@@ -40,4 +40,12 @@ Route::group([
$router->resource("/loan_students_list", "LoanStudentsListController");
$router->resource("/config_list", "ConfigController");
$router->resource("/minimum_limit_tuition", "MinimumLimitTuitionController");
+ $router->resource("/user_follow_overview", "UserFollowOverviewController");
+ $router->resource("/admin_follow_show", "AdminFollowShowController");
+ $router->resource("/user_follow_record", "UserFollowRecordController");
+ $router->resource("/user_follow_status", "UserFollowStatusController");
+
+ $router->group(['prefix' => '/api'], function (Router $router) {
+ $router->get("/getSpecialityList", [\App\Admin\Controllers\UserFollowOverviewController::class, 'getSpecialityList']);
+ });
});
diff --git a/app/Models/AdminFollowShow.php b/app/Models/AdminFollowShow.php
new file mode 100644
index 0000000..b01e6a2
--- /dev/null
+++ b/app/Models/AdminFollowShow.php
@@ -0,0 +1,18 @@
+ 'array',
+ 'speciality_id'=>'array'
+ ];
+}
diff --git a/app/Models/UserFollowRecord.php b/app/Models/UserFollowRecord.php
new file mode 100644
index 0000000..c8b70f9
--- /dev/null
+++ b/app/Models/UserFollowRecord.php
@@ -0,0 +1,14 @@
+