<?php
declare (strict_types = 1);

namespace app\controller;

use app\BaseController;
use app\model\Account;
use think\facade\Cache;
use think\Exception;use think\facade\Db;
use think\App;
use think\facade\Validate;

class User extends BaseController
{
	private $token_time = 0;// token 有效时间
    public function __construct(App $app)
    {
       parent::__construct($app);
       $this->token_time= env("token.expire");
    }
    /**注册接口
    * @param string username 账户名称
    * @param string password 账户密码
    * @param string mobile 账户手机号
    * @param string source  来源默认register
	* @return \think\response\Json|void
	* @throws \think\db\exception\DataNotFoundException
	* @throws \think\db\exception\DbException
	* @throws \think\db\exception\ModelNotFoundException
	 */
    public function register()
    {
        $post =$this->request->only(["username"=>'',"password"=>"","mobile"=>"","source"=>"register"],"post","trim");

        $validate=Validate::rule([
    		'username|账户名称' => 'require|max:255',
    		'password|密码' => 'require|min:6|max:200',
    		'mobile|手机号' => 'require|number|length:11|mobile',
            ]);
    	if($validate->check($post)==false) return json_show(1004,$validate->getError());
        $source = isset($post['source']) ? trim($post['source']):"";
        $uiq = Db::table("sys_account")->where(["username"=>$post['username']])->find();
        if($uiq){
            return json_show(1002,"账户名已存在!");
        }
        $uiq = Db::table("sys_account")->where(["mobile"=>$post['mobile']])->find();
        if($uiq){
            return json_show(1002,"手机号已注册!");
        }
        Db::startTrans();
        try {
            $salt =makeSalt();
            $password = sha1($post['password'].$salt);
            $data = [
            	'username'=>$post['username'],
                "password"=>$password,
                "salt"=>$salt,
                "mobile"=>$post['mobile'],
                "source"=>$source,
                "status"=>1,
                "addtime"=>date("Y-m-d H:i:s"),
                "updatetime"=>date("Y-m-d H:i:s")
                ];
            $reuslt = Db::table('sys_account')->insert($data,true);
            if($reuslt){
                $data=[
                    "nickname"=>$post['username'],
                    "mobile"=>$post['mobile'],
                    "email"=>"",
                    "portrait"=>"",
                    "sex"=>1,
                    "post"=>"",
                    "department"=>"",
                    "account_id"=>$reuslt,
                    "status"=>1,
                    "addtime"=>date("Y-m-d H:i:s"),
                    "updatetime"=>date("Y-m-d H:i:s")
                ];
                $user=Db::table("sys_user")->insert($data,true);

                if($user){
                        Db::commit();
                        return json_show(0,"账户注册成功");
                }
            }
            Db::rollback();
            return json_show(1002,"账户注册失败");

        }catch (\Exception $e){
            Db::rollback();
            return json_show(1002,"账户注册失败".$e->getMessage());
        }


    }

    /**
     * 显示创建资源表单页.
     *
     * @return \think\Response
     */
    public function verify_code()
    {
        $post = $this->request->only("mobile","post");
        $code = make_verify();
        $mobile = isset($post['mobile'])&&checkMobile($post['mobile']) ? $post['mobile'] :"" ;
        if($mobile==""){
            return json_show(1001,"手机号格式不正确");
        }
        $mess =Db::name("send_message")->where(['mobile'=>$mobile,"status"=>0,"msg_type"=>1])->find();
        if($mess){
            if($mess['expire']>time()-60){
                return json_show(1001,"验证码发送中!");
            }
            $mess['status']=1;
            Db::name("send_message")->save($mess);
        }
//        $sendJson = sendMessage($mobile, $code);
//        $sendResult = json_decode($sendJson, TRUE);
//        if($sendResult['description'] != 'Success') {
//            return json_show(1002, '短信发送失败,请重试');
//        }

        $data=['code'=>$code,"mobile"=>$mobile,"status"=>0,"msg_type"=>1,"addtime"=>date("Y-m-d H:i:s"),
            "expire"=>time()];
        $result = Db::name("send_message")->insert($data);
        return $result ? json_show(0,"验证码已发送",["code"=>$code]): json_show(1001,"验证码发送失败");
    }

