<?php
namespace app\common\validate;
use app\common\model\UserInfo as UserInfoModel;
use app\common\model\Company as CompanyModel;
use think\Validate;

class RealName extends Validate
{
    protected $rule =   [
        'uid'          => 'require',
        'name'         => 'require',
        'id_number'    => 'require|checkIdNumber',
        'contacts'     => 'require',
        'mobile'       => 'require',
        'area'         => 'require|array',
        'address'      => 'require',
        'img1'         => 'checkImg1',
        'img2'         => 'checkImg2',
        'img3'         => 'checkImg3',
        'img4'         => 'checkImg4',
        'img5'         => 'checkImg5',
    ];
    protected $message  =   [
        'uid.require'                       => '请先登录', 
        'name.require'                      => '名称不能为空', 
        'id_number.require'                 => '身份证号或企业统一社会信用代码不能为空',  
        'id_number.unique'                  => '身份证号或企业统一社会信用代码已存在', 
        'contacts.require'                  => '请输入联系人',
        'mobile.require'                    => '请输入联系人手机号',
        'area.require'                      => '请选择地区',
        'array.require'                     => '请选择地区',
        'address.require'                   => '请输入联系地址',
    ];
    
    protected $scene = [
        'user'             =>  ['uid','name','id_number','img1','img2'],
        'company'          =>  ['uid','name','id_number','contacts','mobile','area','address','img1','img2','img3','img5'],
        'other'          =>  ['uid','name','id_number','contacts','mobile','area','address','img1','img2','img3','img5'],
    ];
    protected function checkImg1($value,$rule,$data=[])
    {
        switch ($data['id_type']) {
            case 0:
                return empty($value)?'请上传身份证人像面':true;
            case 1:
            case 2:
                if (in_array('id_card_f',config('xy_company.attestation_ms')))
                    return empty($value)?'请上传身份证人像面':true;
                return true;
            default:
                return '身份类型不正确';
        }
    }
    protected function checkImg2($value,$rule,$data=[])
    {
        switch ($data['id_type']) {
            case 0:
                return empty($value)?'请上传身份证人像面':true;
            case 1:
            case 2:
                if (in_array('id_card_e',config('xy_company.attestation_ms')))
                    return empty($value)?'请上传身份证国徽面':true;
                return true;
            default:
                return '身份类型不正确';
        }
    }
    protected function checkImg3($value,$rule,$data=[])
    {
        if (in_array('license',config('xy_company.attestation_ms')))
            return !empty($value);
        return true;
    }
    protected function checkImg4($value,$rule,$data=[])
    {
        if (in_array('supplement',config('xy_company.attestation_ms')))
            return !empty($value);
        return true;
    }
    protected function checkImg5($value,$rule,$data=[])
    {
        if (in_array('loc',config('xy_company.attestation_ms')))
            return !empty($value);
        return true;
    }
    protected function checkIdNumber($value,$rule,$data=[])
    {
        switch ($data['id_type']) {
            case 0:
                if (UserInfoModel::where(['idcard'=>$value])->count())
                    return '身份证号已存在';
                return $this->is_idcard($value,$rule,$data=[]);
            case 1:
            case 2:
                if (CompanyModel::where(['uscc'=>$value])->count())
                    return '统一社会信用代码已存在';
                return $this->checkUscc($value,$rule,$data=[]);
            default:
                return '身份类型不正确';
        }
    }
    protected function checkUscc($str,$rule,$data=[]){
        $one = '159Y';//第一位可以出现的字符
        $two = '12391';//第二位可以出现的字符
        $str = strtoupper($str);
        if (!strstr($one, $str['1']) || !strstr($two, $str['2']) && !empty($array[substr($str, 2, 6)])) {
            return '企业统一社会信用代码不正确';
        }
        //加权因子数值
        $wi = array(1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28);
        $str_organization = substr($str, 0, 17);
        $num = 0;
        for ($i = 0; $i < 17; $i++) {
            if(isset($str_organization[$i])&&isset($wi[$i])){
                $num += $this->transformation($str_organization[$i]) * $wi[$i];
            }
        }
        switch ($num % 31) {
            case '0':
                $result = 0;
                break;
            default:
                $result = 31 - $num % 31;
                break;
        }
        if (substr($str, -1, 1) == $this->transformation($result, true)) {
            return true;
        } else {
            return '企业统一社会信用代码不正确';
        }
    }
    protected function transformation($num, $status = false){
        //值转换
        $list = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'J' => 18, 'K' => 19, 'L' => 20, 'M' => 21, 'N' => 22, 'P' => 23, 'Q' => 24, 'R' => 25, 'T' => 26, 'U' => 27, 'W' => 28, 'X' => 29, 'Y' => 30);
        if ($status == true) {
            $list = array_flip($list);
        }
        return $list[$num];
    }
    /**
     * 身份证号验证
     * @param $id
     * @return bool
     */
    protected function is_idcard($id,$rule,$data=[])
    {
        $id = strtoupper($id);
        $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
        $arr_split = array();
        if(!preg_match($regx, $id))
        {
            return '身份证号不正确';
        }
        if(15==strlen($id)) //检查15位
        {
            $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";

            @preg_match($regx, $id, $arr_split);
            //检查生日日期是否正确
            $dtm_birth = "19".$arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
            if(!strtotime($dtm_birth))
            {
                return '身份证号不正确';
            } else {
                return '身份证号不正确';
            }
        }
        else      //检查18位
        {
            $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
            @preg_match($regx, $id, $arr_split);
            $dtm_birth = $arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
            if(!strtotime($dtm_birth)) //检查生日日期是否正确
            {
                return true;
            }
            else
            {
                //检验18位身份证的校验码是否正确。
                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
                $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                $sign = 0;
                for ( $i = 0; $i < 17; $i++ )
                {
                    $b = (int) $id[$i];
                    $w = $arr_int[$i];
                    $sign += $b * $w;
                }
                $n = $sign % 11;
                $val_num = $arr_ch[$n];
                if ($val_num != substr($id,17, 1))
                {
                    return '身份证号不正确';
                }
                else
                {
                    return true;
                }
            }
        }

    }
}