<?php
class objectAction extends action
{
	private $tree = null;
    function __construct(){
        parent::__construct();
		$this->mod = new objectMod();
		$this->tree = new LibLRTree($this->mod->e['title'],$this->mod->e['table'],$this->mod->e['tree']);
    }

    function __destruct(){
    }
	/**
	 * Method 列表数据
	 */
    function list($parentId,$level=-1,$isfull=0){
		$where = '';
    	if($parentId>0){
    		$where .= ' AND ' . $this->tree->getChildrensWhereById($parentId);
    	}
    	if($level>-1){
    		$where .= ' AND o_level>=' . $level;
    	}
		if($_POST['filters']){
			$groups = json_decode(htmlspecialchars_decode($_POST['filters']),true);
			//附表记录查询
			$scheCols = [];
			if($parentId && $rootRow = $this->mod->getRootRowByChildren($parentId)){
				foreach($rootRow['ext'] as $v){
					if($v['oe_editor'] == 'checkbox' || $v['oe_editor'] == 'select' || $v['oe_editor'] == 'radio' || $v['oe_editor'] == 'not') 
						$scheCols['oe_'.$v['oe_id']] = $v['oe_editor_sche']; 
				}
			}
			$gridWhere = $this->groups2sql($groups,function($field,$op,$data)use($scheCols){
				if(isset($scheCols[$field])){
					$isLike = ($op=='cn');
					$data = $this->mod->getIdByText($scheCols[$field],$data,$isLike);
				}else if($field=='o_name' && $op=='cn'){
					$field = 'o_keyword';
				}
                if(is_array($data)){
                    return ['field'=>$field,'op'=>'in','data'=>"'".implode("','",$data)."'"];
                }else{
                    return ['field'=>$field,'op'=>$op,'data'=>$data];
                }
			});
			//
			if($gridWhere)
				$where .= ' AND ' . $gridWhere;
		}
		$data = $this->mod->list($parentId,$where, $_POST['page'], $_POST['rows'], $_POST['sidx'], $_POST['sord'],'',$isfull);
		foreach($data['rows'] as $k=>$v){
			//叶子图标
			$v['icon'] = 'fa fa-dot-circle-o';
			$data['rows'][$k] = $v;
		}
		echo json_encode($data, JSON_UNESCAPED_UNICODE);
	}
	/**
	 * Method 通过关键字取一行数据
	 */
	function getRowByKey($key){
		if($key==0){
			$this->exitJson(0,[]);
		}else{
			$row = $this->mod->getRowByKey('*',$key);
			if($row){
			//print_r($row);
				$row['root'] = $this->mod->getRootRowByChildren($row); //子树根节点
				$row['extvals'] = $this->mod->getExtvalList($key); //扩展值信息
				//查找在凭证中是否存在
				if($one = $this->mod->getOneSelectTable(
						'voucher','1',
						sprintf("v_state=1 AND (v_subject=%s OR v_object_1=%s OR v_object_2=%s OR v_object_4=%s)",$key,$key,$key,$key)
						)
				){
					$row['voucher_used'] = 1;
				}else{
					$row['voucher_used'] = 0;
				}

				$this->exitJson(0,$row);
			}else{
				$this->exitJson(2000);
			}
		}
	}
	/**
	 * Method 通过名称取一行数据
	 */
	function getRowByName($root,$name){
		if(empty($root) && empty($name)){
			$this->exitJson(2001);
		}else{
			if($row = $this->mod->getRowByFullName($root,$name)){
				$this->getRowByKey($row['o_id']);
			}else{
				$this->exitJson(0,0);
			}
		}
	}
	/**
	 * Method 通过关键字取所有子节点记录
	 */
	function getChildrens($key,$level=-1){
		$data = $this->mod->getRowByKey('*',$key);
		if($data){
			$data['childres'] = $this->tree->getChildrensById($key,$level);
			$this->exitJson(0,$data);
		}else{
			$this->exitJson(2000);
		}
	}
	/**
	 * Method 唯一值检测
	 */
	function onlyCheck(){
		$result = false;
		$parentId = $_REQUEST['parentId'];
		$field = $_REQUEST['field'];
		$key   = $_REQUEST['key'];
		$value = $_REQUEST['value'];
		$key = (empty($key)) ? 0 : $key;
		if($parentId!='' && $field!='' && $value!=''){
			$where = $this->tree->getChildrensWhereById($parentId);
			$where .= sprintf(" AND %s<>'%s' AND %s='%s'",$this->mod->e['key'],$key,$field,$value);
			if($this->mod->getOne('1',$where)){
				$result = true;
			}
		}else{
			$result = true; //数据有误
		}
		echo ($result) ? 'false' : 'true'; //存在不通过，不存在通过
	}
	/**
	 * Method 获取下一个编码
	 */
	function autocode(){
		$result = '0001';
		$parentId = $_REQUEST['parentId'];
		if($parentId!=''){
			$where = $this->tree->getChildrensWhereById($parentId);
			if($val = $this->mod->getOne('max(o_code)',$where)){
				$pos = -1;
				for($i=strlen($val)-1;$i>=0;$i--){
					if(is_numeric($val[$i])){
						$pos = $i;
					}
					else
						break;
				}
				if($pos==-1){
					//如果是字母,得到最后一个字母上ascii码+1的字符，如果最后一个字母是Z，刚在整编码后加字符串 1
					$c = substr($val,-1,1);
					if(ord($c)<90)
						$code = chr(ord($c)+1);
					else
						$code = $c.'1';
				}else{
					//如果是数字
					$num= substr($val,$pos,strlen($val));
					$seq = ltrim($num,'0') * 1 + 1;
					$code = str_pad($seq, strlen($num), "0", STR_PAD_LEFT);
				}
				$val = substr($val,0,$pos) . $code;
				$result = $val;
			}
		}
		$this->exitJson(0,$result);
	}
	/**
	 * Method 添加操作
	 */
	function getKeyWord($code,$name){
    	$pinyin = new \Overtrue\Pinyin\Pinyin();
    	return strtoupper($code.','.$name.','.$pinyin->abbr($name).','.$pinyin->permalink($name,''));
    }

