<?php
namespace app\adminVue\controller;
use think\facade\Db;

class V2MobileMenu extends V2Base
{
    private function requireManager() {
        if ((int)$this->actor['rightid']<=98) $this->fail('仅rightid>98的账号可以管理小程序菜单',403);
    }
    private function version($row) { return hash_hmac('sha256',json_encode($row),$this->requestToken()); }
    private function number($value,$min=1,$max=2147483647) {
        if ((!is_int($value)&&!is_string($value))||!preg_match('/^(0|[1-9][0-9]{0,9})$/D',(string)$value)||(float)$value<$min||(float)$value>$max) $this->fail('数字参数不正确');
        return (int)$value;
    }
    private function ids($raw,$max,$allowed=null) {
        if (!is_array($raw)||count($raw)>$max) $this->fail('可见范围参数不正确');
        $ids=[];foreach($raw as $value)$ids[]=$this->number($value);
        if(count(array_unique($ids))!==count($ids)||($allowed!==null&&array_diff($ids,$allowed)))$this->fail('可见范围包含无效或重复选项');
        sort($ids,SORT_NUMERIC);return $ids;
    }
    public function index() {
        $this->requireManager();$list=[];
        foreach(Db::name('admin_menus_wx')->order('sort,id')->select()->toArray() as $row) {
            $list[]=['id'=>(int)$row['id'],'title'=>$row['title'],'action'=>$row['action'],'route'=>$row['route'],
                'icon'=>$row['icon'],'iconColor'=>$row['icon_color'],'sort'=>(int)$row['sort'],'status'=>(int)$row['status']===1,
                'userTypes'=>array_values(array_filter(array_map('intval',explode(',',$row['user_types'])))),
                'departmentIds'=>array_values(array_filter(array_map('intval',explode(',',$row['department_ids'])))),'version'=>$this->version($row)];
        }
        $departments=Db::name('admin_org')->where('mid',0)->field('id,title')->order('id')->select()->toArray();
        foreach($departments as &$d)$d['id']=(int)$d['id'];unset($d);
        return json(['code'=>0,'msg'=>'','data'=>['list'=>$list,'departments'=>$departments,
            'userTypes'=>[['id'=>1,'title'=>'现场员工'],['id'=>2,'title'=>'双身份人员'],['id'=>3,'title'=>'管理人员']]]]);
    }
    public function save() {
        $this->requireManager();$id=$this->number($this->request->post('id'));$title=$this->request->post('title');$version=$this->request->post('version');
        if(!is_string($title)||trim($title)===''||mb_strlen(trim($title))>60||preg_match('/[<>\x00-\x1F]/u',$title))$this->fail('菜单名称须为1至60个字符');
        if(!is_string($version)||!preg_match('/^[a-f0-9]{64}$/D',$version))$this->fail('请重新打开菜单设置');
        $types=$this->ids($this->request->post('userTypes'),3,[1,2,3]);
        if(!$types)$this->fail('请至少选择一种人员分类');
        $departments=$this->ids($this->request->post('departmentIds'),100);
        $departmentText=implode(',',$departments);if(strlen($departmentText)>500)$this->fail('选择部门过多');
        $sort=$this->number($this->request->post('sort'),0,9999);$status=$this->request->post('status');
        if(!is_bool($status))$this->fail('菜单启用状态不正确');
        $config=config('database.connections.'.config('database.default'));$prefix=$config['prefix'];
        if(!preg_match('/^[a-zA-Z0-9_]*$/D',$prefix))$this->fail('数据库配置无效',500);
        $pdo=Db::connect()->getConnection()->getPdo();$locked=false;
        try {
            $pdo->exec('LOCK TABLES '.$prefix.'admin_menus_wx WRITE, '.$prefix.'admin_user READ, '.$prefix.'admin_org READ');$locked=true;
            if((int)Db::name('admin_user')->where(['id'=>$this->actor['id'],'status'=>1])->value('rightid')<=98)$this->fail('设置权限已变化，请刷新',403);
            $row=Db::name('admin_menus_wx')->where('id',$id)->find();if(!$row)$this->fail('菜单不存在',404);
            if(!hash_equals($this->version($row),$version))$this->fail('菜单配置已变化，请重新打开编辑',409);
            if($departments&&Db::name('admin_org')->where('mid',0)->whereIn('id',$departments)->count()!==count($departments))$this->fail('所选部门已不存在，请重新选择');
            Db::name('admin_menus_wx')->where('id',$id)->update(['title'=>trim($title),'user_types'=>implode(',',$types),'department_ids'=>$departmentText,'sort'=>$sort,'status'=>$status?1:0]);
        } finally {if($locked)$pdo->exec('UNLOCK TABLES');}
        return json(['code'=>0,'msg'=>'小程序菜单已保存','data'=>null]);
    }
}