	/**
    * @param string username 账户
    * @param string password 密码
    * @param string plat_code 来源
	* @return \think\response\Json
	* @throws \Psr\SimpleCache\InvalidArgumentException
	* @throws \think\db\exception\DataNotFoundException
	* @throws \think\db\exception\DbException
	* @throws \think\db\exception\ModelNotFoundException
	* @throws \think\exception\DbException
	 */
    public function login()
    {
        $post = $this->request->only(["username"=>"","password"=>"","plat_code"=>""],"post","trim");
         $validate=Validate::rule([
    		'username|账户名称' => 'require|max:255',
    		'password|密码' => 'require|min:6|max:200',
            ]);
    	if($validate->check($post)==false) return json_show(1004,$validate->getError());

        $acc= Db::name("account")->where(['username'=>$post['username'],"is_del"=>Account::$account_del])->find();
        if($acc==false){
            return json_show(1003,'账户名不存在');
        }
        if($acc['status']==Account::$account_end){
            return json_show(1003,'账户名已禁用');
        }
        $sha1=sha1($post['password'].$acc['salt']);
        if($sha1!=$acc['password']){
            return json_show(1003,'账户或密码错误');
        }
        $token = makeToken($acc);
        if($token==""){
            return json_show(1003,'token生成失败');
        }
        if($post['plat_code']!=""){
        	$platinfo = Db::name("account_plat")->alias("a")
        	->leftJoin("platform b","a.plat_code=b.plat_code and b.is_del=0 and b.status=1")
        	->where(["a.status"=>1,"a.is_del"=>0,"a.plat_code"=>$post['plat_code'],"a.account_id"=>$acc['id']])
        	->findOrEmpty();
        	if(empty($platinfo)){
        		 return json_show(1003,'该系统账号为开通登录');
        	}
        }
		$user =Db::name("account")->alias("a")
		->leftJoin("user b","a.id=b.account_id and b.status=1")
		->field("a.id,a.username,a.mobile,a.source,b.nickname,b.sex,b.email,a.addtime,a.updatetime")
		->where(["a.id"=>$acc["id"]])
		->find();
        if($user==false){
        	 return json_show(1003,'用户信息不存在');
        }
		$usercompany = Db::name("account_company")->where(["account_id"=>$user['id'],"is_del"=>0,"status"=>1])
		->column("companyCode,companyName,company_type,is_main,status");
        $user['company_relaton'] = $usercompany;
        $cache = Cache::store("redis")->set("user:info:{$token}",$user ,$this->token_time);
        if($cache==false)  return json_show(1003,'token保存失败');
        $user['token']=$token;
        return json_show(0,"登录成功",$user);
    }

    /**
     *钉钉登录接口
     *
     * @param  \think\Request  $request
     * @param  string  $code
     * @return \think\Response
     */
    public function DingTalk()
    {
        $config= config("dingtalk");
        $dingtalk =new \DingTalk($config);
        $post = $this->request->only(["code"=>""],"post","trim");
        $code=isset($post["code"])&&$post["code"]!="" ? $post["code"]:"";
        if($code==""){
        	return json_show(106,"参数code不能为空");
        }
        $li = $dingtalk->getUserByCode($code);
        if($li['errcode']!=0){
            return  json_show(107,"授权失败",$li);
        }
        $list = $dingtalk->getUser($li['userid']);
        if($list['errcode']!=0){
            return  json_show(107,"授权失败",$list);
        }
        $userinfo = Db::name("account")->alias("a")
		->leftJoin("user b","a.id=b.account_id and b.status=1")
		->field("a.id,a.username,a.mobile,a.source,b.nickname,b.sex,b.email,a.addtime,a.updatetime")
		->where(['DTuserid'=>$list['userid'],"unionid"=>$list['unionid'],"a.is_del"=>0])
		->findOrEmpty();
        if(empty($userinfo)){
        	Db::startTrans();
        	try{
        		$accountid = $this->DingTalkRegister($list);
        		Db::commit();
        	}catch (\Exception $e){
				Db::rollback();
				return json_show(106,$e->getMessage());
        	}
        	$userinfo = Db::name("account")->alias("a")
			->leftJoin("user b","a.id=b.account_id and b.status=1")
			->field("a.id,a.username,a.mobile,a.source,b.nickname,b.sex,b.email,a.addtime,a.updatetime")
			->where(["a.id"=>$accountid,"a.is_del"=>0])
			->findOrEmpty();
        }
		 $token = makeToken($userinfo);
        $usercompany = Db::name("account_company")->where(["account_id"=>$userinfo['id'],"is_del"=>0,"status"=>1])
		->column("companyCode,companyName,company_type,is_main,status");
        $user['company_relaton'] = $usercompany;
        $cache = Cache::store("redis")->set("user:info:{$token}",$user ,$this->token_time);
        if($cache==false)  return json_show(1003,'token保存失败');
        $user['token']=$token;
        return json_show(0,"授权成功",$userinfo);
    }
	/**
	* @param $Dingtalinfo
	 * @return int|string
	* @throws \think\Exception
	 */
   private function DingTalkRegister($Dingtalinfo){
    	  $salt=makeSalt();
          $data=[
               "username"=>$Dingtalinfo['mobile'],
               "password"=>sha1("dingding123".$salt),
               "mobile"=>$Dingtalinfo['mobile'],
               "salt"=>$salt,
               "status"=>1,
               "source"=>"dingtalk",
               "addtime"=>date("Y-m-d H:i:s"),
               "updatetime"=>date("Y-m-d H:i:s")
           ];
           $account = Db::table("sys_account")->insert($data,true);
           if($account<=0)throw new Exception("账户创建失败");

	   $verify = Db::name("user")->where("mobile","=",$Dingtalinfo['mobile'])->findOrEmpty();
       if(!empty($verify)){
           $verify['unionid']=$Dingtalinfo['unionid'];
           $verify['openId']=$Dingtalinfo['openId'];
           $verify['DTuserid']=$Dingtalinfo['userid'];
           $verify['mobile']=$Dingtalinfo['mobile'];
           $verify['account_id']=$account;
           isset($verify['portrait'])??$verify['portrait']=$Dingtalinfo['avatar'];
           isset($verify['email'])??$verify['email']=$Dingtalinfo['email'];
           $verify['updatetime']=date("Y-m-d H:i:s");
           $user =Db::name("user")->save($verify);
           if($user==false) throw new Exception("用户信息创建失败");
           $uid = $verify["id"];
       }else{
          $data=[
              "nickname"=>$Dingtalinfo['name'],
              "mobile"=>$Dingtalinfo['mobile'],
              "email"=>$Dingtalinfo['email'],
              "portrait"=>$Dingtalinfo['avatar'],
              "sex"=>1,
              "post"=>"",
              "unionid"=>$Dingtalinfo['unionid'],
              "openId"=>$Dingtalinfo['openId'],
              "DTuserid"=>$Dingtalinfo['userid'],
              "department"=>"",
              "status"=>1,
              "account_id"=>$account,
              "addtime"=>date("Y-m-d H:i:s"),
              "updatetime"=>date("Y-m-d H:i:s")
          ];
           $uid =Db::name("user")->insert($data,true);
       }
       if($uid==false) throw new Exception("用户信息创建失败");
       return $account;
   }

