TicketController.php 11.1 KB
<?php

namespace App\Http\Controllers\Api\WorkOrder;

use App\Enums\Common\Code;
use App\Http\Controllers\Api\BaseController;
use App\Http\Logic\Aside\Project\ProcessRecordsLogic;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Http\Requests\Api\WorkOrder\TicketListRequest;
use App\Http\Requests\Api\WorkOrder\TicketStoreRequest;
use App\Models\Project\ProcessRecords;
use App\Models\Project\Project;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Models\WorkOrder\TicketLog;
use App\Models\WorkOrder\TicketProject;
use App\Models\WorkOrder\Tickets;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class TicketController extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(TicketListRequest $request, $project_id)
    {
        $validated = $request->validated();
        $project = TicketProject::where('uuid', $project_id)->first();
        if (!$project) return $this->error('未找到项目', 404);
        $page = (int)$request->input('page', 1);
        $size = (int)$request->input('size', 10);

        $tickets = Tickets::with([
            'project.pm',
            'project.assm',
            'project.seom',
            'project.first_engineer',
            'logs.engineer',
        ])
            ->where('project_id', $project->id)
            ->where('title', 'not like', '研发工单%')
//            ->where('submit_side', 2)
            ->when($request->input('status') !== null, function ($query) use ($request) {
                // status 查 gl_tickets.status
                $status = $request->input('status');
                return $query->where('status', $status);
            })
            ->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 . '%');
                        });
                });
            })
            ->orderBy('id', 'desc')
            ->paginate($size, ['*'], 'page', $page);
        return response()->json(['data' => $tickets]);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     * B端用户在企微群里提交工单
     */
    public function store($project_id, TicketStoreRequest $request)
    {
        $request->validated();
        $project = TicketProject::where('uuid', $project_id)->first();
        if (!$project) return response('未找到项目', 404);
        if ($project->is_del) return response('项目状态异常', 400);
        if (empty($project->first_engineer)) return response('项目未分配工单负责人', 400);

        $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 = 2; // 2 for B-side submission
            $ticket->submit_username = $request->input('submit_username');
            $ticket->save();
            $ticket->saveEngineers([$project->engineer_id]);
            $project->pushWechatGroupMsg("客户新增了工单(ID:{$ticket->id}),请及时处理!");
            return $ticket;
        });
        return response()->json(['data' => $result]);
    }

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

        if (!$ticket) return response('工单未找到', 404);

        if ($ticket->project->uuid !== $project_id) return response('无权限查看该工单', 403);

        if ($ticket->project->is_del) return response('项目状态异常', 400);

        return response()->json(['data' => $ticket]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

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

    public function projectInfo($project_id)
    {
        $project = TicketProject::with([
            'pm',
            'assm',
            'seom',
            'first_engineer',
        ])
            ->where('uuid', $project_id)->first();
        if (!$project) return response()->json(['message' => '未找到对应的工单项目'], 404);
        return response()->json(['data' => $project]);
    }

    /**
     * @param $friend_id
     * @return void
     * 企微群里@小超或艾丝,触发推送工单
     * 接收群ID
     */
    public function pushTicketByBot($friend_id)
    {
        $project = TicketProject::where('wechat_group_id', $friend_id)->where('is_del', 0)->first();
        if (!$project)
            return response()->json(['message' => '未找到对应的工单项目'], 404);

//        $url = in_array($project->project_cate, [3,4]) ? 'https://hub.ai.cc/api/fob_ai_customer_service/push_message' : 'https://hub.ai.cc/api/globalso_ai_customer_service/send_msg';
//        $response = Http::post($url, [
//            'type' => 'Link',
//            'friend_id' => $friend_id,
//            'content' => json_encode([
//                'title' => 'AI协同工单 - ' . $project->company_name,
//                'desc' => "您好,我们同事没有及时回复,你可以查看工单进度!",
//                'size' => 0,
//                'thumbSize' => 0,
//                'thumbUrl' => 'https://hub.globalso.com/logocm.png',
//                'url' => 'https://oa.quanqiusou.cn/afterorder?project_id='.$project->uuid
//            ], JSON_UNESCAPED_UNICODE)
//        ]);
//        // 返回 $response 的相应内容以及网络状态码
//        return response($response->body(), $response->status());

        $project->pushWechatGroupMsg("您好,我们同事没有及时回复,你可以查看工单进度!");
        return response()->json(['message' => '工单推送成功']);
    }

    /**
     * @remark :工单中获取
     * @name   :get_process_records
     * @author :lyh
     * @method :post
     * @time   :2025/9/9 15:28
     */
    public function get_project_records(Request $request){
        $request->validate([
            'project_id'=>'required'
        ],[
            'project_id.required' => '项目ID不能为空'
        ]);
        $data = (new ProcessRecords())->read(['project_id'=>$this->param['project_id']]);
        $project = (new Project())->with(['payment', 'deploy_build', 'deploy_optimize', 'online_check',
            'project_after','inquiry_filter_config','web_traffic_config','project_keyword'])->where(['id'=>$this->param['project_id']])->first()->toArray();
        if(!$data){
            $data = [
                'project_id' => $this->param['project_id'],
                'record' => [],
                'remark' => '',
                'project_record'=>0,
                'optimize_record'=>0,
                'type'=>$project['type']
            ];
        }else{
            $data['type'] = $project['type'];
        }
        $data['record'] = array_filter($data['record'], function($item) {
            return $item['date'] > '2025-09-01';
        });
        if($project['type'] == 2 || ($project['deploy_build']['seo_plan'] > 0 && ($project['deploy_build']['plan'] == 0))){
            //优化项目  默认在seo优化中
            if($data['optimize_record'] == 0) {
                $data['optimize_record'] = 1;
            }
            //时间大于优化时间,默认
            if(date('Y-m-d') > $project['deploy_optimize']['start_date']){
                $data['optimize_record'] = 2;
            }
            //首次达标时间
            if(!empty($project['deploy_optimize']['first_compliance_time'])){
                $data['optimize_record'] = 3;
            }
            //无剩余时间
            if($project['project_type'] == 1){
                $remain_day = $project['seo_remain_day'];
                if($project['seo_remain_day'] == 0){$data['optimize_record'] = 4;}
            }else{
                $remain_day = $project['remain_day'];
                if($project['remain_day'] == 0){$data['optimize_record'] = 4;}
            }
            if(in_array(2,$project['level'])){
                $data['date_project_record'] = ['暂停优化'];
            }else{
                $data['date_project_record'] = Project::projectProgress('optimize');
                $data['date_project_record'][4] .= (': '.$remain_day.'天');
            }
        }else{
            //查看是否绑定微信群
            $projectAss = new ProjectAssociation();
            $count = $projectAss->counts(['project_id'=>$this->param['project_id']]);
            if(($count > 0) && ($data['project_record'] == 0)){
                $data['project_record'] = 1;
            }
            $data['date_project_record'] = Project::projectProgress('build');
        }
        $this->response('success',Code::SUCCESS,$data);
    }

    /**
     * @remark :获取项目uuid
     * @name   :getProjectUuid
     * @author :lyh
     * @method :post
     * @time   :2025/11/19 11:35
     */
    public function getProjectUuid()
    {
        $this->request->validate([
            'post_id'=>'required',
            'project_cate'=>'required'
        ],[
            'post_id.required' => '项目post_id不能为空',
            'project_cate.required' => '项目类型不能为空'
        ]);
        $ticketProjectModel = new TicketProject();
        $uuid = $ticketProjectModel->getValue(['post_id'=>$this->param['post_id'],'project_cate'=>$this->param['project_cate']],'uuid');
        $this->response('success',Code::SUCCESS,['project_id'=>$uuid]);
    }

    /**
     * @remark :类型
     * @name   :getorderTypeOptions
     * @author :lyh
     * @method :post
     * @time   :2025/11/27 17:02
     */
    public function getorderTypeOptions()
    {
        $ticket = new Tickets();
        $data = $ticket->getApiOrderTypeOptions();
        $this->response('success', Code::SUCCESS, $data);
    }
}