AsideTicketController.php 15.2 KB
<?php

namespace App\Http\Controllers\Aside\WorkOrder;

use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Http\Requests\Aside\WorkOrder\AsideTicketStoreRequest;
use App\Http\Requests\Aside\WorkOrder\AsideTicketListRequest;
use App\Http\Requests\Aside\WorkOrder\AsideTicketUpdateRequest;
use App\Http\Requests\Aside\WorkOrder\TicketProjectListRequest;
use App\Models\Manage\ManageHr;
use App\Models\WorkOrder\TicketLog;
use App\Models\WorkOrder\TicketProject;
use App\Models\WorkOrder\Tickets;
use Illuminate\Support\Facades\DB;


class AsideTicketController extends BaseController
{
    /**
     * A端查看所有工单
     *
     * @return \Illuminate\Http\Response
     */
    public function index(AsideTicketListRequest $request)
    {
        $validated = $request->validated();
        $query = Tickets::with([
            'logs.engineer',
            'project.pm:',
            'project.projectV6',
        ])
            ->when(!empty($validated['engineer_id']), function ($query) use ($validated) {
                // 查 gl_tickets 表 submit_user_id 或 gl_ticket_logs 表 engineer_id
                $engineerId = $validated['engineer_id'];
                return $query->where(function ($q) use ($engineerId) {
                    $q->where('submit_user_id', $engineerId)
                        ->orWhereHas('logs', function ($q1) use ($engineerId) {
                            $q1->where('engineer_id', $engineerId);
                        });
                });
            })
            ->when($request->input('project_id') !== null, function ($query) use ($request) {
                // project_id 查 gl_ticket_projects.uuid
                $projectId = $request->input('project_id');
                return $query->whereHas('project', function ($q) use ($projectId) {
                    $q->where('uuid', $projectId);
                });
            })
            ->when($request->input('status') !== null, function ($query) use ($request) {
                // status 查 gl_tickets.status
                $status = $request->input('status');
                if($status == '-1'){
                    $newTime = date("Y-m-d H:i:s", strtotime("-120 hours"));
                    return $query->where('status', 0)->where('plan_end_at','<',$newTime);//超过120个小时未处理的工单
                }else{
                    return $query->where('status', $status);
                }

            })
            ->when($request->input('timeout') !== null, function ($query) use ($request) {
                // status 查 gl_tickets.status
                $timeout = $request->input('timeout');
                switch ($timeout) {
                    case 1:
                        $newTime = date("Y-m-d H:i:s", strtotime("-24 hours"));
                        break;
                    case 2:
                        $newTime = date("Y-m-d H:i:s", strtotime("-48 hours"));
                        break;
                    case 3:
                        $newTime = date("Y-m-d H:i:s", strtotime("-72 hours"));
                        break;
                    default:
                        $newTime = date("Y-m-d H:i:s");
                        break;
                }
                return $query->where('status', 0)->where('plan_end_at','<',$newTime);//超过120个小时未处理的工单
            })
            ->when($request->input('star') !== null, function ($query) use ($request) {
                $star = $request->input('star');
                return $query->where('star', $star);
            })
            ->when($request->input('search'), function ($query) use ($request) {
                // search 查 gl_tickets.title 或 gl_ticket_projects.title 或 gl_ticket_projects.company_name
                $search = $request->input('search');
                return $query->where(function ($q) use ($search) {
                    $q->where('title', 'like', '%' . $search . '%')
                        ->orWhereHas('project', function ($q1) use ($search) {
                            $q1->where('title', 'like', '%' . $search . '%')
                                ->orWhere('company_name', 'like', '%' . $search . '%');
                        });
                });
            })
            // 根据TicketProject的status字段筛选
            ->when($request->input('project_status') !== null, function ($query) use ($request) {
                $projectStatus = $request->input('project_status');
                return $query->whereHas('project', function ($q) use ($projectStatus) {
                    $q->where('status', $projectStatus);
                });
            })
            // 根据TicketProject的project_cate字段筛选
            ->when($request->input('project_cate') !== null, function ($query) use ($request) {
                $projectCate = $request->input('project_cate');
                return $query->whereHas('project', function ($q) use ($projectCate) {
                    $q->where('project_cate', $projectCate);
                });
            });
        //TODO::用户部门搜索
        if(isset($this->param['dept_id']) && !empty($this->param['dept_id'])){
            $manageHrModel = new ManageHr();
            $manageIdArr = $manageHrModel->selectField(['dept_id'=>$this->param['dept_id'],'status'=>1],'manage_id');
            $query->whereHas('logs', function ($q) use ($manageIdArr) {
                $q->whereIn('engineer_id', $manageIdArr);
            });
        }
        if(!empty($this->param['start_at']) && !empty($this->param['end_at'])){
            return $query->whereBetween('created_at',[$this->param['start_at'],$this->param['end_at']]);
        }

        // 添加排序功能
        $query->orderBy('status', 'asc');
//        $query->orderBy('id', 'desc');
        $sortField = $request->input('sort_field', 'plan_end_at');
        $sortOrder = strtolower($request->input('sort_order', 'asc'));
        $query->orderBy($sortField, $sortOrder);
        if ($sortField != 'plan_end_at') $query->orderBy('plan_end_at', 'asc');
        $lists = $query->paginate($this->row, ['*'], 'page', $this->page)->toArray();
        if(!empty($lists) && !empty($lists['list'])){
            foreach ($lists['list'] as $key => $item){
                //计算超时多少个小时
                if($item['status'] == 0){
                    $end = date('Y-m-d H:i:s');
                    $start = $item['plan_end_at'];
                    if($start < $end){
                        $item['plan_ent_time'] =  diffInHours($start,$end);
                    }
                }
                $lists['list'][$key] = $item;
            }
        }
        $this->response('success', Code::SUCCESS, $lists);
    }