    /**
	* @return \think\response\Json
	* @throws \think\db\exception\DataNotFoundException
	* @throws \think\db\exception\DbException
	* @throws \think\db\exception\ModelNotFoundException
	* @throws \think\exception\DbException
	 */
   public function  verify_token(){
       $post=$this->request->only(["token"=>''],"post");
        $validate=Validate::rule([
    		'token' => 'require',
            ]);
    	if($validate->check($post)==false) return json_show(1004,$validate->getError());
        $getToken=checkToken($post['token'],$this->token_time);
      return $getToken ==false?json_show(104,"token失效") :json_show(0,"获取成功",$getToken);
   }

    /**
     * @return \think\response\Json|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
   public function reset_password_mobile(){
       $post=$this->request->post();
       $mobile = isset($post['mobile'])? trim($post['mobile']):"";
       if($mobile==""){
           return json_show(1001,"手机号不能为空");
       }
       if(checkMobile($mobile)==false){
           return json_show(1002,"手机号格式不正确!");
       }
       $code = isset($post['code'])? trim($post['code']):"";
       if($code==""){
           return json_show(1001,"验证码不能为空");
       }
       $username = isset($post['username'])?trim($post['username']):"";
       if($username==""){
           return json_show(1001,"参数username 不能为空");
       }
       $account = Db::name("account")->where("username","=",$username)->find();
       if($account['mobile']!=$mobile){
           return json_show(1004,"账户关联手机号不正确");
       }
       $password = isset($post['password'])?trim($post['password']):"";
       if($password==""){
           return json_show(1001,"新密码不能为空");
       }

       if(sha1($password.$account['salt'])==$account['password']){
           return json_show(1001,"新密码不能与原密码相同");
       }
       $codeinfo = Db::name("send_message")->where(["mobile"=>$mobile,"status"=>0,"msg_type"=>1])->find();

       if($code!=$codeinfo['code']){
           return json_show(1003,"验证码错误");
       }
       $codeinfo['status']=1;
       Db::name("send_message")->save($codeinfo);
        $account['salt']=makeSalt();
        $account['updatetime']=date("Y-m-d");
        $account['is_pass']=1;
        $account['password']=sha1($password.$account['salt']);
        $result=Db::name("account")->save($account);
        return $result?json_show(0,"密码修改成功"):json_show(1003,"密码修改失败");
   }
}