<?php
namespace app\adminVue\controller;

use think\facade\Db;

/** 小程序点检异常的只读后台列表。 */
class V2CheckIssue extends V2Base
{
    private function configRows(){return Db::name('me_base')->whereIn('mid',[20,21])->order('id')->select()->toArray();}
    public function settings(){
        $rows=$this->configRows();$notify=[];$mapping=[];
        foreach($rows as $r){if((int)$r['mid']===20)$notify[]=(int)$r['title'];else {if(isset($mapping[$r['mark']]))$this->fail('项目负责人配置重复，请核对mid=21记录',409);$mapping[$r['mark']]=$r;}}
        $projects=Db::name('team_base')->where('mid',1)->whereIn('content',[1,2])->field('id,title')->orderRaw('CAST(mark AS SIGNED) ASC')->order('id')->select()->toArray();
        foreach($projects as &$p){$r=$mapping[$p['id']]??[];$p['dayId']=(int)($r['title']??0);$p['nightId']=(int)($r['content']??0);}unset($p);
        return json(['code'=>0,'data'=>['version'=>hash('sha256',json_encode($rows)),'notifyIds'=>$notify,'projects'=>$projects,'people'=>Db::name('admin_user')->where('status',1)->field('id,username,truename,dpt')->order('truename,id')->select()->toArray()]]);
    }
    public function saveSettings(){
        $lock='check-issue-settings:'.substr(hash('sha256',Db::connect()->getConfig('database')),0,32);
        $got=Db::query('SELECT GET_LOCK(?,5) acquired',[$lock]);if((int)$got[0]['acquired']!==1)$this->fail('配置正在保存，请稍后重试',409);
        try{Db::transaction(function(){
            $rows=$this->configRows();if($this->request->post('version')!==hash('sha256',json_encode($rows)))$this->fail('配置已变化，请重新打开窗口',409);
            $kind=$this->request->post('kind');
            if($kind==='notify'){
                $ids=$this->request->post('personIds');if(!is_array($ids)||count($ids)>200)$this->fail('通知人员参数无效');
                foreach($ids as $id)$this->validatePerson($id,true);$ids=array_values(array_unique(array_map('intval',$ids)));
                Db::name('me_base')->where('mid',20)->delete();foreach($ids as $id)Db::name('me_base')->insert(['mid'=>20,'title'=>(string)$id,'content'=>'','mark'=>'','status'=>1]);
            }elseif($kind==='project'){
                $id=$this->request->post('projectId');if(!is_scalar($id)||!preg_match('/^[1-9][0-9]*$/D',(string)$id)||!Db::name('team_base')->where(['id'=>$id,'mid'=>1])->whereIn('content',[1,2])->count())$this->fail('项目不可用');
                $day=$this->request->post('dayId',0);$night=$this->request->post('nightId',0);$this->validatePerson($day);$this->validatePerson($night);
                $existing=Db::name('me_base')->where(['mid'=>21,'mark'=>(string)$id])->select()->toArray();if(count($existing)>1)$this->fail('项目配置重复',409);
                $data=['title'=>(string)(int)$day,'content'=>(string)(int)$night];if($existing)Db::name('me_base')->where('id',$existing[0]['id'])->update($data);else Db::name('me_base')->insert($data+['mid'=>21,'mark'=>(string)$id,'status'=>1]);
            }else $this->fail('配置类型无效');
        });}finally{Db::query('SELECT RELEASE_LOCK(?)',[$lock]);}
        return $this->settings();
    }
    private function validatePerson($id,$engineer=false){
        if(!$engineer&&($id===0||$id==='0'||$id===''))return;
        if(!is_scalar($id)||!preg_match('/^[1-9][0-9]{0,9}$/D',(string)$id))$this->fail('人员参数无效');
        $q=Db::name('admin_user')->where(['id'=>$id,'status'=>1]);$q->where('dpt',2);if(!$q->count())$this->fail($engineer?'请选择有效工程部人员':'请选择有效工程部负责人');
    }
    public function options() {
        return json(['code'=>0,'data'=>['projects'=>Db::name('team_base')->where('mid',1)->whereIn('content',[1,2])->field('id,title')->orderRaw('CAST(mark AS SIGNED) ASC')->order('id')->select()->toArray()]]);
    }
    public function index() {
        $page=$this->request->get('page',1);$limit=$this->request->get('limit',20);
        foreach(['page'=>[$page,1000000],'limit'=>[$limit,100]] as $field=>$rule)if(!is_scalar($rule[0])||!preg_match('/^[1-9][0-9]*$/D',(string)$rule[0])||(float)$rule[0]>$rule[1])$this->fail('分页参数无效');
        $status=$this->request->get('status','');$project=$this->request->get('project','');$keyword=$this->request->get('keyword','');
        if(!is_scalar($status)||!in_array((string)$status,['','0','1','2','3'],true))$this->fail('状态参数无效');
        if(!is_scalar($project)||((string)$project!==''&&!preg_match('/^[1-9][0-9]{0,9}$/D',(string)$project)))$this->fail('项目参数无效');
        if(!is_string($keyword)||mb_strlen($keyword)>50)$this->fail('关键词最多50字');
        $q=Db::name('me_check_issue')->alias('i')->leftJoin('me_check_record r','r.id=i.check_id')->leftJoin('me_machine_list m','m.id=r.m_id')->leftJoin('me_check_list c','c.id=r.check_id')->leftJoin('team_list t','t.id=i.tid')->leftJoin('team_base p','p.id=t.project')->leftJoin('team_base l','l.id=m.line')->leftJoin('member_list reporter','reporter.id=i.mid')->leftJoin('admin_user owner','owner.id=i.owner')->leftJoin('me_check_issue_flow f','f.issue_id=i.id');
        if((string)$status!=='')$q->where('i.status',(int)$status);
        if((string)$project!=='')$q->where('t.project',(int)$project);
        if(trim($keyword)!=='')$q->whereLike('m.m_name|m.fixed_number|c.content|r.mark','%'.trim($keyword).'%');
        $total=(clone $q)->count();
        $rows=$q->field('i.id,i.status,i.check_time,i.mark feedback,i.update feedback_time,m.m_name device_name,m.fixed_number asset,c.content,c.standard,c.method,r.mark description,t.team team_name,p.title project_name,l.title line_name,reporter.ename reporter,owner.truename owner_name,f.confirmed_at')->order('i.check_time desc,i.id desc')->limit(((int)$page-1)*(int)$limit,(int)$limit)->select()->toArray();
        $cancelled=[];foreach($rows as $row)if((int)$row['status']===0)$cancelled[]=$row['id'];
        $original=[];if($cancelled)foreach(Db::name('me_check_issue_log')->whereIn('issue_id',$cancelled)->where('action','上报异常')->order('id')->field('issue_id,note')->select()->toArray() as $log)if(!isset($original[$log['issue_id']]))$original[$log['issue_id']]=$log['note'];
        foreach($rows as &$row){$row['id']=(int)$row['id'];$row['status']=(int)$row['status'];$row['status_name']=[0=>'已撤销',1=>'待处理',2=>'待确认',3=>'已关闭'][$row['status']]??'历史状态';if(isset($original[$row['id']]))$row['description']=$original[$row['id']];if(!(int)$row['feedback_time'])$row['owner_name']='';foreach(['check_time','feedback_time','confirmed_at'] as $key)$row[$key]=!empty($row[$key])?date('Y-m-d H:i',(int)$row[$key]):'';}
        unset($row);
        return json(['code'=>0,'data'=>['list'=>$rows,'total'=>$total]]);
    }
}
