<?php
namespace app\bsadmin\controller;
use think\facade\View;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Validate;
use app\bsadmin\model\Config as ConfigModel;
use app\common\model\StatusAlias as StatusAliasModel;
use app\common\model\Article as ArticleModel;
use app\common\model\ArticleContent as ArticleContentModel;
use app\common\model\ArticleCate as ArticleCateModel;
use app\common\model\Vip as VipModel;
use app\common\model\VipValueAdded as VipValueAddedModel;


class Setting extends Base
{
    public $payCtype=['alipay','wxpay','applepay','xy_toutiaopay','xy_baidupay'];
    public $loginCtype=['qqlogin','wxlogin'];
    public $basicCtype=['basic','web','sms','xy_map','xy_seo','xy_xycms'];
    public $upconfigCtype=['xy_oss','xy_upconfig'];
    public $captchaCtype=['captcha','xy_geetest','xy_vaptcha','xy_tencent_tsec'];
    public $miniprogramCtype=['xy_wechatminiprogram','xy_toutiao','xy_alipay_mp','xy_baidump'];
    public $imCtype=['xy_xycms','xy_im_setting'];
    public function basic()
    {
        if (request()->isAjax()) {
            $G=request()->get();
            $ctype='';
            if(!empty($G['ctype']))$ctype=$G['ctype'];
            return $this->updateConfigAjax($ctype);
        }
        $this->getAgreement();
        $Data=ConfigModel::getList([['ctype','in',$this->basicCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','basic');
    	return View::fetch('website');
    }
    public function web()
    {
        $this->getAgreement();
        $Data=ConfigModel::getList([['ctype','in',$this->basicCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','web');
    	return View::fetch('website');
    }
    public function sms()
    {
        $this->getAgreement();
        $Data=ConfigModel::getList([['ctype','in',$this->basicCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','sms');
        return View::fetch('website');
    }
    public function map()
    {
        $this->getAgreement();
        $Data=ConfigModel::getList([['ctype','in',$this->basicCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_map');
        return View::fetch('website');
    }
    public function seo()
    {
        $this->getAgreement();
        $Data=ConfigModel::getList([['ctype','in',$this->basicCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_seo');
        return View::fetch('website');
    }
    public function xycms()
    {
        $this->getAgreement();
        $Data=ConfigModel::getList([['ctype','in',$this->basicCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_xycms');
        return View::fetch('website');
    }
    public function getAgreement()
    {
        $ArticleCateModel=ArticleCateModel::where(['alias'=>'agreement'])->find();
        $user_agreement=ArticleModel::alias('article')->where(['article.alias'=>'user_agreement'])
            ->join('article_content content','content.tid = article.id','LEFT')->field('article.*,content.content')
            ->withAttr('start_time',function($v,$d){
                return $v?date('Y-m-d',$v):'';
            })
            ->withAttr('end_time',function($v,$d){
                return $v?date('Y-m-d',$v):'';
            })->find();
        if (!$user_agreement) {
            if ($ArticleCateModel) {
                $ArticleModel=new ArticleModel;
                $ArticleModel->title    = '用户协议';
                $ArticleModel->alias    = 'user_agreement';
                $ArticleModel->cid      = $ArticleCateModel->id;
                $ArticleModel->status   = 1;
                $ArticleContentModel=new ArticleContentModel;
                $ArticleContentModel->content='用户协议';
                // 启动事务
                Db::startTrans();
                try {
                    $ArticleModel->save();
                    $ArticleContentModel->tid=$ArticleModel->id;
                    $ArticleContentModel->save();
                    // 提交事务
                    Db::commit();
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                }
                $user_agreement=ArticleModel::alias('article')->where(['article.alias'=>'user_agreement'])
                    ->join('article_content content','content.tid = article.id','LEFT')->field('article.*,content.content')
                    ->withAttr('start_time',function($v,$d){
                        return $v?date('Y-m-d',$v):'';
                    })
                    ->withAttr('end_time',function($v,$d){
                        return $v?date('Y-m-d',$v):'';
                    })->find();
            }
        }
        View::assign('user_agreement',$user_agreement);
        $privacy=ArticleModel::alias('article')->where(['article.alias'=>'privacy'])
            ->join('article_content content','content.tid = article.id','LEFT')->field('article.*,content.content')
            ->withAttr('start_time',function($v,$d){
                return $v?date('Y-m-d',$v):'';
            })
            ->withAttr('end_time',function($v,$d){
                return $v?date('Y-m-d',$v):'';
            })->find();
        if (!$privacy) {
            if ($ArticleCateModel) {
                $ArticleModel=new ArticleModel;
                $ArticleModel->title    = '隐私政策';
                $ArticleModel->alias    = 'privacy';
                $ArticleModel->cid      = $ArticleCateModel->id;
                $ArticleModel->status   = 1;
                $ArticleContentModel=new ArticleContentModel;
                $ArticleContentModel->content='隐私政策';
                // 启动事务
                Db::startTrans();
                try {
                    $ArticleModel->save();
                    $ArticleContentModel->tid=$ArticleModel->id;
                    $ArticleContentModel->save();
                    // 提交事务
                    Db::commit();
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                }
                $privacy=ArticleModel::alias('article')->where(['article.alias'=>'privacy'])
                    ->join('article_content content','content.tid = article.id','LEFT')->field('article.*,content.content')
                    ->withAttr('start_time',function($v,$d){
                        return $v?date('Y-m-d',$v):'';
                    })
                    ->withAttr('end_time',function($v,$d){
                        return $v?date('Y-m-d',$v):'';
                    })->find();
            }
        }
        View::assign('privacy',$privacy);
    }
    public function alipay()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->payCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','alipay');
        return View::fetch('pay');
    }
    public function wxpay()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->payCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','wxpay');
        return View::fetch('pay');
    }
    public function applepay()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->payCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','applepay');
        return View::fetch('pay');
    }
    public function toutiaopay()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->payCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_toutiaopay');
        return View::fetch('pay');
    }
    public function baidupay()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->payCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_baidupay');
        return View::fetch('pay');
    }
    public function qqlogin()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->loginCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','qqlogin');
        return View::fetch('login');
    }
    public function wxlogin()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->loginCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','wxlogin');
        return View::fetch('login');
    }
    public function email()
    {
        $Data=ConfigModel::getList([['ctype','in',['xycms_message','xy_getui','xy_email']]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_email');
        return View::fetch('message');
    }
    public function getui()
    {
        $Data=ConfigModel::getList([['ctype','in',['xycms_message','xy_getui','xy_email']]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_getui');
        return View::fetch('message');
    }
    public function upconfig()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->upconfigCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_upconfig');
        return View::fetch('upconfig');
    }
    public function oss()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->upconfigCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_oss');
        return View::fetch('upconfig');
    }
    public function wechatMp()
    {
        $Data=ConfigModel::getList(['ctype'=>'xy_wechat_mp']);
        View::assign('Data',$Data);
        View::assign('ctype','xy_wechat_mp');
        return View::fetch('basic');
    }
    public function wechatminiprogram()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->miniprogramCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_wechatminiprogram');
        return View::fetch('miniprogram');
    }
    public function toutiao()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->miniprogramCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_toutiao');
        return View::fetch('miniprogram');
    }
    public function alipayMp()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->miniprogramCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_alipay_mp');
        return View::fetch('miniprogram');
    }
    public function baidump()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->miniprogramCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_baidump');
        return View::fetch('miniprogram');
    }
    public function im_setting()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->imCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_im_setting');
        return View::fetch('im');
    }
    public function captcha()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->captchaCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','captcha');
        return View::fetch('captcha');
    }
    public function geetest()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->captchaCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_geetest');
        return View::fetch('captcha');
    }
    public function vaptcha()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->captchaCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_vaptcha');
        return View::fetch('captcha');
    }
    public function tencentTSec()
    {
        $Data=ConfigModel::getList([['ctype','in',$this->captchaCtype]]);
        View::assign('Data',$Data);
        View::assign('ctype','xy_tencent_tsec');
        return View::fetch('captcha');
    }
    public function default_avatar()
    {
        $Data=ConfigModel::getList(['ctype'=>'xy_default_avatar']);
        View::assign('Data',$Data);
        View::assign('ctype','xy_default_avatar');
        return View::fetch('basic');
    }
    public function crm()
    {
        $Data=ConfigModel::getList(['ctype'=>'xy_crm']);
        View::assign('Data',$Data);
        View::assign('ctype','xy_crm');
        return View::fetch('basic');
    }
    public function sub_website()
    {
        $Data=ConfigModel::getList(['ctype'=>'xy_sub_website']);
        View::assign('Data',$Data);
        View::assign('ctype','xy_sub_website');
        return View::fetch('basic');
    }
    public function getApplePayProductList()
    {
        $OrderType=StatusAliasModel::where(['alias'=>'vip/type'])->field('value,title')->select()->toArray();
        foreach ($OrderType as $k => $v) {
            switch ($v['value']) {
                case 1:
                $OrderType[$k]['data']=VipModel::where('price','>',0)->field('id,title,status,price')->select()->toArray();
                break;
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                $OrderType[$k]['data']=VipValueAddedModel::where(['type'=>$v['value']])->field('id,title,status,price')->select()->toArray();
                break;
                case 10:
                $OrderType[$k]['data']=[
                ['id'=>6,'title'=>'60积分','price'=>'6'],
                ['id'=>30,'title'=>'300积分','price'=>'30'],
                ['id'=>68,'title'=>'680积分','price'=>'68'],
                ['id'=>98,'title'=>'980积分','price'=>'98'],
                ['id'=>128,'title'=>'1280积分','price'=>'128'],
                ['id'=>198,'title'=>'1980积分','price'=>'198'],
                ['id'=>328,'title'=>'3280积分','price'=>'328'],
                ['id'=>648,'title'=>'6480积分','price'=>'648']
                ];
                break;
            }
        }
        return $this->ajaxReturn('已保存',0,$OrderType);
    }
    public function add()
    {
        if (request()->isAjax()) {
            $D=request()->post();
            $rule =   [
                'ctype'         => 'require',
                'title'         => 'require|max:120',
                'key'           => 'require|unique:config,ctype^key',
                'type'          => 'require',
            ];
            $msg  =   [
                'ctype.require'         => '请选择配置项', 
                'title.require'         => '请输入配置名称', 
                'title.max'             => '配置名称不能超过120个字符', 
                'key.require'           => '请输入配置名', 
                'key.unique'            => '配置名已存在', 
                'type.require'          => '请选择输入类型', 
            ];
            switch ($D['type']) {
                case 'radio':
                case 'select':
                    $rule['options']='require|array';
                    $msg['options.require']='候选项不能为空';
                    $msg['options.array']='候选项不能为空';
                    $rule['value']='require';
                    $msg['value.require']='默认值不能为空';
                    break;
                case 'checkbox':
                    $rule['options']='require|array';
                    $msg['options.require']='候选项不能为空';
                    $msg['options.array']='候选项不能为空';

                    $rule['arr_value']='require|array';
                    $msg['arr_value.require']='默认值不能为空';
                    $msg['arr_value.array']='默认值不能为空';
                    break;
                case 'array':
                    $rule['array']='require|array';
                    $msg['array.require']='默认值不能为空';
                    $msg['array.array']='默认值不能为空';
                    break;
                default:
                    // $rule['value']='require';
                    // $msg['value.require']='默认值不能为空';
                    break;
            }
            $Validate=Validate::rule($rule)->message($msg);
            $result = $Validate->check($D);
            if(!$result){return $this->ajaxReturn($Validate->getError(),-100);}

            //排除系统内定配置项
            $sysArr=['app','cache','cookie','database','log','session','filesystem','template','trace','paginate','auth','console','middleware','systemset','ueditor','worker','worker_server','view'];
            if(in_array($D['ctype'], $sysArr)){
                return $this->ajaxReturn('该配置名为系统配置，不可使用',-100);
            }
            $configModel=new ConfigModel;
            $configModel->ctype         =  $D['ctype'];  
            $configModel->title         =  $D['title'];  
            $configModel->key           =  $D['key'];  
            $configModel->type          =  $D['type'];  
            $configModel->tips          =  $D['tips'];  
            $configModel->value         =  $D['value'];  
            switch ($D['type']) {
                case 'radio':
                case 'select':
                    $configModel->options       =  json_encode($D['options'],JSON_UNESCAPED_UNICODE);
                    break;
                case 'checkbox':
                    $configModel->options       =  json_encode($D['options'],JSON_UNESCAPED_UNICODE);
                    $configModel->value=implode(',',$D['arr_value']);
                    break;
                case 'array':
                    $array=[];
                    foreach ($D['array'] as $k => $v) {
                        if (is_numeric($v)) {
                            $array[]=(float) $v;
                        }else{
                            $array[]=$v;
                        }
                    }
                    $configModel->value=json_encode($array);
                    break;
            }
            if($configModel->save()){
                if($this->updateConfig($D['ctype'])){
                    return $this->ajaxReturn('保存成功');
                }else{
                    return $this->ajaxReturn('保存成功，更新配置文件失败，请手动更新',-100);
                }
            }else{
                return $this->ajaxReturn('保存失败，请重试',-100);
            }
        }else{
            return View::fetch();
        }
    }
    public function edit($id)
    {
        if (request()->isAjax()) {
            $D=request()->post();
            $rule =   [
                'ctype'         => 'require',
                'title'         => 'require|max:120',
                'key'           => 'require|unique:config,ctype^key',
                'type'          => 'require',
            ];
            $msg  =   [
                'ctype.require'         => '请选择配置项', 
                'title.require'         => '请输入配置名称', 
                'title.max'             => '配置名称不能超过120个字符', 
                'key.require'           => '请输入配置名', 
                'key.unique'            => '配置名已存在', 
                'type.require'          => '请选择输入类型', 
            ];
            switch ($D['type']) {
                case 'radio':
                case 'select':
                    $rule['options']='require|array';
                    $msg['options.require']='候选项不能为空';
                    $msg['options.array']='候选项不能为空';
                    $rule['value']='require';
                    $msg['value.require']='默认值不能为空';
                    break;
                case 'checkbox':
                    $rule['options']='require|array';
                    $msg['options.require']='候选项不能为空';
                    $msg['options.array']='候选项不能为空';

                    $rule['arr_value']='require|array';
                    $msg['arr_value.require']='默认值不能为空';
                    $msg['arr_value.array']='默认值不能为空';
                    break;
                case 'array':
                    $rule['array']='require|array';
                    $msg['array.require']='默认值不能为空';
                    $msg['array.array']='默认值不能为空';
                    break;
                default:
                    // $rule['value']='require';
                    // $msg['value.require']='默认值不能为空';
                    break;
            }
            $Validate=Validate::rule($rule)->message($msg);
            $result = $Validate->check($D);
            if(!$result){return $this->ajaxReturn($Validate->getError(),-100);}

            //排除系统内定配置项
            $sysArr=['app','cache','cookie','database','log','session','filesystem','template','trace','paginate','auth','console','middleware','systemset','ueditor','worker','worker_server','view'];
            if(in_array($D['ctype'], $sysArr)){
                return $this->ajaxReturn('该配置名为系统配置，不可使用',-100);
            }
            $configModel=ConfigModel::where(['id'=>$D['id']])->find();
            $configModel->ctype         =  $D['ctype'];  
            $configModel->title         =  $D['title'];  
            $configModel->key           =  $D['key'];  
            $configModel->type          =  $D['type'];  
            $configModel->tips          =  $D['tips'];  
            $configModel->value         =  $D['value'];  
            switch ($D['type']) {
                case 'radio':
                case 'select':
                    $configModel->options       =  json_encode($D['options'],JSON_UNESCAPED_UNICODE);
                    break;
                case 'checkbox':
                    $configModel->options       =  json_encode($D['options'],JSON_UNESCAPED_UNICODE);
                    $configModel->value=implode(',',$D['arr_value']);
                    break;
                case 'array':
                    $array=[];
                    foreach ($D['array'] as $k => $v) {
                        if (is_numeric($v)) {
                            $array[]=(float) $v;
                        }else{
                            $array[]=$v;
                        }
                    }
                    $configModel->value=json_encode($array);
                    break;
            }
            if($configModel->save()){
                if($this->updateConfig($D['ctype'])){
                    return $this->ajaxReturn('保存成功');
                }else{
                    return $this->ajaxReturn('保存成功，更新配置文件失败，请手动更新',-100);
                }
            }else{
                return $this->ajaxReturn('保存失败，请重试',-100);
            }
        }else{
            $ConfigModel=ConfigModel::where(['id'=>$id])->find();
            if ($ConfigModel) {
                if($ConfigModel->options){
                    $options=json_decode($ConfigModel->options,true);
                    if(!empty($options))
                    $ConfigModel->options=arrtoint($options,'value');
                }else{
                    $ConfigModel->options=[];
                }
                if (is_numeric($ConfigModel->value)) {
                    $ConfigModel->value=(float) $ConfigModel->value;
                }
                switch ($ConfigModel->type) {
                    case 'radio':
                    case 'select':
                        break;
                    case 'checkbox':
                        $ConfigModel->arr_value=explode(',',$ConfigModel->value);
                        $ConfigModel->value='';
                        break;
                    case 'array':
                        $ConfigModel->array=json_decode($ConfigModel->value,true);
                        $ConfigModel->value='';
                        break;
                }
            }
            View::assign('Find',$ConfigModel);
            return View::fetch('add');
        }
    }
    public function del($id)
    {
        $ctype='';
        $ConfigModel=ConfigModel::where(['id'=>$id])->find();
        if(ConfigModel::where(['ctype'=>$ConfigModel->ctype,'key'=>$ConfigModel->key])->count()<=1){
            return $this->ajaxReturn('最后一个类型配置不能删除',-100);
        }
        $ctype=$ConfigModel->ctype;
        if($ConfigModel->delete()){
            if($this->updateConfig($ctype)){
                return $this->ajaxReturn('已保存');
            }else{
                return $this->ajaxReturn('已删除，更新配置文件失败，请手动更新',-100);
            }
        }else{
            return $this->ajaxReturn('删除失败，请重试',-200);
        }
    }
    /**
     * [editConfig 编辑配置项]
     * @param  array  $D [description]
     * @return [type]    [description]
     */
    public function editConfig()
    {
        $D=request()->post();
        $configModel=ConfigModel::where(['id'=>$D['id']])->find();
        $configModel->value=$D['value'];
        if($configModel->type == 'checkbox'){
            $configModel->value=implode(',',$D['value']);
        }elseif ($configModel->type == 'array') {
            $array=[];
            foreach ($D['value'] as $k => $v) {
                if (is_numeric($v)) {
                    $array[]=(float) $v;
                }else{
                    $array[]=$v;
                }
            }
            $configModel->value=json_encode($array);
        }else{
            $configModel->value=$D['value'];
        }
        if ($configModel->save()) {
            if($this->updateConfig($configModel->ctype)){
                return $this->ajaxReturn('已保存');
            }else{
                return $this->ajaxReturn('保存成功，更新配置文件失败，请手动更新',-100);
            }
        }else{
            return $this->ajaxReturn('不存在该配置',-100);
        }
    }
    public function updateConfigAjax($ctype='')
    {
        if($ctype){
            $this->updateConfig($ctype);
        }else{
            $ConfigArr=ConfigModel::column('ctype');
            foreach ($ConfigArr as $k => $v) {
                $this->updateConfig($v);
            }
        }
        return $this->ajaxReturn();
    }
    /**
     * [updateConfig 更新配置]
     * @param  string $ctype [description]
     * @return [type]        [description]
     */
    protected function updateConfig($ctype='basic')
    {
        try {
            //读取配置
            $_CONFIG_=ConfigModel::where(['ctype'=>$ctype])->field('title,type,key,value')->select();
            //组装配置
            $configWrite="<?php\nreturn [\n";
            $ConfigArr=[];
            foreach ($_CONFIG_ as $k => $v) {
                if ($v['type']=='checkbox') {
                    $value_arr=explode(',',$v['value']);
                    $configWrite.="//".$v['title']."\n'".$v['key']."'=>[";
                    foreach ($value_arr as $ke => $va) {
                        if (is_numeric($va)) {
                            //组装配置
                            $configWrite.=$va.",";
                        }else{
                            //组装配置
                            $configWrite.="'".$va."',";
                        }
                    }
                    Cache::set($ctype.'.'.$v['key'],$value_arr);
                    $ConfigArr[$v['key']]=$value_arr;
                    $configWrite.="],\n";
                }elseif ($v['type']=='array') {
                    Cache::set($ctype.'.'.$v['key'],$v['value']);
                    $ConfigArr[$v['key']]=$v['value'];
                    //组装配置
                    $configWrite.="//".$v['title']."\n'".$v['key']."'=>".$v['value'].",\n";
                }else{
                    Cache::set($ctype.'.'.$v['key'],$v['value']);
                    $ConfigArr[$v['key']]=$v['value'];
                    if (is_numeric($v['value'])) {
                        //组装配置
                        $configWrite.="//".$v['title']."\n'".$v['key']."'=>".$v['value'].",\n";
                    }else{
                        $value=str_replace("'","\'",$v['value']);
                        $value=str_replace("\n","",$value);
                        //组装配置
                        $configWrite.="//".$v['title']."\n'".$v['key']."'=>'".$value."',\n";
                    }
                }
            }
            Cache::set($ctype,$ConfigArr);
            //组装配置
            $configWrite.="\n];";
            //写入配置文件
            $configPath=config_path().$ctype.".php";
            $configFile = fopen($configPath, "w") or die("Unable to open file!");
            fwrite($configFile, $configWrite);
            fclose($configFile);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }
}