	/**
	 * Method 添加操作
	 */
	function add(){
		$input = file_get_contents('php://input');
		$params = json_decode($input,true);
		$this->mod->Begin();
		$lastID = $this->add2db($params);
		$dbOk = $this->mod->End();
		if($dbOk && $lastID>0){
			$this->exitJson(0,['key'=>$lastID]);
		}else{
			$this->exitJson(2000);
		}
	}
	/**
	 * Method 添加操作
	 */
	function add2db($params){
		$key = $this->mod->e['key'];
		$post = $this->mod->checkValueForm($params['base'],[$key]);//添加时,主键可以为空
		if($post['error']){
			$this->exitJson(2001,$post['error']);
		}
		$data = $post['data'];
		$data['o_code'] = trim(strtoupper($data['o_code']));
		$data['o_keyword'] = $this->getKeyWord($data['o_code'],$data['o_name']);
		$lastID = 0;
		$this->tree->newNode($data[$this->mod->e['tree']['fieldParentId']],function($res)use(&$data,&$lastID){
			$data = array_merge($data,$res);//获取左右值与层级
			$lastID = $this->mod->addRow($data); //创建节点时，需要调用者先添加记录，并返回ID
			return $lastID;
		});
		if($lastID){
			if($rootRow = $this->mod->getRootRowByChildren($lastID)){
				$this->mod->callSub($rootRow[$this->mod->e['key']],'formartParams',$params);
				/*
				$extclass = 'id'.$rootRow[$this->mod->e['key']];
				$file = mvc::$cfg['ROOT'].'mod/object_ext/'.$extclass.'.php';
				if(file_exists($file)){
					require_once($file);
					$extobj = new $extclass();
					if(method_exists( $extclass, 'formartParams')){
						$params = $extobj->formartParams($params,$rootRow);
					}
				}*/
			}
			$exts = $params['exts'];
			$this->mod->setExt('object_ext_val',$exts,$lastID);
		}
		return $lastID;
	}
	
	/**
	 * Method 重构左右值
	 */
	function restLR(){
		set_time_limit(0);
		ignore_user_abort(true);
		$this->tree->restLR(); //重构左右值
		$this->exitJson(0,0);
	}
	
