<?php
/**
 * 异步写日志方法
 * 
 *  * ============================================================================
 * 版权所有 2017北京素玄科技，并保留所有权利。
 * 
 * 网站地址: http://www.suxuantech.com
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！未经允许的情况下，您不能对本系统代码做任何修改 .
 * 不允许对程序代码以任何形式任何目的的再发布。
 * 如有修改需求，请联系素玄科技有限公司：contact@suxuantech.cn
 * ============================================================================
 * $Author: songdemei<songdemei@suxuantech.cn> 2018-03-16 $
 */
namespace app\crm\lib;
use think\Controller;
class RunSyncLogs extends Controller {
    
    public function saveLogs($data){
        if(empty($data)){
            $this->log('Queue body is empty.');
            return false;
        }
        /**
         * 要存日志的表名，即向哪张表存数据
         * 
         * @var [String]
         */
        $tableName = isset($data['table_name'])?$data['table_name']:'';
        /**
         * 要存的数据，单条数据，以一维数组形式，一次处理一个日志
         * @var [Array]
         */
        $data = isset($data['data'])?$data['data']:array();
        /**
         * 要存的数据，多条数据，以二维数组形式，一次处理一个日志
         * @var [Array]
         */
        $datas = isset($data['datas'])?$data['datas']:array();

        if(empty($tableName)){
            $this->log('Table name is empty,ignore it.');
            return false;
        }
        $extName = '_'.date('Ym');
        $res = $this->checkTable($tableName,$extName);
        if($res === false){
            $this->log('Check extend table false.');
            return false;
        }
        $tableName .= $extName;
        if(empty($data) && empty($datas)){
            $this->log('Log body is empty,ignore it.');
            return false;
        }
        if(!empty($data) && is_array($data)){
            //处理单条数据日志
            $this->log('Start do a log for:'.$tableName);
            $this->saveOneLog($tableName,$data);
        }elseif (!empty($datas) && is_array($datas)) {
            # 处理多条数据
            $this->log('Start do '.count($datas).' logs for:'.$tableName);
            $this->saveAllLog($tableName,$datas);
        }else{
            $this->log('Log body must be array,ignore it.');
            return false;
        }
        
    }
    function checkTable($tableName,$ext=''){
        if($this->isTableExist($tableName) === false){
            return false;
        }
        if($this->isTableExist($tableName.$ext) === false){
            //分表不存在，则从主表创建
            $res = db($tableName,'db_logs')->query('show create table '.$tableName);
            $extTableSql = end($res[0]);
            $extTableSql = str_replace("`".$tableName."`", "`".$tableName.$ext."`", $extTableSql);
            $createRes = db($tableName,'db_logs')->execute($extTableSql);
            if($createRes === false){
                return false;
            }
        }
        return true;
        
    }
    function saveOneLog($tableName,$data){
        #增加字段判断，防止插入数据时报错。
        #coding...
        $unknowColumn = [];
        $column = $this->getColumns($tableName);
        if(!$column || empty($column)){
            $this->log('Table has no column:'.$tableName);
            return false;
        }
        foreach ($data as $key => $value) {
            # code...
            if(!in_array($key, $column)){
                $unknowColumn[] = $key;
                unset($data[$key]);
            }
        }
        if(!empty($unknowColumn)){
            $this->log('Unknwo column in log data:'.implode(',', $unknowColumn));
        }
        try{
            db($tableName,'db_logs')->insert($data);
            $this->log('One log save success.');
        }catch(\Exception $e){
            $this->log('One log save error:'.$e->getMessage());
        }

    }

    function saveAllLog($tableName,$datas){
        #增加字段判断，防止插入数据时报错。
        #coding...
        $unknowColumn = [];
        $column = $this->getColumns($tableName);
        if(!$column || empty($column)){
            $this->log('Table has no column:'.$tableName);
            return false;
        }
        foreach ($datas as $data) {
            # code...
            foreach ($data as $key => $value) {
                if(!in_array($key, $column)){
                    $unknowColumn[] = $key;
                    unset($data[$key]);
                }
            }
        }
        if(!empty($unknowColumn)){
            $this->log('Unknwo column in log data:'.implode(',', $unknowColumn));
        }
        try{
            db($tableName,'db_logs')->insertAll($datas);
            $this->log('Some log save success,logs count:'.count($datas));
        }catch(\Exception $e){
            $this->log('One log save error:'.$e->getMessage());
        }

    }
    function getColumns($table){
        $sql = 'desc '.$table;
        $res = db($table,'db_logs')->master()->query($sql);
        $column = [];
        foreach($res as $value){
            $column[] = $value['Field'];
        }
        return $column;
    }
    function isTableExist($table){
        $sql = "show tables;";
        $res = db($table,'db_logs')->master()->query($sql);
        foreach($res as $value){
            
            if(array_search($table, $value)){
                return true;
            }
        }
        return false;
    }
    // 调试用的log方法
    function log($str){
        if(config('app_debug')){
            echo date('Y-m-d H:i:s').$str."\r\n";
        }
    }

}