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.

226 lines
11 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\Models\Admin;
use App\Models\Blacklist;
use App\Models\GateLog;
use App\Models\Role;
use App\Models\Visit;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Helpers\ResponseCode;
use Illuminate\Support\Carbon;
use Rap2hpoutre\FastExcel\FastExcel;
/**
* 门岗
*/
class GateController extends CommonController
{
/**
* @OA\Get(
* path="/api/admin/gate/user-list",
* tags={"门岗-门岗人列表"},
* summary="列表",
* description="",
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function uerList()
{
$admin = Admin::whereHas('role', function ($query) {
$query->where('name', 'like', '%门岗%');
})->get();
return $this->success($admin);
}
/**
* @OA\Get(
* path="/api/admin/gate/visit-list",
* tags={"门岗-拜访记录"},
* summary="拜访记录",
* description="",
* @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="关键词"),
* @OA\Parameter(name="audit_status", in="query", @OA\Schema(type="string"), required=false, description="审核状态-1待学习0待审核1通过(待进厂)2驳回3已进厂4已离厂"),
* @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=false, description="开始日期"),
* @OA\Parameter(name="end_date", in="query", @OA\Schema(type="string"), required=false, description="结束日期"),
* @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="code", in="query", @OA\Schema(type="string"), required=false, description="编码"),
* @OA\Parameter(name="idcard", in="query", @OA\Schema(type="string"), required=false, description="身份证号码"),
* @OA\Parameter(name="car_no", in="query", @OA\Schema(type="string"), required=false, description="停车牌"),
* @OA\Parameter(name="person_no", in="query", @OA\Schema(type="string"), required=false, description="人牌"),
* @OA\Parameter(name="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是默认0"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function visitList()
{
$all = request()->all();
$list = Visit::with('logs.admin', 'logs.user', 'visitTime', 'admin', 'visitArea', 'acceptAdmin.department', 'acceptAdminSignFile', 'acceptGoodsAdmin.department')->where(function ($query) use ($all) {
if (isset($all['keyword'])) {
$query->where('name', 'like', '%' . $all['keyword'] . '%');
}
if (isset($all['audit_status'])) {
$query->where('audit_status', $all['audit_status']);
}
if (isset($all['code'])) {
$query->where('code', $all['code']);
}
if (isset($all['idcard'])) {
$query->where('idcard', $all['idcard']);
}
// 普通访客:按预约到访日 date 落在查询区间内;长期访客:查询区间与长期有效区间 [start_date,end_date] 有交集即可出现在「今日」等列表中
if (!empty($all['start_date']) && !empty($all['end_date'])) {
$qs = $all['start_date'];
$qe = $all['end_date'];
$query->where(function ($sub) use ($qs, $qe) {
$sub->where(function ($q1) use ($qs, $qe) {
$q1->where(function ($q2) {
$q2->whereNull('long_time')->orWhere('long_time', 0);
})->whereBetween('date', [$qs, $qe]);
})->orWhere(function ($q1) use ($qs, $qe) {
$q1->where('long_time', 1)
->whereNotNull('start_date')
->whereNotNull('end_date')
->where('start_date', '<=', $qe)
->where('end_date', '>=', $qs);
});
});
}
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc');
if (isset($all['is_export']) && !empty($all['is_export'])) {
return (new FastExcel($list->limit(10000)->get()->toArray()))->download('门岗访客记录' . date('YmdHis') . '.csv', function ($info) {
return [
'编码' => $info['code'] ?? '',
'姓名' => $info['name'] ?? '',
'类型' => $info['type_text'] ?? '',
'审核状态' => $info['audit_status_text'] ?? '',
'被访人' => ($info['accept_admin']['name']) ?? '',
'预约日期' => $info['date'] ?? '',
'证件号' => $info['idcard'] ?? '',
'手机号' => $info['mobile'] ?? '',
'单位名称' => $info['company_name'] ?? '',
'到访时段开始' => ($info['visit_time']['start_time']) ?? '',
'到访时段结束' => ($info['visit_time']['end_time']) ?? '',
'创建时间' => $info['created_at'] ?? '',
];
});
}
$list = $list->paginate($all['page_size'] ?? 20);
return $this->success($list);
}
/**
* @OA\Get(
* path="/api/admin/gate/use-code",
* tags={"门岗-核销"},
* summary="核销",
* description="",
* @OA\Parameter(name="admin_id", in="query", @OA\Schema(type="string"), required=false, description="管理员id"),
* @OA\Parameter(name="code", in="query", @OA\Schema(type="string"), required=false, description="编码"),
* @OA\Parameter(name="car_no", in="query", @OA\Schema(type="string"), required=false, description="停车牌"),
* @OA\Parameter(name="person_no", in="query", @OA\Schema(type="string"), required=false, description="人牌"),
* @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=false, description="1进厂2离厂"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function useCode()
{
$all = \request()->all();
$messages = [
'code.required' => '编号必填',
'type.required' => '类型必填',
'admin_id.required' => '操作人必填'
];
$validator = Validator::make($all, [
'code' => 'required',
'type' => 'required',
'admin_id' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$check = Visit::where('code', $all['code'])->first();
if (empty($check)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '拜访记录不存在']);
}
if ($check->audit_status == 2 || $check->audit_status == 5) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '当前记录不可核销']);
}
// 物流访客:每次进/离厂都必须先上传当次车辆照片
if ((int)$check->type === 3) {
$latestGateLog = GateLog::where('visit_id', $check->id)->orderByDesc('id')->first();
$fileIds = [];
if (is_array($check->file)) {
$fileIds = $check->file;
} elseif (is_string($check->file) && !empty($check->file)) {
$decoded = json_decode($check->file, true);
if (is_array($decoded)) {
$fileIds = $decoded;
}
}
$hasPhoto = count($fileIds) > 0;
if (!$hasPhoto) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '物流访客需先上传车辆照片后再核销']);
}
// 要求本次核销前有一次新的更新动作,避免重复使用上次照片直接核销
if (!empty($latestGateLog) && strtotime((string)$check->updated_at) <= strtotime((string)$latestGateLog->created_at)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '物流访客本次进/离厂请先上传当次照片']);
}
}
// 长期访客:校验当前日期在有效周期内
$today = Carbon::now()->format('Y-m-d');
if ((int)$check->long_time === 1) {
if (empty($check->start_date) || empty($check->end_date)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '长期访客未配置有效周期']);
}
if ($today < $check->start_date || $today > $check->end_date) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '当前不在长期访客有效周期内']);
}
$todayLastLog = GateLog::where('visit_id', $check->id)->where('biz_date', $today)->orderByDesc('id')->first();
if ((int)$all['type'] === 1 && $todayLastLog && (int)$todayLastLog->action === 1) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '今日已进厂,请先离厂后再进厂']);
}
if ((int)$all['type'] === 2 && (!$todayLastLog || (int)$todayLastLog->action !== 1)) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '今日无有效进厂记录,无法离厂']);
}
}
$remark = '进厂';
if ($all['type'] == 2) {
$remark = '离厂';
}
$gateLog = GateLog::add($all['admin_id'], $all['code'], $all['person_no'] ?? [], $all['car_no'] ?? [], $remark, $check->id, (int)$all['type'], $today);
if ($all['type'] == 1) {
// 入场
Visit::where('code', $all['code'])->update(['audit_status' => 3, 'person_no' => $all['person_no'] ?? '', 'car_no' => $all['car_no'] ?? '']);
// 通知被访人
$vars = ['date' => $check->date, 'name' => $check->name, 'phone_number' => $check->mobile];
$template_id = 'zPtka4';
$acceptAdmin = Admin::find($check->accept_admin_id);
sms($acceptAdmin->mobile, $vars, $template_id);
}
if ($all['type'] == 2) {
Visit::where('code', $all['code'])->update(['audit_status' => 4]);
}
return $this->success($gateLog);
}
}