	/**
	 * Method 导入
	 */
	function importCsv($id){
		$file = mvc::$cfg['PATH_CACHE'].$id.'.csv';
		if (!is_file($file)) {
	        $this->exitJson(1002,$file);
	    }
	    $handle = fopen($file, 'r');
	    if (!$handle) {
	        $this->exitJson(1003,$file);
	    }
	    set_time_limit(3600 * 24 * 30);
	    echo '<pre>';
	    $i = 0;
		$cols = [];
		$this->mod->Begin();
	    while (($data = fgetcsv($handle)) !== false) {
	    	if($i==0){
		    	//处理表头
	    		$this->mod->callSub($id,'getImportConfig',$config);
	    		if(!$config){
	    			$this->exitJson(1002,'导入模板不存在');
	    		}
	    		$firstData = $data;
	    		foreach($firstData as $k=>$v){
	    			$v = iconv('gbk', 'utf-8//TRANSLIT//IGNORE',$v);
	    			$v = trim($v);
	    			$firstData[$k] = $v;
	    			$idx = array_search($v, array_column($config['cols'], 'title'));
	    			if($idx>-1){
	    				$col = $config['cols'][$idx];
	    				$cols[$k] = $col;
	    			}
	    		}
	    	}else{
		    	//处理数据
		    	$row = [];
		    	$parent_code = '';
		    	$parent_name = '';
		    	$row['base']['o_parent_id'] = $id; //默认父节点
		    	foreach($data as $k=>$v){
	    			$v = iconv('gbk', 'utf-8//TRANSLIT//IGNORE',$v);
	    			$v = trim($v);
	    			$col = $cols[$k];
	    			if($col['type']=='base'){
	    				//基础
	    				$row['base'][$col['rules']['field']] = $v;
	    				if(isset($col['rules']['parent_code'])){
	    					$idx = array_search($col['rules']['parent_code'], $firstData);
    						if($idx!=-1){
    							$parent_code = $data[$idx];
    						}
	    				}else if(isset($col['rules']['parent_name'])){
	    					$idx = array_search($col['rules']['parent_name'], $firstData);
    						if($idx!=-1){
    							$parent_name = $data[$idx];
    						}
	    				}
	    			}else if($col['type']=='exts'){
	    				//扩展
	    				if($col['rules']['sche']){
	    					//得到扩展值
	    					if(is_array($col['rules']['sche_data'])){
	    						$fv = ($v=='') ? '-NONE-' : $v;
	    						$idx='';
	    						foreach ($col['rules']['sche_data'] as $fvk => $fvs) {
	    							if(in_array($fv, $fvs)){
	    								$idx = $fvk;
	    								break;
	    							}
	    						}
	    						$v = $idx;
	    					}else if($col['rules']['sche_data']!=''){
	    						//查库
	    						$v = $this->mod->getIdByText($col['rules']['sche_data'],$v);
	    					}
	    				}
	    				//构建扩展结构
	    				if(!emptY($v)){
		    				if(isset($row['exts'][$col['rules']['checkbox']])){
		    					$row['exts'][$col['rules']['oe_id']][] = $v;
		    					sort($row['exts'][$col['rules']['oe_id']]);
		    				}else{
		    					$row['exts'][$col['rules']['oe_id']] = $v;
		    				}
	    				}
	    			}
		    	}
		    	//查父节点
		    	if($parent_code!='' || $parent_name!=''){
		    		if($parent_code!=''){
		    			$row['base']['o_parent_id'] = $this->mod->getIdByCode($id,$parent_code);
		    		}else if($parent_name!=''){
		    			$row['base']['o_parent_id'] = $this->mod->getIdByText($id,$parent_name);
		    		}
		    	}
		    	//入库
		    	if($row['base']['o_code'] && $row['base']['o_name'] && !empty($row['base']['o_parent_id'])){
		    		$has = $this->mod->getIdByCode($id,$row['base']['o_code']); //去重
		    		if(!$has){
		    			//print_r($row);
		    			$this->add2db($row);
		    		}
		    	}
	    	}
	    	//处理数据
	    	$i++;
	    }
	    $dbOk = $this->mod->End();
	    fclose($handle);
    }

