You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\Admin;
use App\Exports\CommonExport;
use App\Helpers\ResponseCode;
use App\Jobs\SendAppoint;
use App\Models\Appointment;
use App\Models\AppointmentConfig;
use App\Models\User;
use App\Notifications\AppointmentNotify;
use App\Repositories\DoorRepository;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
class AppointmentController extends BaseController
{
/**
* 构造函数
*/
public function __construct()
{
parent::__construct(new Appointment());
}
/**
* @OA\Get(
* path="/api/admin/appointments/index",
* tags={"预约管理"},
* summary="列表",
* description="",
* @OA\Parameter(name="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是"),
* @OA\Parameter(name="export_fields", in="query", @OA\Schema(type="string"), required=false, description="需要导出的字段数组"),
* @OA\Parameter(name="filter", in="query", @OA\Schema(type="string"), required=false, description="查询条件。数组"),
* @OA\Parameter(name="show_relation", in="query", @OA\Schema(type="string"), required=false, description="需要输出的关联关系数组包括teachercourseSettingscoursePeriodsthirdAppointmentLogs第三方日志记录thirdPlateLogs第三方车牌预约记录"),
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
* @OA\Parameter(name="user_name", in="query", @OA\Schema(type="string"), required=false, description="用户名"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function index()
{
$all = request()->all();
$list = $this->model->with(underlineToHump($all['show_relation'] ?? []))->where(function ($query) use ($all) {
if (isset($all['user_name'])) {
$query->whereHas('user', function ($query) use ($all) {
$query->where('name', 'like', '%' . $all['user_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 == 'gt') {
$query->where($key, '>', $value);
}
// 大于等于
if ($op == 'egt') {
$query->where($key, '>=', $value);
}
// 小于
if ($op == 'lt') {
$query->where($key, '<', $value);
}
// 小于等于
if ($op == 'elt') {
$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');
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/appointments/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="需要输出的关联关系数组包括teachercourseSettingscoursePeriodsthirdAppointmentLogs第三方日志记录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('user', 'appointmentAccompany')
->with(['thirdAppointmentLogs' => function ($query) {
$query->where('url', 'not like', '%GetEmpQrCode%');
}])->find($all['id']);
return $this->success($detail);
}
/**
* @OA\Post(
* path="/api/admin/appointments/save",
* tags={"预约管理"},
* summary="更新或新增",
* @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=true, description="课程ID存在则更新不存在则新增"),
* @OA\Parameter(name="user_id", in="query", @OA\Schema(type="string", format="date"), description="用户id创建时多个用户英文逗号分隔"),
* @OA\Parameter(name="date", in="query", @OA\Schema(type="string", format="date"), description="预约日期"),
* @OA\Parameter(name="start_time", in="query", @OA\Schema(type="string", format="date-time"), description="开始时间,例如2023-01-01 11:11:11"),
* @OA\Parameter(name="end_time", in="query", @OA\Schema(type="string", format="date-time"), description="结束时间,例如2023-01-01 11:11:11"),
* @OA\Parameter(name="content", in="query", @OA\Schema(type="string"), description="预约事项"),
* @OA\Parameter(name="site", in="query", @OA\Schema(type="integer"), description="预约地点ID。数字1-6"),
* @OA\Parameter(name="plate", in="query", @OA\Schema(type="string"), description="车牌号。多个英文逗号分隔"),
* @OA\Parameter(name="accompany_total", in="query", @OA\Schema(type="integer"), description="陪同人数"),
* @OA\Parameter(name="status", in="query", @OA\Schema(type="integer"), description="状态 0未审核 1审核通过 2审核不通过3取消"),
* @OA\Parameter(name="reason", in="query", @OA\Schema(type="string"), description="审核不通过原因"),
* @OA\Parameter(name="name", in="query", @OA\Schema(type="string"), description="名字"),
* @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), description="手机号"),
* @OA\Parameter(name="idcard", in="query", @OA\Schema(type="string"), description="身份证号码"),
* @OA\Parameter(name="accompany", in="query", @OA\Schema(type="string"), description="陪同人员二维数组包括nameidcardmobile"),
* @OA\Parameter(name="is_hand", in="query", @OA\Schema(type="string"), description="是否手动预约0否1是"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function save()
{
$all = \request()->all();
$is_hand = request('is_hand', 1);
$userIds = explode(',', $all['user_id']);
$success = 0;
$err = [];
foreach ($userIds as $userId) {
$all['user_id'] = $userId;
$result = $this->saveData($all, $is_hand, $out);
if ($result) {
$success++;
} else {
$err[] = $out;
}
}
return $this->success(['total' => count($userIds), 'success' => $success, 'err' => $err]);
}
/**
* @OA\Get(
* path="/api/admin/appointments/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()
{
$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, '数据不存在']);
}
// 取消预约
Appointment::sendCancelAppoin($model);
$model->delete();
// 记录日志
$this->saveLogs('delete', $model);
return $this->success('删除成功');
}
/**
* @OA\Post(
* path="/api/admin/appointments/excel-show",
* tags={"预约管理"},
* summary="导入预览",
* description="",
* @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()
{
return parent::excelShow();
}
/**
* @OA\Post(
* path="/api/admin/appointments/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()
{
return parent::import();
}
/**
* 更新新增操作
* @param $all
*/
public function saveData($all, $is_hand, &$out)
{
DB::beginTransaction();
try {
if (isset($all['id'])) {
$model = Appointment::find($all['id']);
if (empty($model)) {
$out = '数据不存在';
return false;
}
} else {
$model = new Appointment();
$all['admin_id'] = $this->getUserId();
$all['department_id'] = $this->getUser()->department_id;
// 检测是否有预约次数
if (isset($all['user_id']) && !empty($all['user_id'])) {
$user = User::find($all['user_id']);
if (empty(User::getHasAppointment($all['user_id']))) {
$out = $user->name . '预约次数不足';
return false;
}
if (empty($is_hand)) {
// 批量预约预约,默认取用户信息
$all['name'] = $user->name ?? '';
$all['mobile'] = $user->mobile ?? '';
$all['idcard'] = $user->idcard ?? '';
$all['plate'] = $user->plate ?? '';
}
}
$all['code'] = randStr(8);
}
$original = $model->getOriginal();
$model->fill($all);
$model->save();
// 写入陪同人员
if (isset($all['accompany']) && !empty($all['accompany'])) {
$model->appointmentAccompany()->delete();
$model->appointmentAccompany()->createMany($all['accompany']);
}
DB::commit();
// 预约地点配置
$appointmentConfig = $model->site_detail;
// 确认预约-根据预约情况调用三方接口
if (($original && $original['status'] == 0 && $model->status == 1) || (empty($original) && $model->status == 1)) {
// 发送预约
dispatch((new SendAppoint($model, $appointmentConfig)));
}
if (($original && $original['status'] == 0 && in_array($model->status, [1, 2, 4]))) {
// 预约结果通知
$data = ['appointment_id' => $model->id];
Notification::send(User::find($model->user_id), new AppointmentNotify($data));
}
// 取消预约
if (($original && $original['status'] == 1 && $model->status == 3)) {
Appointment::sendCancelAppoin($model);
}
// 记录日志
$this->saveLogs($original, $model);
$out = '成功';
return true;
} catch (\Exception $exception) {
DB::rollBack();
$out = $exception->getMessage();
return false;
}
}
/**
* @OA\Get(
* path="/api/admin/appointments/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->find($all['id']);
$appointmentConfig = $model->site_detail;
// 执行预约
if ($model->status == 1 || $model->status == 4) {
$doors = $appointmentConfig->pluck('door')->filter();
if ($doors->isNotEmpty()) {
$result = (new DoorRepository)->checkRepeatDoor($model->mobile, $appointmentConfig, $model->end_time, $out);
if (!$result) {
return $this->fail([ResponseCode::ERROR_BUSINESS, $out]);
}
}
// 发送预约
dispatch((new SendAppoint($model, $appointmentConfig)));
}
// 取消预约
if (($model->status == 3)) {
Appointment::sendCancelAppoin($model);
}
return $this->success('成功');
}
}