        /**
     * @param $search
     * @return void
     * V5V6所有项目
     */
    public function getProjects($search)
    {
        $projects = TicketProject::where(function ($query) use ($search) {
                // 查找项目名称或公司名称
                $query->where('title', 'like', '%' . $search . '%')
                    ->orWhere('company_name', 'like', '%' . $search . '%');
            })
            ->get();
        $this->response('success', Code::SUCCESS, $projects);
    }

    /**
     * @param TicketProjectListRequest $request
     * @return void
     * A端V5V6项目列表
     */
    public function projectList(TicketProjectListRequest $request)
    {
        $validated = $request->validated();
        $dept_id = ManageHr::where('manage_id', $this->manage['id'])
            ->value('dept_id');

        $lists = TicketProject::when(($this->manage['role'] != 1 && $dept_id != 5), function ($query) use ($dept_id) {
                /**
                 * 超管看所有项目 $this->manage['role']=1
                 * 全球搜: 技术部ID 1、售后部ID 2
                 * 超迹AI: AICC技术部 ID 4
                 * 域途:域途运营部 ID 17
                 */
                if (in_array($dept_id, [1, 2])) {
                    // V5 V6
                    return $query->whereIn('project_cate', [1, 2]);
                }elseif ($dept_id == 4) {
                    // 超迹AI
                    return $query->where('project_cate', 3);
                }elseif ($dept_id == 17){
                    // 域途
                    return $query->where('project_cate', 4);
                }else{
                    // 其他部门,不允许看数据
                    return $query->where('id', 0); // 返回空结果
                }
            })
            ->when(!empty($validated['search']), function ($query) use ($validated) {
                // 查找项目名称或公司名称
                $search = $validated['search'];
                return $query->where(function ($q) use ($search) {
                    $q->where('title', 'like', '%' . $search . '%')
                        ->orWhere('company_name', 'like', '%' . $search . '%');
                });
            })
            ->when(!empty($validated['version']), function ($query) use ($validated) {
                // 版本号筛选
                $version = $validated['version'];
                return $query->where('version', $version);
            })
            ->when(!empty($validated['project_cate']), function ($query) use ($validated) {
                // 版本号筛选
                $project_cate = $validated['project_cate'];
                return $query->where('project_cate', $project_cate);
            })
            ->paginate($this->row, ['*'], 'page', $this->page);
        $this->response('success', Code::SUCCESS, $lists);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(AsideTicketStoreRequest $request)
    {
        $request->validated();
        $project = TicketProject::where('uuid', $request->input('project_id'))->first();
        if ($project->is_del) $this->response('该项目状态异常', Code::USER_MODEL_NOTFOUND_ERROE);
        $result = DB::transaction(function () use ($request, $project) {
            $ticket = new Tickets();
            $ticket->project_id = $project->id;
            $ticket->title = $request->input('title');
            $ticket->content = $request->input('content');
            // $files = [NULL]
            $files = $request->input('files');
            if (empty($files) || (is_array($files) && count(array_filter($files, function($v){ return !is_null($v); })) === 0)) {
                $ticket->files = null;
            } else {
                $ticket->files = json_encode($files);
            }
            $ticket->submit_side = 1; // 1 for A-side submission
            $ticket->submit_user_id = $this->manage['id'];
            $ticket->submit_username = $this->manage['name'];
            $ticket->star = $request->input('star', 3);
            $ticket->plan_end_at = $request->input('plan_end_at', null);
            $ticket->close_wechat = $request->input('close_wechat', false);
            $ticket->num = $request->input('num', 0);
            $ticket->save();
            // 分配工单参与人
            $ticket->saveEngineers($request->input('engineer_ids', []));
            $nickname = ManageHr::where('manage_id', $this->manage['id'])->value('nickname') ?? mb_substr($ticket->submit_username, 0, 1) . '**';
            if ($project->wechat_switch && !$ticket->close_wechat)
                $project->pushWechatGroupMsg("创贸({$nickname})新增了工单(ID:{$ticket->id}),请及时处理!");
            return $ticket;
        });
        $this->response('success', Code::SUCCESS, $result->toArray());
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $ticket = Tickets::with([
            'logs.engineer',
            'project.projectV6:id,company,title',
        ])->find($id);

        if (!$ticket) $this->response('工单不存在', Code::USER_MODEL_NOTFOUND_ERROE);

        $this->response('success', Code::SUCCESS, $ticket->toArray());
    }

    /**
     * A端负责人修改工单
     * 1. 邀请同事
     * 2. 修改工单状态
     */
    public function update(AsideTicketUpdateRequest $request, $id)
    {
        $request->validated();
        $ticket = Tickets::find($id);
        if (!$ticket) $this->response('工单不存在', Code::USER_MODEL_NOTFOUND_ERROE);

        // 开始修改
        $result = DB::transaction(function () use ($request, $ticket) {
            if ($request->input('engineer_ids'))
                $ticket->saveEngineers($request->input('engineer_ids'));

            // 其他字段有提交数据才修改,比如star plan_end_at
            if ($request->input('title'))
                $ticket->title = $request->input('title');
            if ($request->input('content'))
                $ticket->content = $request->input('content');
            if ($request->input('star'))
                $ticket->star = $request->input('star');
            if ($request->input('plan_end_at'))
                $ticket->plan_end_at = $request->input('plan_end_at');
            if ($request->input('status'))
                $ticket->status = $request->input('status');
            if ($request->input('num'))
                $ticket->num = $request->input('num',0);
            //同步更改工单时间
            $ticket->logs()->where('status', '<', TicketLog::STATUS_COMPLETED)->where('is_engineer', 1)->update(['plan_end_at' => $ticket->plan_end_at]);
            if ($ticket->status == Tickets::STATUS_COMPLETED)
            {
                // 完成工单,把子任务里面未完成的工单改为完成
                $ticket->end_at = now();
                $ticket->end_time = diffInHours($ticket->created_at,now());
                $ticket->logs()->where('status', '<', TicketLog::STATUS_COMPLETED)->where('is_engineer', 1)
                    ->update(['status' => TicketLog::STATUS_COMPLETED, 'end_at' => now(),'end_time'=>$ticket->end_time]);
                // 推动微信通知
                $project = $ticket->project;
                if ($project->wechat_switch && !$ticket->close_wechat)
                    $project->pushWechatGroupMsg("工单(ID:{$ticket->id})已全部完成,请访问查看详情!");
                $ticket->pushDing('finish');

            }
            $ticket->save();
            return $ticket;
        });
        $this->response('success', Code::SUCCESS, $result->toArray());
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }


    /**
     * 手动触发,推送工单到企微群
     */
    public function pushNotify($id)
    {
        $project = TicketProject::where('uuid', $id)
            ->where('is_del', 0)
            ->first();

        if (empty($project))
            $this->response('工单项目不存在', Code::USER_MODEL_NOTFOUND_ERROE);

        if (empty($project->wechat_group_id)) {
            $this->response('该工单没有绑定的企微群', Code::USER_MODEL_NOTFOUND_ERROE);
        }
        if ($project->wechat_switch)
            $project->pushWechatGroupMsg();
        $this->response('success', Code::SUCCESS);
    }

}