	/**
	 * Method 修改操作
	 */
	function edit(){
		$input = file_get_contents('php://input');
		$params = json_decode($input,true);
		$key = $params['base'][$this->mod->e['key']];
		if(empty($key)){
			$this->exitJson(2001,'无效的主键');
		}
		$row = $this->mod->getRowByKey('*',$key);
		if(!$row){
			$this->exitJson(2001,'库中已无此记录');
		}
		if($rootRow = $this->mod->getRootRowByChildren($row)){
			$rootId = $rootRow[$this->mod->e['key']];
			$this->mod->callSub($rootId,'formartParams',$params);
		}else{
			$this->exitJson(2001,'找不到对应的模块');
		}
		$post = $this->mod->checkValueForm($params['base']);
		if($post['error']){
			$this->exitJson(2001,$post['error']);
		}
		$data = $post['data'];
		$data['o_code'] = trim(strtoupper($data['o_code']));
		$data['o_keyword'] = $this->getKeyWord($data['o_code'],$data['o_name']);
		$exts = $params['exts'];
		$this->mod->Begin();
		$result = $this->mod->setRowByKey($data,$key);
		if($result){
			$result = $this->mod->setExt('object_ext_val',$exts,$key);
			if( $result && ($row['o_parent_id']!=$data['o_parent_id'] || $row['o_code']!=$data['o_code']) ){
				$this->tree->restLR(); //重构左右值
			}
		}
		$dbOk = $this->mod->End();
		if($dbOk){
			$this->exitJson(0,['key'=>$key]);
		}else{
			$this->exitJson(2000);
		}
	}
	/**
	 * Method 删除操作
	 */
	function delete(){
		$input = file_get_contents('php://input');
		$params = json_decode($input,true);
		if(empty($params['key'])){
			$this->exitJson(2001);
		}
		//查找在凭证中是否存在
		if($one = $this->mod->getOneSelectTable(
				'voucher','1',
				sprintf("v_subject=%s OR v_object_1=%s OR v_object_2=%s OR v_object_4=%s",$params['key'],$params['key'],$params['key'],$params['key'])
				)
		){
			$this->exitJson(2001,"此项目在凭证中已被使用，不能删除");
		}
		$result = false;
		$this->mod->Begin();
		$this->tree->deleteNode($params['key'],function()use($params,&$result){
			$this->mod->deleteRowsSelectTable('object_ext_val',sprintf("oev_o_id=%s",$params['key']));
			if(true){ //可以执行其他相关的操作，返回true才执行节点删除
				return true;
			}else{
				return false;
			}
		});
		$dbOk = $this->mod->End();
		if($dbOk){
			$this->exitJson(0);
		}else{
			$this->exitJson(2000);
		}
	}
	/**
	 * Method 取=父ID的树节点数据,用于jsTree
	 */
    function getJsTreeNode(){
		$key        = $_REQUEST['key'];
		$rootKey    = $_REQUEST['rootKey'];
		$defaultKey = $_REQUEST['defaultKey'];
		$level      = $_REQUEST['level'];
		$noid       = $_REQUEST['noid'];
    	$root = 0;
		$data = [];
		if(($key == '#' || $key == '0') && $rootKey>0){
			$row = $this->tree->getRowById($rootKey);
			$children = $this->tree->hasChildren($row);
			$data =  [
				'id'=> $rootKey,
				'text'=>$row['o_name'],
				'parent'=> '#',
				'children'=> $children,
				"type"=> 'root',
				"state"=>["opened"=>true]
			];
		}else if($key){
			$row = $this->tree->getRowById($key);
			if($row['o_level']+1 <= $level){
				if($table = $this->tree->getChildrensById($key,$row['o_level']+1)){
					foreach($table as $row){
						if($noid != $row['o_id'])
							$data[] = $this->formatJsTreeData($row);
					}
				}
			}
		}		
		echo json_encode($data, JSON_UNESCAPED_UNICODE);
	}
	/**
	 * Method 搜索节点
	 */
    function searchJsTreeNode(){
		$rootKey    = $_REQUEST['rootKey'];
		$level      = $_REQUEST['level'];
		$str        = $_REQUEST['str'];
		$data = $this->tree->searchNodeForJsTree($str,$rootKey);
		echo json_encode($data, JSON_UNESCAPED_UNICODE);
	}
	/**
	  * @method 格式化为jsTree数据记录
	  * @param  [array]  $row  行记录
	  * @return [bool]
	  */
	function formatJsTreeData($row){
		$children = $this->tree->hasChildren($row);
		$icon = ($children) ? '' : 'glyphicon glyphicon-file';
		$type = ($children) ? 'folder' : 'file';
		$data = [
			'id'=> $row['o_id'],
			'text'=>$row['o_code'] . ' ' . $row['o_name'],
			'parent'=> $row['o_parent_id'],
			'children'=> $children,
			"type"=> $type
		];
		return $data;
	}
}