all(); $clear = request('clear', 1); $list = $this->model->with(['course.typeDetail', 'user' => function ($query) use ($all, $clear) { if ($clear) { $query->with(['company', 'courseSigns' => function ($q) { $q->where('status', 1)->with('course'); }]); } }])->whereHas('user', function ($query) use ($all) { if (isset($all['is_vip'])) { $query->where('is_vip', $all['is_vip']); } if (isset($all['company_name'])) { $query->whereHas('company', function ($query) use ($all) { $query->where('company_name', 'like', '%' . $all['company_name'] . '%'); }); } if (isset($all['company_position'])) { $query->where('company_position', $all['company_position']); } if (isset($all['company_area'])) { $company_area = explode(',', $all['company_area']); $query->whereIn('company_area', $company_area); } if (isset($all['company_type'])) { $company_type = explode(',', $all['company_type']); $query->where(function ($q) use ($company_type) { foreach ($company_type as $v) { $q->orWhereRaw('FIND_IN_SET(?, company_type)', [$v]); } }); } if (isset($all['company_industry'])) { $company_industry = explode(',', $all['company_industry']); $query->whereIn('company_industry', $company_industry); } if (isset($all['is_schoolmate'])) { $query->where('is_schoolmate', $all['is_schoolmate']); } if (isset($all['mobile'])) { $query->where('mobile', 'like', '%' . $all['mobile'] . '%'); } if (isset($all['education'])) { $education = explode(',', $all['education']); $query->whereIn('education', $education); } if (isset($all['type'])) { $type = explode(',', $all['type']); $query->where(function ($q) use ($type) { foreach ($type as $v) { $q->orWhereRaw('FIND_IN_SET(?, type)', [$v]); } }); } })->where(function ($query) use ($all) { if (isset($all['filter_date']) && !empty($all['filter_date'])) { foreach ($all['filter_date'] as $item) { $query->whereJsonContains("data->{$item->name}", $item->value); } } })->where(function ($query) use ($all, $clear) { if ($clear) { $query->with('thirdAppointmentLogs'); } if (isset($all['start_date'])) { $query->whereDate('created_at', '>=', $all['start_date']); } if (isset($all['end_date'])) { $query->whereDate('created_at', '<=', $all['end_date']); } if (isset($all['course_type_id'])) { $course_type_id = explode(',', $all['course_type_id']); $courses = Course::where(function ($query) use ($all) { // if (isset($all['start_date'])) { // $query->where('start_date', '>=', $all['start_date']); // } // if (isset($all['end_date'])) { // $query->where('start_date', '<=', $all['end_date']); // } })->whereIn('type', $course_type_id)->get(); $query->whereNotIn('status', [4, 5]) ->where(function ($query) use ($courses) { $query->whereIn('course_id', $courses->pluck('id')); }); } if (isset($all['name'])) { $query->where(function ($q) use ($all) { $q->whereHas('user', function ($q) use ($all) { $q->where('name', 'like', '%' . $all['name'] . '%'); })->orWhere('change_data', 'like', '%' . $all['name'] . '%'); }); } if (isset($all['filter']) && !empty($all['filter'])) { foreach ($all['filter'] as $condition) { $key = $condition['key'] ?? null; $op = $condition['op'] ?? null; $value = $condition['value'] ?? null; if (!isset($key) || !isset($op) || !isset($value)) { continue; } // 等于 if ($op == 'eq') { $query->where($key, $value); } // 不等于 if ($op == 'neq') { $query->where($key, '!=', $value); } // 模糊搜索 if ($op == 'like') { $query->where($key, 'like', '%' . $value . '%'); } // 否定模糊搜索 if ($op == 'notlike') { $query->where($key, 'not like', '%' . $value . '%'); } // 范围搜索 if ($op == 'range') { list($from, $to) = explode(',', $value); if (empty($from) || empty($to)) { continue; } $query->whereBetween($key, [$from, $to]); } } } })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc') ->orderBy('created_at', 'desc'); if (isset($all['is_export']) && !empty($all['is_export'])) { $list = $list->limit(5000)->get()->toArray(); return Excel::download(new CommonExport($list, $all['export_fields'] ?? ''), $all['file_name'] ?? '' . date('YmdHis') . '.xlsx'); } else { // 输出 $list = $list->paginate($all['page_size'] ?? 20); } return $this->success($list); } /** * @OA\Get( * path="/api/admin/course-signs/show", * tags={"报名管理"}, * summary="详情", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组,填写输出指定数据.thirdAppointmentLogs第三方日志记录,thirdPlateLogs第三方车牌预约记录"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function show() { $all = \request()->all(); $messages = [ 'id.required' => 'Id必填', ]; $validator = Validator::make($all, [ 'id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $detail = $this->model->with(underlineToHump($all['show_relation'] ?? []))->find($all['id']); $detail->audits = $detail->audits()->with('user')->get(); return $this->success($detail); } /** * @OA\Post( * path="/api/admin/course-signs/save", * tags={"报名管理"}, * summary="更新或新增", * @OA\Parameter(name="update_user", in="query", @OA\Schema(type="integer"), required=true, description="是否更新用户信息0否1是"), * @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=true, description="课程ID(存在则更新,不存在则新增)"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="验证token"), * @OA\Parameter(name="course_id", in="query", @OA\Schema(type="string"), description="课程id"), * @OA\Parameter(name="title", in="query", @OA\Schema(type="string", format="date"), description="标题"), * @OA\Parameter(name="content", in="query", @OA\Schema(type="string", format="date"), description="内容"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="string", format="date"), description="状态0待审核1通过2拒绝3备选"), * @OA\Parameter(name="reason", in="query", @OA\Schema(type="string", format="date"), description="原因"), * @OA\Parameter(name="score", in="query", @OA\Schema(type="string", format="date"), description="分数"), * @OA\Parameter(name="position", in="query", @OA\Schema(type="string", format="date"), description="职位"), * @OA\Parameter(name="fee_status", in="query", @OA\Schema(type="string", format="date"), description="0未缴费1缴费成功2缴费失败3待确认"), * @OA\Parameter(name="file_ids", in="query", @OA\Schema(type="string", format="date"), description="附件id数组"), * @OA\Response( * response=200, * description="操作成功" * ) * ) */ public function save() { $all = \request()->all(); $update_user = request('update_user', 0); DB::beginTransaction(); try { if (isset($all['id'])) { $model = $this->model->find($all['id']); if (empty($model)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']); } // 检测手机号是否存在 if (isset($all['mobile'])) { $otherUser = User::where('mobile', $all['mobile'])->where('id', '!=', $model->id)->first(); if ($otherUser) return $this->fail([ResponseCode::ERROR_BUSINESS, '该手机号已存在']); } } else { $model = $this->model; $all['admin_id'] = $this->getUserId(); $all['department_id'] = $this->getUser()->department_id; // 检测手机号是否存在 if (isset($all['mobile'])) { $otherUser = User::where('mobile', $all['mobile'])->first(); if ($otherUser) return $this->fail([ResponseCode::ERROR_BUSINESS, '该手机号已存在']); } } $original = $model->getOriginal(); $model->fill($all); $model->save(); // 是否强制更新用户信息 if ($update_user == 1 && $model->change_data) { // 强制更新用户信息 $user = User::find($model->user_id); foreach ($model->status == 1 && $model->change_data as $key => $value) { $user->$key = $value; } $user->save(); } DB::commit(); // 获取课程信息 $course = Course::find($model->course_id); // 缴费结果通知和关联设置 if (($original && !in_array($original['fee_status'], [1, 2]) && in_array($model->fee_status, [1, 2]))) { // 发通知 $data = ['course_sign_id' => $model->id]; Notification::send(User::find($model->user_id), new FeeResultNotify($data)); // 缴费成功则设置成vip if ($model->fee_status == 1) { $user = User::find($model->user_id); $user->is_vip = 1; $user->save(); } } // 多条件讨论 // 其他状态到审核通过 if ($original['status'] != 1 && $model->status == 1) { // 发通过通知 $data = ['course_sign_id' => $model->id]; Notification::send(User::find($model->user_id), new AuditNotify($data)); } // 其他条件到审核不通过 if ($original['status'] != 2 && $model->status == 2) { // 发不通过通知 $data = ['course_sign_id' => $model->id]; Notification::send(User::find($model->user_id), new AuditNotify($data)); } // 审核通过到其他条件,减少次数 if ($original['status'] == 1 && $model->status != 1) { // 减少预约次数 CourseAppointmentTotal::reduce($model->user_id, $model->id); } // 执行预约操作 if (($course->is_fee == 0 && $model->status == 1) || ($course->is_fee == 1 && $model->fee_status == 1)) { // 预约车 $user = User::find($model->user_id); // 发送车辆预约信息 if ($user->plate) { $plateArray = explode(',', $user->plate); foreach ($plateArray as $plate) { // 车辆预约 dispatch((new SendCourseCar($model, $plate))); } } // 预约门禁 dispatch((new SendCourseDoor($model))); } // 记录日志 $this->saveLogs($original, $model); return $this->success($model); } catch (\Exception $exception) { DB::rollBack(); return $this->fail([$exception->getCode(), $exception->getMessage()]); } } /** * @OA\Get( * path="/api/admin/course-signs/destroy", * tags={"报名管理"}, * summary="删除", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function destroy() { return parent::destroy(); } /** * @OA\Post( * path="/api/admin/course-signs/excel-show", * tags={"报名管理"}, * summary="导入预览", * description="", * @OA\Parameter(name="course_id", in="query", @OA\Schema(type="string"), required=true, description="课程id"), * @OA\Parameter(name="file", in="query", @OA\Schema(type="string"), required=true, description="文件"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function excelShow() { $file = \request()->file('file'); $course_id = request('course_id'); //判断文件是否有效 if (!(\request()->hasFile('file') && $file->isValid())) { return $this->fail([ResponseCode::ERROR_BUSINESS, '文件不存在或无效']); } //获取文件大小 $img_size = floor($file->getSize() / 1024); if ($img_size >= 50 * 1024) { return $this->fail([ResponseCode::ERROR_BUSINESS, '文件必须小于50M']); } //过滤文件后缀 $ext = $file->getClientOriginalExtension(); if (!in_array($ext, ['xls', 'xlsx', 'csv'])) { return $this->fail([ResponseCode::ERROR_BUSINESS, '仅支持xls/xlsx/csv格式']); } $tempFile = $file->getRealPath(); $dataArray = (new FastExcel)->import($tempFile)->toArray(); // 数据过滤,只能导入数据表有的字段 // 获取用户表信息 $userFieldByComment = (new CustomFormField)->getRowTableFieldsByComment('users'); // 获取自定义的字段的信息 $course_forms = CourseForm::where('course_id', $course_id)->pluck('name', 'field')->toArray(); // 获取所有的字段 $fields = array_merge($userFieldByComment, $course_forms); $fields = array_filter($fields); $statusList = CourseSign::$intToString['status']; $statusList = array_flip($statusList); $list = []; foreach ($dataArray as $key => $value) { foreach ($fields as $k => $v) { if (isset($value[$v])) { // 日期格式 if ($value[$v] instanceof \DateTimeImmutable) { $list[$key][$k] = Carbon::parse($value[$v])->toDateString(); } else { if (in_array($k, ['company_type', 'type'])) { $list[$key][$k] = str_replace('、', ',', $value[$v]); $list[$key][$k] = str_replace(',', ',', $list[$key][$k]);; } else { $list[$key][$k] = $value[$v]; } } } } // 审核状态匹配 if (isset($value['审核状态']) && !empty($value['审核状态'])) { // 获取审核状态 $list[$key]['status'] = $statusList[$value['审核状态']]; $list[$key]['status_name'] = $value['审核状态']; } else { $list[$key]['status'] = 0; $list[$key]['status_name'] = '待审核'; } $list[$key] = array_merge($list[$key], ['course_id' => $course_id]); } return $this->success($list); } /** * @OA\Post( * path="/api/admin/course-signs/import", * tags={"报名管理"}, * summary="导入", * description="", * @OA\Parameter(name="data", in="query", @OA\Schema(type="string"), required=true, description="导入分析获取到的二维数组"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function import() { $all = \request()->all(); $messages = [ 'data.required' => '数据必填', ]; $validator = Validator::make($all, [ 'data' => 'required', ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $records = $all['data']; if (!isset($records[0]['course_id']) || empty($records[0]['course_id'])) { return $this->fail([ResponseCode::ERROR_BUSINESS, '课程id不存在']); } if (!isset($records[0]['mobile']) || empty($records[0]['mobile'])) { return $this->fail([ResponseCode::ERROR_BUSINESS, '联系方式必填']); } $course_id = $records[0]['course_id']; DB::beginTransaction(); try { // 获取数据表的所有字段 // 获取用户表信息 $userFieldByComment = (new CustomFormField)->getRowTableFieldsByComment('users'); // 获取自定义的字段的信息 $course_forms = CourseForm::where('course_id', $course_id)->pluck('name', 'field')->toArray(); // 获取所有的字段 $fields = array_merge($userFieldByComment, $course_forms); foreach ($records as $item) { if (empty($item['mobile'])) { return $this->fail([ResponseCode::ERROR_BUSINESS, ($item['姓名'] ?? '') . '手机号不存在']); } $where = ['mobile' => $item['mobile']]; // 去除空值更新 $userItem = array_filter($item, function ($value) { return $value != ''; }); // 所有数据通过追加的形式更新 $user = User::where($where)->first(); if ($user) { // 更新,所有$record里的数组通过追加在原来数据后面的形式更新 foreach ($userItem as $k => &$v) { if (!in_array($k, User::$coverFields)) { // 追加更新 $tempArray = explode(',', $user->$k . ',' . $v); $tempArray = array_unique(array_filter($tempArray)); $v = implode(',', $tempArray); } } $user->fill($userItem); $user->save(); } else { // 新增 $userItem['is_import'] = 1; $user = User::create($userItem); } // 更新报名表 $signWhere = ['user_id' => $user->id, 'course_id' => $course_id]; $signData = []; foreach ($item as $k2 => $v2) { if (isset($course_forms[$k2])) { $signData[] = [ 'name' => $course_forms[$k2], 'field' => $k2, 'value' => $v2 ]; } } $course = Course::find($course_id); $fee_status = $course->is_fee; if ($item['status'] == 0) $fee_status = 0; $courseSign = CourseSign::updateOrCreate($signWhere, ['is_import' => 1, 'user_id' => $user->id, 'status' => $item['status'], 'fee_status' => $fee_status, 'course_id' => $course_id, 'data' => $signData]); // 加预约次数 if ($item['status'] == 1) { CourseAppointmentTotal::add($courseSign->user_id, $courseSign->id); if ($fee_status == 1) { // 设置vip $user->is_vip = 1; $user->save(); } } } DB::commit(); return $this->success(['total' => count($records)]); } catch (\Exception $exception) { DB::rollBack(); return $this->fail([$exception->getTrace(), $exception->getMessage()]); } } /** * @OA\Post( * path="/api/admin/course-signs/batch-update-status", * tags={"报名管理"}, * summary="批量修改审核状态", * description="", * @OA\Parameter(name="course_id", in="query", @OA\Schema(type="string"), required=true, description="课程id"), * @OA\Parameter(name="ids", in="query", @OA\Schema(type="string"), required=true, description="英文逗号分隔的id数组"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="string"), required=true, description="状态0待审核1通过2拒绝"), * @OA\Parameter(name="reason", in="query", @OA\Schema(type="string"), required=true, description="reason"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function batchUpdateStatus() { $all = \request()->all(); $messages = [ 'course_id.required' => '课程必填', 'ids.required' => '编号必填', 'status.required' => '状态必填', ]; $validator = Validator::make($all, [ 'course_id' => 'required', 'ids' => 'required', 'status' => 'required', ], $messages); if ($validator->fails()) { return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } DB::beginTransaction(); try { $idsArray = explode(',', $all['ids']); foreach ($idsArray as $id) { $model = $this->model->find($id); if (empty($model)) continue; $data = ['course_id' => $all['course_id'], 'course_sign_id' => $id, 'status_text' => CourseSign::$intToString['status'][$all['status']]]; $model->status = $all['status']; $model->reason = $all['reason'] ?? ''; $model->save(); if ($model->status == 1) { Notification::send(User::find($model->user_id), new AuditNotify($data)); } } DB::commit(); return $this->success('批量更新成功'); } catch (\Exception $exception) { DB::rollBack(); return $this->fail([$exception->getCode(), $exception->getMessage()]); } } /** * @OA\Post( * path="/api/admin/course-signs/batch-update-fee-status", * tags={"报名管理"}, * summary="批量修改缴费状态", * description="", * @OA\Parameter(name="ids", in="query", @OA\Schema(type="string"), required=true, description="英文逗号分隔的id数组"), * @OA\Parameter(name="fee_status", in="query", @OA\Schema(type="string"), required=true, description="0未缴费1缴费成功2缴费失败"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function batchUpdateFeeStatus() { $all = \request()->all(); $messages = [ 'ids.required' => '编号必填', 'fee_status.required' => '状态必填', ]; $validator = Validator::make($all, [ 'ids' => 'required', 'fee_status' => 'required', ], $messages); if ($validator->fails()) { return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $idsArray = explode(',', $all['ids']); $this->model->whereIn('id', $idsArray)->update(['fee_status' => $all['fee_status']]); return $this->success('批量更新成功'); } /** * @OA\Post( * path="/api/admin/course-signs/batch-notice", * tags={"报名管理"}, * summary="批量发送缴费通知", * description="", * @OA\Parameter(name="course_id", in="query", @OA\Schema(type="string"), required=true, description="课程id"), * @OA\Parameter(name="ids", in="query", @OA\Schema(type="string"), required=true, description="英文逗号分隔的id数组"), * @OA\Parameter(name="content", in="query", @OA\Schema(type="string"), required=true, description="发送内容"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function batchNotice() { $all = \request()->all(); $messages = [ 'course_id.required' => '课程必填', 'ids.required' => 'id必填', 'content.required' => '内容必填', ]; $validator = Validator::make($all, [ 'course_id' => 'required', 'ids' => 'required', 'content' => 'required', ], $messages); if ($validator->fails()) { return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $idsArray = explode(',', $all['ids']); $data = ['course_id' => $all['course_id'], 'content' => $all['content']]; DB::beginTransaction(); try { foreach ($idsArray as $id) { $model = $this->model->find($id); if (empty($model)) continue; if ($model->fee_status == 0) { Notification::send(User::find($model->user_id), new FeeNotify($data)); } } DB::commit(); return $this->success('发送成功'); } catch (\Exception $exception) { DB::rollBack(); return $this->fail([$exception->getCode(), $exception->getMessage()]); } } /** * @OA\Get( * path="/api/admin/course-signs/retry-appointment", * tags={"报名管理"}, * summary="重新发送第三方预约信息", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function retryAppointment() { $all = \request()->all(); $messages = [ 'id.required' => 'Id必填', ]; $validator = Validator::make($all, [ 'id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $model = $this->model->find($all['id']); if (empty($model)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '数据不存在']); } $model = $this->model->with('course')->find($all['id']); $course = $model->course; // 执行预约 // 执行预约操作 if (($course->is_fee == 0 && $model->status == 1) || ($course->is_fee == 1 && $model->fee_status == 1)) { // 预约车 $user = User::find($model->user_id); // 发送车辆预约信息 if ($user->plate) { $plateArray = explode(',', $user->plate); foreach ($plateArray as $plate) { // 车辆预约 dispatch((new SendCourseCar($model, $plate))); } } // 预约门禁 dispatch((new SendCourseDoor($model))); } return $this->success('成功'); } }