mirror of https://gitee.com/zorlan/skycaiji
parent
f5af21e5ef
commit
b1497d0ad5
|
@ -15,49 +15,64 @@ use skycaiji\admin\controller\BaseController;
|
|||
class Init{
|
||||
|
||||
public function run(){
|
||||
|
||||
$curController=strtolower(request()->controller());
|
||||
if('store'==$curController){
|
||||
|
||||
controller('Store','controller')->_checkCors(true);
|
||||
}
|
||||
/*自动登录*/
|
||||
$muser=model('User');
|
||||
$s_userid=session('user_id');
|
||||
if(!IS_CLI&&empty($s_userid)){
|
||||
|
||||
$s_userlogin=session('user_login');
|
||||
if(!IS_CLI&&empty($s_userlogin)){
|
||||
|
||||
$login_history=cookie('login_history');
|
||||
if(!empty($login_history)){
|
||||
$login_history=explode('|', $login_history);
|
||||
$user=$muser->where('username',$login_history[0])->find();
|
||||
$loginHistory=cookie('login_history');
|
||||
if(!empty($loginHistory)){
|
||||
$loginHistory=explode('|', $loginHistory);
|
||||
$user=$muser->getByUid($loginHistory[0]);
|
||||
if(!empty($user)){
|
||||
$user['username']=strtolower($user['username']);
|
||||
|
||||
if($user['username']==$login_history[0]&&$login_history[1]==md5($user['username'].$user['password'])){
|
||||
session('user_id',$user['uid']);
|
||||
if($loginHistory[1]==$muser->generate_key($user)){
|
||||
$muser->setLoginSession($user);
|
||||
}
|
||||
}
|
||||
unset($user);
|
||||
}
|
||||
$s_userid=session('user_id');
|
||||
$s_userlogin=session('user_login');
|
||||
}
|
||||
$s_userlogin=is_array($s_userlogin)?$s_userlogin:array();
|
||||
$s_userid=intval($s_userlogin['uid']);
|
||||
|
||||
$isAdmin=null;
|
||||
$user=null;
|
||||
if($s_userid>0){
|
||||
$GLOBALS['_sc']['user']=$muser->getByUid($s_userid);
|
||||
if(!empty($GLOBALS['_sc']['user'])){
|
||||
$GLOBALS['_sc']['user']=$GLOBALS['_sc']['user']->toArray();
|
||||
$GLOBALS['_sc']['user']['group']=model('Usergroup')->getById($GLOBALS['_sc']['user']['groupid']);
|
||||
if(!empty($GLOBALS['_sc']['user']['group'])){
|
||||
$GLOBALS['_sc']['user']['group']=$GLOBALS['_sc']['user']['group']->toArray();
|
||||
if(model('Usergroup')->is_admin($GLOBALS['_sc']['user']['group'])){
|
||||
session('is_admin',true);
|
||||
}else{
|
||||
session('is_admin',null);
|
||||
$userKeyIsRight=false;
|
||||
$user=$muser->getByUid($s_userid);
|
||||
if(!empty($user)){
|
||||
$user=$user->toArray();
|
||||
$user['group']=model('Usergroup')->getById($user['groupid']);
|
||||
if(!empty($user['group'])){
|
||||
$user['group']=$user['group']->toArray();
|
||||
if(model('Usergroup')->is_admin($user['group'])){
|
||||
$isAdmin=true;
|
||||
}
|
||||
}
|
||||
if($s_userlogin['key']==$muser->generate_key($user)){
|
||||
|
||||
$userKeyIsRight=true;
|
||||
}
|
||||
}
|
||||
if(!$userKeyIsRight){
|
||||
|
||||
$user=null;
|
||||
}
|
||||
}
|
||||
if(empty($user)){
|
||||
|
||||
$muser->setLoginSession(null);
|
||||
}
|
||||
|
||||
if(!empty($GLOBALS['_sc']['user'])&&session('is_admin')){
|
||||
set_g_sc('user',$user);
|
||||
|
||||
session('is_admin',$isAdmin);
|
||||
|
||||
if(!is_empty(g_sc('user'))&&$isAdmin){
|
||||
/*是管理员,进行下列操作*/
|
||||
if('index'==$curController&&'index'==strtolower(request()->action())){
|
||||
|
||||
|
@ -89,13 +104,25 @@ class Init{
|
|||
$mconfig->cacheConfigList();
|
||||
$configList=$mconfig->getConfigList();
|
||||
}
|
||||
$GLOBALS['_sc']['c']=$configList;
|
||||
set_g_sc('c',$configList);
|
||||
set_g_sc('c_caiji_interval',intval(g_sc_c('caiji','interval')));
|
||||
|
||||
if(!empty($GLOBALS['_sc']['c']['site']['closelog'])){
|
||||
$timezone=g_sc_c('site','timezone');
|
||||
if(!empty($timezone)){
|
||||
|
||||
if(strpos($timezone, 'UTC')===0){
|
||||
|
||||
|
||||
$timezone=str_replace(array('UTC+','UTC-'), array('Etc/GMT-','Etc/GMT+'), $timezone);
|
||||
}
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
|
||||
if(!is_empty(g_sc_c('site','closelog'))){
|
||||
|
||||
\think\Log::init(array('type'=>'test','level'=>array()));
|
||||
}
|
||||
if(!empty($GLOBALS['_sc']['c']['site']['dblong'])){
|
||||
if(!is_empty(g_sc_c('site','dblong'))){
|
||||
|
||||
$dbParams=config('database.params');
|
||||
$dbParams[\PDO::ATTR_PERSISTENT]=true;
|
||||
|
@ -103,13 +130,13 @@ class Init{
|
|||
}
|
||||
|
||||
|
||||
if(empty($GLOBALS['_sc']['c']['download_img'])){
|
||||
$GLOBALS['_sc']['c']['download_img']=$mconfig->get_img_config_from_caiji($GLOBALS['_sc']['c']['caiji']);
|
||||
if(is_empty(g_sc_c('download_img'))){
|
||||
set_g_sc(['c','download_img'],$mconfig->get_img_config_from_caiji(g_sc_c('caiji')));
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['clientinfo']=clientinfo();
|
||||
if(!empty($GLOBALS['_sc']['clientinfo'])){
|
||||
$GLOBALS['_sc']['clientinfo']=base64_encode(json_encode($GLOBALS['_sc']['clientinfo']));
|
||||
set_g_sc('clientinfo',clientinfo());
|
||||
if(!is_empty(g_sc('clientinfo'))){
|
||||
set_g_sc('clientinfo',base64_encode(json_encode(g_sc('clientinfo'))));
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,7 +147,7 @@ class Init{
|
|||
$usertoken=md5($usertoken);
|
||||
session('usertoken',$usertoken);
|
||||
}
|
||||
$GLOBALS['_sc']['usertoken']=$usertoken;
|
||||
set_g_sc('usertoken',$usertoken);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,10 @@ class Collect extends Command{
|
|||
$this->setName('collect')
|
||||
->addArgument('op', Argument::OPTIONAL, "op")
|
||||
->addOption('cli_user', null, Option::VALUE_REQUIRED, 'cli user')
|
||||
->addOption('task_id', null, Option::VALUE_REQUIRED, 'collect:task_id')
|
||||
->addOption('task_id', null, Option::VALUE_REQUIRED, 'task:task_id')
|
||||
->addOption('task_ids', null, Option::VALUE_REQUIRED, 'batch:task_ids')
|
||||
->addOption('rele_id', null, Option::VALUE_REQUIRED, 'test:rele_id')
|
||||
->addOption('logid', null, Option::VALUE_REQUIRED, 'logid')
|
||||
->setDescription('collect task');
|
||||
}
|
||||
|
||||
|
@ -34,9 +36,12 @@ class Collect extends Command{
|
|||
if(is_array($cacheConfig)){
|
||||
\think\Config::set($cacheConfig);
|
||||
}
|
||||
|
||||
\skycaiji\common\model\Config::set_url_compatible();
|
||||
|
||||
$op=$input->getArgument('op');
|
||||
|
||||
static $loginOps=array('task','batch');
|
||||
static $loginOps=array('task','batch','test');
|
||||
|
||||
if(in_array($op, $loginOps)){
|
||||
|
||||
|
@ -48,24 +53,31 @@ class Collect extends Command{
|
|||
if(!empty($cliUser[0])){
|
||||
|
||||
$muser=new \skycaiji\admin\model\User();
|
||||
$user=$muser->where('username',$cliUser[0])->find();
|
||||
$user=$muser->getByUid($cliUser[0]);
|
||||
if(!empty($user)){
|
||||
$user['username']=strtolower($user['username']);
|
||||
|
||||
if($user['username']==$cliUser[0]&&$cliUser[1]==md5($user['username'].$user['password'])){
|
||||
session('user_id',$user['uid']);
|
||||
if($cliUser[1]==$muser->generate_key($user)){
|
||||
$muser->setLoginSession($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!session('?user_id')){
|
||||
$sUserlogin=session('user_login');
|
||||
if(empty($sUserlogin)){
|
||||
$this->error_msg('抱歉,必须传入账号信息!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$logid='';
|
||||
if ($input->hasOption('logid')){
|
||||
$logid=$input->getOption('logid');
|
||||
$logid=base64_decode($logid);
|
||||
}
|
||||
|
||||
$rootUrl=\think\Config::get('root_website').'/index.php?s=';
|
||||
|
||||
|
||||
if('task'==$op){
|
||||
|
||||
$taskId=0;
|
||||
|
@ -75,6 +87,7 @@ class Collect extends Command{
|
|||
}
|
||||
|
||||
$curUrl=$rootUrl.'/admin/task/collect&backstage=1&id='.urlencode($taskId);
|
||||
$curUrl=$this->url_append_logid($curUrl,$logid);
|
||||
\think\Request::create($curUrl);
|
||||
|
||||
define('BIND_MODULE', "admin/task/collect");
|
||||
|
@ -87,17 +100,33 @@ class Collect extends Command{
|
|||
$taskIds=$input->getOption('task_ids');
|
||||
}
|
||||
$curUrl=$rootUrl.'/admin/task/collectBatch&backstage=1&ids='.urlencode($taskIds);
|
||||
$curUrl=$this->url_append_logid($curUrl,$logid);
|
||||
\think\Request::create($curUrl);
|
||||
|
||||
define('BIND_MODULE', "admin/task/collectBatch");
|
||||
\think\App::run()->send();
|
||||
}elseif('test'==$op){
|
||||
|
||||
$releId=0;
|
||||
if ($input->hasOption('rele_id')){
|
||||
$releId=$input->getOption('rele_id');
|
||||
$releId=intval($releId);
|
||||
}
|
||||
|
||||
$curUrl=$rootUrl.'/admin/release/test&backstage=1&id='.urlencode($releId);
|
||||
$curUrl=$this->url_append_logid($curUrl,$logid);
|
||||
\think\Request::create($curUrl);
|
||||
|
||||
define('BIND_MODULE', "admin/release/test");
|
||||
\think\App::run()->send();
|
||||
}elseif('backstage'==$op){
|
||||
|
||||
set_time_limit(0);
|
||||
$curKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
|
||||
do{
|
||||
|
||||
$cacheKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
|
||||
$curKey=CacheModel::getInstance()->getCache('collect_backstage_key', 'data');
|
||||
do{
|
||||
|
||||
CacheModel::getInstance()->setCache('collect_backstage_time',time());
|
||||
$cacheKey=CacheModel::getInstance()->getCache('collect_backstage_key', 'data');
|
||||
if(empty($curKey)||$curKey!=$cacheKey){
|
||||
|
||||
|
||||
|
@ -107,7 +136,7 @@ class Collect extends Command{
|
|||
$mconfig=new \skycaiji\admin\model\Config();
|
||||
$caijiConfig=$mconfig->getConfig('caiji','data');
|
||||
|
||||
if($caijiConfig['server']!='cli'){
|
||||
if(!$mconfig->server_is_cli(true,$caijiConfig['server'])){
|
||||
$this->error_msg('不是cli命令行模式');
|
||||
}
|
||||
if(empty($caijiConfig['auto'])){
|
||||
|
@ -117,23 +146,24 @@ class Collect extends Command{
|
|||
$this->error_msg('不是后台运行方式');
|
||||
}
|
||||
|
||||
$url=$rootUrl.'/admin/api/collect&backstage=1';
|
||||
|
||||
try{
|
||||
|
||||
\util\Curl::get($url,null,array('timeout'=>3));
|
||||
}catch(\Exception $ex){
|
||||
|
||||
$checkCollectWait=\skycaiji\admin\model\Config::check_collect_wait();
|
||||
if(!$checkCollectWait){
|
||||
$url=$rootUrl.'/admin/api/collect&backstage=1';
|
||||
|
||||
try{
|
||||
|
||||
\util\Curl::get($url,null,array('timeout'=>3));
|
||||
}catch(\Exception $ex){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$waitTime=$caijiConfig['interval']*60;
|
||||
$waitTime=$waitTime>0?$waitTime:60;
|
||||
sleep($waitTime);
|
||||
|
||||
sleep(60);
|
||||
}while(1==1);
|
||||
}elseif('auto'==$op){
|
||||
|
||||
$curUrl=$rootUrl.'/admin/api/collect&backstage=1';
|
||||
$curUrl=$this->url_append_logid($curUrl,$logid);
|
||||
\think\Request::create($curUrl);
|
||||
|
||||
define('BIND_MODULE', "admin/api/collect");
|
||||
|
@ -144,4 +174,12 @@ class Collect extends Command{
|
|||
protected function error_msg($msg){
|
||||
exit($msg);
|
||||
}
|
||||
|
||||
|
||||
protected function url_append_logid($url,$logid){
|
||||
if(!empty($logid)){
|
||||
$url=$url.(strpos($url,'?')===false?'?':'&').'logid='.urlencode($logid);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
|
@ -10,12 +10,16 @@
|
|||
*/
|
||||
|
||||
/*采集规则标签*/
|
||||
function cp_sign($sign,$num=''){
|
||||
function cp_sign($sign,$id=''){
|
||||
$sign=strtolower($sign);
|
||||
if($sign=='match'){
|
||||
return lang('sign_match',array('num'=>$num));
|
||||
if($id==':id'){
|
||||
|
||||
$id='(?P<id>\w*)';
|
||||
}
|
||||
return lang('sign_match',array('id'=>$id));
|
||||
}else{
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/*密码验证*/
|
||||
|
@ -64,18 +68,13 @@ function program_filemd5_list($path,&$md5FileList){
|
|||
}
|
||||
}
|
||||
}
|
||||
/*验证用户token*/
|
||||
function check_usertoken(){
|
||||
if($GLOBALS['_sc']['usertoken']!=input('_usertoken_')){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*输出用户token*/
|
||||
function html_usertoken(){
|
||||
|
||||
return '<input type="hidden" name="_usertoken_" value="'.$GLOBALS['_sc']['usertoken'].'" />';
|
||||
return '<input type="hidden" name="_usertoken_" value="'.g_sc('usertoken').'" />';
|
||||
}
|
||||
function url_usertoken(){
|
||||
return '_usertoken_='.rawurlencode(g_sc('usertoken'));
|
||||
}
|
||||
|
||||
/*判断正在执行采集任务*/
|
||||
|
@ -106,100 +105,150 @@ function cli_command_exec($paramStr){
|
|||
}
|
||||
}
|
||||
|
||||
$phpExeFile=$GLOBALS['_sc']['c']['caiji']['server_php'];
|
||||
if(empty($phpExeFile)){
|
||||
|
||||
$phpExeFile=model('Config')->detect_php_exe();
|
||||
$commandStr=g_sc_c('caiji','server_php');
|
||||
if(empty($commandStr)){
|
||||
|
||||
$commandStr=\skycaiji\admin\model\Config::detect_php_exe();
|
||||
}
|
||||
$commandStr=$phpExeFile;
|
||||
if(IS_WIN){
|
||||
|
||||
$commandStr='"'.$commandStr.'"';
|
||||
}
|
||||
|
||||
$cliUser=strtolower($GLOBALS['_sc']['user']['username']);
|
||||
$cliUser=$cliUser.'_'.md5($cliUser.$GLOBALS['_sc']['user']['password']);
|
||||
|
||||
$paramStr.=' --cli_user '.base64_encode($cliUser);
|
||||
|
||||
$commandStr.=' '.config('root_path').DIRECTORY_SEPARATOR.'caiji '.$paramStr;
|
||||
|
||||
$descriptorspec = array(
|
||||
0 => array('pipe', 'r'),
|
||||
1 => array('pipe', 'w'),
|
||||
2 => array('pipe', 'w')
|
||||
);
|
||||
$pipes=array();
|
||||
$handle=proc_open($commandStr,$descriptorspec,$pipes);
|
||||
$hdStatus=proc_get_status($handle);
|
||||
fclose($pipes[0]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
if(!empty($commandStr)){
|
||||
$commandStr=\skycaiji\admin\model\Config::cli_safe_filename($commandStr);
|
||||
|
||||
$cliUser=intval(g_sc('user','uid')).'_'.model('User')->generate_key(g_sc('user'));
|
||||
|
||||
$paramStr.=' --cli_user '.base64_encode($cliUser);
|
||||
|
||||
$commandStr.=' '.config('root_path').DIRECTORY_SEPARATOR.'caiji '.$paramStr;
|
||||
|
||||
if(session_status()!==PHP_SESSION_ACTIVE){
|
||||
session_start();
|
||||
}
|
||||
session_write_close();
|
||||
|
||||
proc_open_exec($commandStr,false);
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
function is_official_url($url){
|
||||
if(preg_match('/skycaiji\.com/i', $url)){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
function proc_open_exec($commandStr,$returnInfo=false,$timeout=10,$closeProc=false){
|
||||
$info=array('status'=>'','output'=>'','error'=>'');
|
||||
$timeout=intval($timeout);
|
||||
if($timeout<=0){
|
||||
$timeout=10;
|
||||
}
|
||||
if(!empty($commandStr)){
|
||||
$descriptorspec = array(
|
||||
0 => array('pipe', 'r'),
|
||||
1 => array('pipe', 'w'),
|
||||
2 => array('pipe', 'w')
|
||||
);
|
||||
$pipes=array();
|
||||
$otherOptions=IS_WIN?array('suppress_errors'=>true,'bypass_shell'=>true):array();
|
||||
$handle=proc_open($commandStr,$descriptorspec,$pipes,null,null,$otherOptions);
|
||||
if($returnInfo){
|
||||
|
||||
if(!is_resource($handle)){
|
||||
|
||||
$info['error']='命令执行失败,请检查可执行文件是否存在,以及'.\util\Funcs::web_server_name().'服务器的用户权限';
|
||||
}else{
|
||||
$returnInfo=$returnInfo=='all'?array('status','output','error'):explode(',',$returnInfo);
|
||||
$nowtime=time();
|
||||
if(in_array('status',$returnInfo)){
|
||||
|
||||
$info['status']=proc_get_status($handle);
|
||||
}
|
||||
if(in_array('output',$returnInfo)){
|
||||
|
||||
if(function_exists('stream_set_blocking')){
|
||||
stream_set_blocking($pipes[1],false);
|
||||
}
|
||||
if(function_exists('stream_set_timeout')){
|
||||
stream_set_timeout($pipes[1],$timeout);
|
||||
}
|
||||
while(is_resource($pipes[1])&&!feof($pipes[1])){
|
||||
$info['output'].=fgets($pipes[1]);
|
||||
if((time()-$nowtime)>$timeout){
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$nowtime=time();
|
||||
if(in_array('error',$returnInfo)){
|
||||
|
||||
if(function_exists('stream_set_blocking')){
|
||||
stream_set_blocking($pipes[2],false);
|
||||
}
|
||||
if(function_exists('stream_set_timeout')){
|
||||
stream_set_timeout($pipes[2],$timeout);
|
||||
}
|
||||
while(is_resource($pipes[2])&&!feof($pipes[2])){
|
||||
$info['error'].=fgets($pipes[2]);
|
||||
if((time()-$nowtime)>$timeout){
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array('output','error') as $key){
|
||||
|
||||
if(!empty($info[$key])){
|
||||
$encode=mb_detect_encoding($info[$key], array('ASCII','UTF-8','GB2312','GBK','BIG5'));
|
||||
if($encode!='UTF-8'){
|
||||
$info[$key] = iconv ( $encode, 'utf-8//IGNORE', $info[$key] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(is_resource($pipes[0])){
|
||||
fclose($pipes[0]);
|
||||
}
|
||||
if(is_resource($pipes[1])){
|
||||
fclose($pipes[1]);
|
||||
}
|
||||
if(is_resource($pipes[2])){
|
||||
fclose($pipes[2]);
|
||||
}
|
||||
if($closeProc&&is_resource($handle)){
|
||||
proc_terminate($handle);
|
||||
proc_close($handle);
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
|
||||
function convert_html2json($html,$returnStr=false){
|
||||
static $jsonpRegExp='/^(\s*[\$\w\-]+\s*[\{\(])+(?P<json>[\s\S]+)(?P<end>[\}\]])\s*\)\s*[\;]{0,1}/i';
|
||||
$json=json_decode($html,true);
|
||||
if(!empty($json)){
|
||||
|
||||
if($returnStr){
|
||||
|
||||
$json=$html;
|
||||
}
|
||||
}elseif(preg_match($jsonpRegExp,$html,$json)){
|
||||
|
||||
$json=trim($json['json']).$json['end'];
|
||||
if(!$returnStr){
|
||||
|
||||
$json=json_decode($json,true);
|
||||
}
|
||||
}
|
||||
return $json?$json:null;
|
||||
function trim_input_array($arrName){
|
||||
if(empty($arrName)){
|
||||
return null;
|
||||
}
|
||||
$data=input($arrName.'/a',array(),'trim');
|
||||
$data=\util\Funcs::array_array_map('trim', $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
function curl_skycaiji($uri,$headers=null,$options=array(),$postData=null,$returnInfo=false){
|
||||
$url='://www.skycaiji.com'.$uri;
|
||||
$info=get_html('https'.$url,$headers,$options,'utf-8',$postData,true);
|
||||
$info=is_array($info)?$info:array();
|
||||
if(empty($info['ok'])){
|
||||
|
||||
$info=get_html('http'.$url,$headers,$options,'utf-8',$postData,true);
|
||||
$info=is_array($info)?$info:array();
|
||||
}
|
||||
return $returnInfo?$info:$info['html'];
|
||||
}
|
||||
|
||||
function array_filter_keep0($list){
|
||||
if(is_array($list)){
|
||||
foreach ($list as $k=>$v){
|
||||
if(empty($v)&&$v!==0&&$v!=='0'){
|
||||
|
||||
unset($list[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function strip_phpcode_comment($code){
|
||||
if($code){
|
||||
$tokens=token_get_all($code);
|
||||
$newCode='';
|
||||
foreach ($tokens as $key=>$token){
|
||||
if (!is_array($token)){
|
||||
$newCode.=$token;
|
||||
}else{
|
||||
|
||||
if($token[0]==T_COMMENT||$token[0]==T_DOC_COMMENT){
|
||||
if(preg_match('/[\r\n]+$/', $token[1])){
|
||||
|
||||
$newCode.=PHP_EOL;
|
||||
}
|
||||
}else{
|
||||
$newCode.=$token[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$code=$newCode;
|
||||
}
|
||||
return $code;
|
||||
function curl_store($providerUrl,$uri,$headers=null,$options=array(),$postData=null){
|
||||
$html=null;
|
||||
if(empty($providerUrl)){
|
||||
|
||||
$html=curl_skycaiji($uri,$headers,$options,$postData);
|
||||
}else{
|
||||
$html=get_html($providerUrl.$uri,$headers,$options,'utf-8',$postData);
|
||||
}
|
||||
return $html;
|
||||
}
|
|
@ -15,7 +15,7 @@ use skycaiji\admin\model\CacheModel;
|
|||
class Api extends BaseController{
|
||||
/*任务api发布*/
|
||||
public function taskAction(){
|
||||
define('CLOSE_ECHO_MSG', 1);
|
||||
define('CLOSE_ECHO_MSG', true);
|
||||
$taskId=input('id/d',0);
|
||||
$apiurl=input('apiurl');
|
||||
$releData=model('Release')->where(array('task_id'=>$taskId))->find();
|
||||
|
@ -23,74 +23,137 @@ class Api extends BaseController{
|
|||
if($apiurl!=$releData['config']['api']['url']){
|
||||
exit('api地址错误!');
|
||||
}
|
||||
|
||||
define('API_TASK_RESPONSE_JSON', true);
|
||||
|
||||
header('Content-type:text/json');
|
||||
controller('admin/Task','controller')->_collect($taskId);
|
||||
}
|
||||
/*执行采集*/
|
||||
public function collectAction(){
|
||||
if(input('?backstage')){
|
||||
|
||||
if(!IS_CLI){
|
||||
ignore_user_abort(true);
|
||||
|
||||
if($GLOBALS['_sc']['c']['caiji']['server']=='cli'){
|
||||
|
||||
cli_command_exec('collect auto');
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!input('?backstage')){
|
||||
|
||||
config('dispatch_error_tmpl','common:error');
|
||||
config('dispatch_success_tmpl','common:success');
|
||||
}
|
||||
|
||||
$this->_backstage_cli_collect('auto');
|
||||
|
||||
define('IS_COLLECTING', 1);
|
||||
$mcache=CacheModel::getInstance();
|
||||
$autoCacheData=$mcache->getCache('auto_collecting');
|
||||
if($autoCacheData){
|
||||
|
||||
|
||||
if((time()-intval($autoCacheData['dateline']))>60*($GLOBALS['_sc']['c']['caiji']['interval']+15)){
|
||||
$autoInterval=time()-intval($autoCacheData['dateline']);
|
||||
if($autoInterval<=60*(g_sc('c_caiji_interval')+10)){
|
||||
|
||||
}else{
|
||||
|
||||
$this->error('有任务正在自动采集');
|
||||
$this->echo_msg_exit('有任务正在自动采集');
|
||||
}
|
||||
}
|
||||
$mcache->setCache('auto_collecting',1);
|
||||
register_shutdown_function('remove_auto_collecting');
|
||||
|
||||
if(input('?backstage')||!session('user_id')){
|
||||
|
||||
define('CLOSE_ECHO_MSG', true);
|
||||
}
|
||||
ignore_user_abort(true);
|
||||
|
||||
if($GLOBALS['_sc']['c']['caiji']['timeout']>0){
|
||||
set_time_limit(60*$GLOBALS['_sc']['c']['caiji']['timeout']);
|
||||
if(g_sc_c('caiji','timeout')>0){
|
||||
set_time_limit(60*g_sc_c('caiji','timeout'));
|
||||
}else{
|
||||
set_time_limit(0);
|
||||
}
|
||||
|
||||
if(empty($GLOBALS['_sc']['c']['caiji']['auto'])){
|
||||
$this->error('请先开启自动采集','Admin/Setting/caiji');
|
||||
if(is_empty(g_sc_c('caiji','auto'))){
|
||||
$this->echo_msg_exit('请先开启自动采集 <a href="'.url('Admin/Setting/caiji').'" target="_blank">设置</a>');
|
||||
}
|
||||
$lastCollectTime=cache('last_collect_time');
|
||||
if($GLOBALS['_sc']['c']['caiji']['interval']>0){
|
||||
|
||||
$waitTime=(60*$GLOBALS['_sc']['c']['caiji']['interval'])-abs(time()-$lastCollectTime);
|
||||
if($waitTime>0){
|
||||
$this->error('再次采集需等待'.(($waitTime<60)?($waitTime.'秒'):(sprintf("%.2f", $waitTime/60).'分钟')),'Admin/Api/collect',null,$waitTime);
|
||||
}
|
||||
|
||||
$checkCollectWait=\skycaiji\admin\model\Config::check_collect_wait();
|
||||
if($checkCollectWait){
|
||||
$this->echo_msg_exit($checkCollectWait['msg'].' <a href="'.url('Admin/Setting/caiji').'" target="_blank">设置运行间隔</a>');
|
||||
}
|
||||
|
||||
|
||||
$mtask=model('Task');
|
||||
$taskList=$mtask->alias('t')->join(model('Collector')->get_table_name().' c','t.id=c.task_id')
|
||||
->field('t.*')->where("t.auto=1 and t.module='pattern'")->order('t.caijitime asc')->select();
|
||||
if(empty($taskList)){
|
||||
$this->error('没有可自动采集的任务');
|
||||
$taskIds=$mtask->alias('t')->join(model('Collector')->get_table_name().' c','t.id=c.task_id')
|
||||
->field('task_id')->where("t.auto=1 and t.module='pattern'")->order('t.caijitime asc')->column('task_id');
|
||||
|
||||
if(empty($taskIds)){
|
||||
$this->echo_msg_exit('没有可自动采集的任务 <a href="'.url('Admin/Task/list').'" target="_blank">设置</a>');
|
||||
}
|
||||
$taskList=collection($taskList)->toArray();
|
||||
cache('last_collect_time',time());
|
||||
|
||||
controller('admin/Task','controller')->_collect_batch($taskList);
|
||||
|
||||
controller('admin/Task','controller')->_collect_batch($taskIds);
|
||||
|
||||
$this->echo_msg('所有任务执行完毕!','green');
|
||||
|
||||
$this->_echo_msg_end();
|
||||
}
|
||||
/*客户端信息*/
|
||||
public function clientinfoAction(){
|
||||
return json(clientinfo());
|
||||
}
|
||||
|
||||
/*验证站点*/
|
||||
public function certificateAction(){
|
||||
$data=array('code'=>0,'msg'=>'','data'=>array());
|
||||
$mprov=model('Provider');
|
||||
$resultData=$mprov->storeAuthResult();
|
||||
if(!$resultData['success']){
|
||||
|
||||
$data['msg']=$resultData['msg'];
|
||||
}else{
|
||||
$data['code']=1;
|
||||
$data['data']['clientinfo']=clientinfo();
|
||||
}
|
||||
return json($data);
|
||||
}
|
||||
|
||||
/*云平台检测更新*/
|
||||
public function store_updateAction(){
|
||||
$updateResult=array('code'=>0,'msg'=>'','data'=>array());
|
||||
|
||||
$mprov=model('Provider');
|
||||
$resultData=$mprov->storeAuthResult();
|
||||
if(!$resultData['success']){
|
||||
|
||||
$updateResult['msg']=$resultData['msg'];
|
||||
}else{
|
||||
|
||||
$resultData=$resultData['data'];
|
||||
$provId=$resultData['provider_id'];
|
||||
|
||||
$storeAddons=input('store_addons');
|
||||
$storeAddons=json_decode(base64_decode($storeAddons),true);
|
||||
$storeAddons=is_array($storeAddons)?$storeAddons:array();
|
||||
|
||||
if(!empty($storeAddons['rule'])&&is_array($storeAddons['rule'])){
|
||||
|
||||
$cond=array('store_id'=>array('in',$storeAddons['rule']),'provider_id'=>$provId);
|
||||
$list=model('Rule')->field('`id`,`store_id`,`uptime`')->where($cond)->column('uptime','store_id');
|
||||
$updateResult['data']['rule']=$list;
|
||||
}
|
||||
if(!empty($storeAddons['plugin'])&&is_array($storeAddons['plugin'])){
|
||||
|
||||
$cond=array('app'=>array('in',$storeAddons['plugin']),'provider_id'=>$provId);
|
||||
$listRelease=model('ReleaseApp')->where($cond)->column('uptime','app');
|
||||
$listRelease=is_array($listRelease)?$listRelease:array();
|
||||
$listFunc=model('FuncApp')->where($cond)->column('uptime','app');
|
||||
$listFunc=is_array($listFunc)?$listFunc:array();
|
||||
$updateResult['data']['plugin']=array_merge($listRelease,$listFunc);
|
||||
}
|
||||
if(!empty($storeAddons['app'])&&is_array($storeAddons['app'])){
|
||||
|
||||
$list=array();
|
||||
foreach ($storeAddons['app'] as $app){
|
||||
|
||||
$appVer=model('App')->app_class($app,false,'version');
|
||||
if(!empty($appVer)){
|
||||
$list[$app]=$appVer;
|
||||
}
|
||||
}
|
||||
$updateResult['data']['app']=$list;
|
||||
}
|
||||
$updateResult['code']=1;
|
||||
}
|
||||
|
||||
return json($updateResult);
|
||||
}
|
||||
}
|
|
@ -27,28 +27,18 @@ class App extends BaseController {
|
|||
|
||||
$navPacks=array();
|
||||
if(is_array($appData['config']['packs'])){
|
||||
$manageUrl=url('App/manage?app='.$app);
|
||||
$manageUrl.=strpos($manageUrl,'?')===false?'?':'&';
|
||||
foreach ($appData['config']['packs'] as $k=>$v){
|
||||
if($v['type']=='nav'){
|
||||
$v['nav_link']=str_replace(array('{app}','{apps}'), array(config('root_website').'/app/'.$app.'/',config('root_website').'/app/'),$v['nav_link']);
|
||||
if(!preg_match('/^\w+\:\/\//', $v['nav_link'])){
|
||||
|
||||
$v['nav_link']=$appUrl.$v['nav_link'];
|
||||
}
|
||||
|
||||
if(isset($navid)&&$navid==$k){
|
||||
|
||||
$v['is_current']=true;
|
||||
}
|
||||
$navPacks[$k]=$v;
|
||||
}
|
||||
}
|
||||
$navPacks=$mapp->convert_packs($appData['config']['packs'],$app,'nav',$navid);
|
||||
}
|
||||
$storeUrl='';
|
||||
$provData=null;
|
||||
$mprov=model('Provider');
|
||||
if($appData['provider_id']>0){
|
||||
$provData=$mprov->where('id',$appData['provider_id'])->find();
|
||||
$storeUrl=$provData?$provData['url']:'';
|
||||
}
|
||||
if(empty($storeUrl)&&\skycaiji\admin\model\Provider::is_official_url($appData['config']['website'])){
|
||||
|
||||
$storeUrl=1;
|
||||
}
|
||||
|
||||
$appClass=$mapp->app_class($app);
|
||||
|
@ -66,7 +56,7 @@ class App extends BaseController {
|
|||
$this->assign('navid',$navid);
|
||||
$this->assign('navPacks',$navPacks);
|
||||
$this->assign('appData',$appData);
|
||||
$this->assign('provData',$provData);
|
||||
$this->assign('storeUrl',$storeUrl);
|
||||
return $this->fetch();
|
||||
}
|
||||
/*协议*/
|
||||
|
|
|
@ -30,7 +30,7 @@ class Backstage extends BaseController{
|
|||
'os'=>php_uname('s').' '.php_uname('r'),
|
||||
'php'=>PHP_VERSION,
|
||||
'db'=>config('database.type'),
|
||||
'version'=>$GLOBALS['_sc']['c']['version']?$GLOBALS['_sc']['c']['version']:constant("SKYCAIJI_VERSION"),
|
||||
'version'=>g_sc_c('version')?g_sc_c('version'):constant("SKYCAIJI_VERSION"),
|
||||
'server'=>$_SERVER["SERVER_SOFTWARE"],
|
||||
'upload_max'=>ini_get('upload_max_filesize')
|
||||
);
|
||||
|
@ -42,33 +42,35 @@ class Backstage extends BaseController{
|
|||
|
||||
$runInfo['auto_status']='良好';
|
||||
/*设置采集状态*/
|
||||
if($GLOBALS['_sc']['c']['caiji']['auto']){
|
||||
if(g_sc_c('caiji','auto')){
|
||||
|
||||
$lastTime=cache('last_collect_time');
|
||||
$taskAutoCount=model('Task')->where('auto',1)->count();
|
||||
if($taskAutoCount<=0){
|
||||
$autoTaskCount=model('Task')->where('auto',1)->count();
|
||||
if($autoTaskCount<=0){
|
||||
|
||||
$serverData['caiji']='<a href="'.url('Admin/Task/list').'">未设置自动采集任务</a>';
|
||||
$runInfo['auto_status']='无任务';
|
||||
}else{
|
||||
|
||||
|
||||
$runInfo['auto_status']='运行良好';
|
||||
if($lastTime>0){
|
||||
$runInfo['auto_status']='运行良好';
|
||||
$serverData['caiji']='最近采集:'.date('Y-m-d H:i:s',$lastTime).' ';
|
||||
if($GLOBALS['_sc']['c']['caiji']['run']=='backstage'){
|
||||
|
||||
if(NOW_TIME-$lastTime>60*($GLOBALS['_sc']['c']['caiji']['interval']+15)){
|
||||
|
||||
$serverData['caiji'].='<p class="help-block">自动采集似乎停止了,请<a href="'.
|
||||
url('Admin/Setting/caiji').'">重新保存设置</a>以便激活采集</p>';
|
||||
$runInfo['auto_status']='停止运行';
|
||||
}
|
||||
}
|
||||
$serverData['caiji']='最近采集:'.date('Y-m-d H:i:s',$lastTime).' ';
|
||||
}
|
||||
if(g_sc_c('caiji','run')=='backstage'){
|
||||
|
||||
$collectBackstageTime=CacheModel::getInstance()->getCache('collect_backstage_time','data');
|
||||
$collectBackstageTime=intval($collectBackstageTime);
|
||||
if((time()-$collectBackstageTime)>60*3){
|
||||
|
||||
$runInfo['auto_status']='停止运行';
|
||||
$serverData['caiji'].='<p class="help-block">自动采集停止了,请重新<a href="'.url('Admin/Setting/caiji').'">保存设置</a>以便激活采集</p>';
|
||||
}
|
||||
}
|
||||
|
||||
$serverData['caiji'].='<a href="javascript:;" id="a_collect_now">实时采集</a>';
|
||||
}
|
||||
}else{
|
||||
$runInfo['auto_status']='已停止';
|
||||
$runInfo['auto_status']='未开启';
|
||||
$serverData['caiji']='<a href="'.url('Admin/Setting/caiji').'">未开启自动采集</a>';
|
||||
}
|
||||
|
||||
|
@ -82,14 +84,29 @@ class Backstage extends BaseController{
|
|||
$systemData=$LocSystem->environment();
|
||||
|
||||
$systemWarning=array('php'=>array(),'path_write'=>array(),'path_read'=>array());
|
||||
|
||||
if(is_array($systemData['php'])){
|
||||
foreach ($systemData['php'] as $k=>$v){
|
||||
if(empty($v[1])){
|
||||
if(empty($v['loaded'])){
|
||||
|
||||
$systemWarning['php'][$v[0]]=$v[0];
|
||||
$systemWarning['php'][$v['name']]=$v['name'];
|
||||
}elseif(!empty($v['lack'])){
|
||||
|
||||
$systemWarning['php'][$v['name']]=$v['name'].' (需支持'.$v['lack'].')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(model('Config')->server_is_cli()||g_sc_c('page_render','tool')){
|
||||
|
||||
$procFuncs=array('proc_open','proc_get_status','proc_terminate','proc_close');
|
||||
foreach ($procFuncs as $procFunc){
|
||||
if(!function_exists($procFunc)){
|
||||
$systemWarning['php'][$procFunc]=$procFunc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(is_array($systemData['path'])){
|
||||
foreach ($systemData['path'] as $k=>$v){
|
||||
if(empty($v[1])){
|
||||
|
@ -114,36 +131,113 @@ class Backstage extends BaseController{
|
|||
}
|
||||
|
||||
|
||||
|
||||
$adminIndexData=cache('backstage_admin_index');
|
||||
|
||||
|
||||
$timeout=NOW_TIME-(3600*24*30);
|
||||
$timeout=time()-(3600*24*30);
|
||||
$mcacheSource=CacheModel::getInstance('source_url');
|
||||
$mcacheSource->db()->where('dateline','<',$timeout)->delete();
|
||||
$mcacheLevel=CacheModel::getInstance('level_url');
|
||||
$mcacheLevel->db()->where('dateline','<',$timeout)->delete();
|
||||
|
||||
$timeout=NOW_TIME-(3600*24);
|
||||
$timeout=time()-(3600*24);
|
||||
$mcacheCont=CacheModel::getInstance('cont_url');
|
||||
$mcacheCont->db()->where('dateline','<',$timeout)->delete();
|
||||
|
||||
$GLOBALS['_sc']['p_name']='后台管理';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Backstage/index'),'title'=>'首页')));
|
||||
$openBasedir=null;
|
||||
if(!cache('ignore_open_basedir_tips')){
|
||||
|
||||
$openBasedir=ini_get('open_basedir');
|
||||
if(!empty($openBasedir)){
|
||||
$openBasedir=explode(IS_WIN?';':':', $openBasedir);
|
||||
$openBasedir=implode('、', $openBasedir);
|
||||
}
|
||||
}
|
||||
|
||||
set_g_sc('p_name','后台管理');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Backstage/index'),'title'=>'首页'))));
|
||||
|
||||
$this->assign('runInfo',$runInfo);
|
||||
$this->assign('serverData',$serverData);
|
||||
$this->assign('upgradeDb',$upgradeDb);
|
||||
$this->assign('systemWarning',$systemWarning);
|
||||
$this->assign('adminIndexData',$adminIndexData);
|
||||
$this->assign('openBasedir',$openBasedir);
|
||||
|
||||
return $this->fetch('backstage/index');
|
||||
}
|
||||
|
||||
|
||||
public function checkUpAction(){
|
||||
$info=array(
|
||||
'pageRenderInvalid'=>false,
|
||||
'phpInvalid'=>false,
|
||||
);
|
||||
|
||||
$mconfig=model('Config');
|
||||
|
||||
if($mconfig->server_is_cli()){
|
||||
|
||||
$phpvInfo=$mconfig->exec_php_version(g_sc_c('caiji','server_php'));
|
||||
if(empty($phpvInfo)||!$phpvInfo['success']){
|
||||
$info['phpInvalid']=true;
|
||||
}
|
||||
}
|
||||
|
||||
$autoTaskIds=model('Task')->where('auto',1)->column('id');
|
||||
if(!empty($autoTaskIds)){
|
||||
foreach ($autoTaskIds as $autoTaskId){
|
||||
$collConfig=model('Collector')->where('task_id',$autoTaskId)->value('config');
|
||||
|
||||
$collConfig=unserialize($collConfig);
|
||||
if($collConfig['page_render']){
|
||||
|
||||
$pageRender=g_sc_c('page_render');
|
||||
if(empty($pageRender['tool'])){
|
||||
|
||||
$info['pageRenderInvalid']=true;
|
||||
}elseif($mconfig->page_render_is_chrome()){
|
||||
|
||||
$chromeSoket=new \util\ChromeSocket($pageRender['chrome']['host'],$pageRender['chrome']['port'],$pageRender['timeout'],$pageRender['chrome']['filename'],$pageRender['chrome']);
|
||||
$info['pageRenderInvalid']=$chromeSoket->hostIsOpen()?false:true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('','',$info);
|
||||
}
|
||||
|
||||
/*实时采集*/
|
||||
public function collectAction(){
|
||||
remove_auto_collecting();
|
||||
controller('admin/Api','controller')->collectAction();
|
||||
}
|
||||
|
||||
/*检测更新*/
|
||||
public function newVersionAction(){
|
||||
$version=curl_skycaiji('/client/info/version?v='.SKYCAIJI_VERSION);
|
||||
$version=json_decode($version,true);
|
||||
$version=is_array($version)?$version:array();
|
||||
$new_version=trim($version['new_version']);
|
||||
$cur_version=g_sc_c('version');
|
||||
|
||||
|
||||
if(version_compare($new_version,$cur_version,'>')){
|
||||
|
||||
$version['is_new_version']=true;
|
||||
}
|
||||
|
||||
$cacheIx=cache('backstage_admin_index');
|
||||
if(empty($cacheIx)||$cacheIx['ver']!=$version['admin_index_ver']){
|
||||
$version['is_new_admin_index']=true;
|
||||
}
|
||||
|
||||
$this->success('',null,$version);
|
||||
}
|
||||
|
||||
|
||||
/*获取推送消息*/
|
||||
public function adminIndexAction(){
|
||||
$refresh=input('refresh');
|
||||
|
@ -151,8 +245,9 @@ class Backstage extends BaseController{
|
|||
$data=is_array($data)?$data:array();
|
||||
if($refresh||empty($data['html'])){
|
||||
|
||||
$data=get_html('https://www.skycaiji.com/store/client/adminIndex?v='.SKYCAIJI_VERSION,null,null,'utf-8');
|
||||
$data=curl_skycaiji('/client/info/push?v='.SKYCAIJI_VERSION);
|
||||
$data=json_decode($data,true);
|
||||
$data=is_array($data)?$data:array();
|
||||
|
||||
$data=array(
|
||||
'ver'=>$data['ver'],
|
||||
|
@ -230,8 +325,10 @@ class Backstage extends BaseController{
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count=$mcache->db()->where('ctype',$taskType)->count();
|
||||
|
||||
|
||||
$count0=$mcache->db()->where('ctype',0)->count();
|
||||
$count1=$mcache->db()->where('ctype',1)->count();
|
||||
|
||||
$this->assign('list',$list);
|
||||
$this->assign('cacheList',$cacheList);
|
||||
|
@ -239,7 +336,7 @@ class Backstage extends BaseController{
|
|||
$this->assign('pagenav',$pagenav);
|
||||
$html=$this->fetch('bk_task_list')->getContent();
|
||||
|
||||
$this->success('',null,array('html'=>$html,'count'=>$count));
|
||||
$this->success('',null,array('html'=>$html,'count0'=>$count0,'count1'=>$count1));
|
||||
}elseif('collected'==$op){
|
||||
$taskId=input('tid/d');
|
||||
if($taskId<=0){
|
||||
|
@ -274,6 +371,12 @@ class Backstage extends BaseController{
|
|||
}
|
||||
|
||||
|
||||
public function ignoreOpenBasedirAction(){
|
||||
cache('ignore_open_basedir_tips',1);
|
||||
$this->success();
|
||||
}
|
||||
|
||||
|
||||
public function createJsLangAction(){
|
||||
$langs=array();
|
||||
$langs['zh-cn']='zh-cn';
|
||||
|
@ -291,12 +394,13 @@ class Backstage extends BaseController{
|
|||
$tpl_lang=array_merge($common_lang,$module_lang);
|
||||
|
||||
$tpl_lang='var tpl_lang='.json_encode($tpl_lang).';';
|
||||
|
||||
|
||||
write_dir_file(config('root_path').'/public/static/js/langs/'.$lv.'.js',$tpl_lang);
|
||||
echo "ok{$lv}<br>";
|
||||
echo "ok:{$lv}<br>";
|
||||
}
|
||||
}
|
||||
/* 排查重复的语言变量 */
|
||||
|
||||
|
||||
public function checkRepeatLangAction() {
|
||||
$file = config ( 'app_path' ) . '/admin/lang/zh-cn.php';
|
||||
$txt = file_get_contents ( $file );
|
||||
|
@ -311,5 +415,4 @@ class Backstage extends BaseController{
|
|||
}
|
||||
print_r ( $repeatList );
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,17 @@
|
|||
namespace skycaiji\admin\controller;
|
||||
|
||||
class BaseController extends \skycaiji\common\controller\BaseController{
|
||||
protected function _initialize(){
|
||||
|
||||
if(request()->isPost()){
|
||||
$curController=strtolower(request()->controller());
|
||||
|
||||
if($curController!='api'){
|
||||
$this->check_usertoken();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*输出模板:防止ajax时乱码*/
|
||||
public function fetch($template = '', $vars = [], $replace = [], $config = []){
|
||||
if(request()->isAjax()){
|
||||
|
@ -24,60 +35,179 @@ class BaseController extends \skycaiji\common\controller\BaseController{
|
|||
|
||||
/*输出内容函数*/
|
||||
private static $echo_msg_head=null;
|
||||
public function echo_msg($str,$color='red',$echo=true,$end_str=''){
|
||||
public function echo_msg($str,$color='red',$echo=true,$end_str='',$div_style=''){
|
||||
if(defined('CLOSE_ECHO_MSG')){
|
||||
$echo=false;
|
||||
}
|
||||
if($echo){
|
||||
$color=empty($color)?'red':$color;
|
||||
|
||||
$isBackstage=input('?backstage');
|
||||
|
||||
$logid=input('logid','');
|
||||
$logFilename=\skycaiji\admin\model\Collector::echo_msg_log_filename($logid);
|
||||
$differSeconds=input('differ_seconds/d',0);
|
||||
|
||||
if(!isset(self::$echo_msg_head)){
|
||||
self::$echo_msg_head=true;
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
header('X-Accel-Buffering: no');
|
||||
@ini_set('output_buffering','Off');
|
||||
|
||||
ob_end_clean();
|
||||
@ob_implicit_flush(1);
|
||||
|
||||
$outputSize=ini_get('output_buffering');
|
||||
$outputSize=intval($outputSize);
|
||||
|
||||
if(preg_match('/\biis\b/i', $_SERVER["SERVER_SOFTWARE"])){
|
||||
|
||||
if($outputSize<1024*1024*4){
|
||||
|
||||
$outputSize=1024*1024*4;
|
||||
echo '<!-- iis默认需输出4mb数据才能实时显示-->';
|
||||
}
|
||||
if(file_exists($logFilename)){
|
||||
|
||||
unlink($logFilename);
|
||||
}
|
||||
echo '<style type="text/css">body{padding:0 5px;font-size:14px;color:#000;}p{padding:0;margin:0;}a{color:#aaa;}</style>';
|
||||
|
||||
$allowOutput=false;
|
||||
if($outputSize>1024*1024){
|
||||
|
||||
$mobileDetect=new \util\MobileDetect();
|
||||
if(!$mobileDetect->isMobile()){
|
||||
|
||||
$allowOutput=true;
|
||||
}
|
||||
}else{
|
||||
$allowOutput=true;
|
||||
if(!file_exists($logFilename)){
|
||||
|
||||
write_dir_file($logFilename,'');
|
||||
}
|
||||
if($allowOutput){
|
||||
echo str_pad(' ', $outputSize>1050?($outputSize+100):1050);
|
||||
|
||||
try {
|
||||
register_shutdown_function(array($this,'_echo_msg_end'));
|
||||
}catch (\Exception $ex){}
|
||||
|
||||
|
||||
if(!$isBackstage){
|
||||
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
header('X-Accel-Buffering: no');
|
||||
@ini_set('output_buffering','Off');
|
||||
|
||||
@ob_end_clean();
|
||||
@ob_implicit_flush(1);
|
||||
|
||||
$outputSize=ini_get('output_buffering');
|
||||
$outputSize=intval($outputSize);
|
||||
|
||||
if(preg_match('/\biis\b/i', $_SERVER["SERVER_SOFTWARE"])){
|
||||
|
||||
if($outputSize<1024*1024*4){
|
||||
|
||||
$outputSize=1024*1024*4;
|
||||
echo '<!-- iis默认需输出4mb数据才能实时显示-->';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$info=array(
|
||||
'js_time'=>time()-$differSeconds,
|
||||
'server'=>\util\Funcs::web_server_name(),
|
||||
'is_backstage'=>$isBackstage,
|
||||
'server_is_cli'=>model('Config')->server_is_cli(),
|
||||
);
|
||||
$info=json_encode($info);
|
||||
|
||||
$cssJs='<style type="text/css">'
|
||||
.'body{padding:0 5px;font-size:14px;color:#000;line-height:20px;}p{padding:0;margin:0;}a{color:#aaa;}'
|
||||
.'.clear{width:100%;overflow:hidden;clear:both;}.left{float:left;}'
|
||||
.'.lurl{float:left;margin-right:3px;height:20px;max-width:70%;overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;word-break:break-all;}'
|
||||
.'</style>'
|
||||
.'<script type="text/javascript">window.parent.window.collectorEchoMsg("start",'.$info.');</script>';
|
||||
|
||||
$this->_echo_msg_output($cssJs, $logFilename);
|
||||
|
||||
if(!$isBackstage){
|
||||
|
||||
$allowOutput=false;
|
||||
if($outputSize>1024*1024){
|
||||
|
||||
$mobileDetect=new \util\MobileDetect();
|
||||
if(!$mobileDetect->isMobile()){
|
||||
|
||||
$allowOutput=true;
|
||||
}
|
||||
}else{
|
||||
$allowOutput=true;
|
||||
}
|
||||
if($allowOutput){
|
||||
if($outputSize<1024*100){
|
||||
|
||||
echo str_pad(' ', $outputSize>1050?($outputSize+100):1050);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '<p style="color:'.$color.';">'.$str.'</p>'.$end_str;
|
||||
if(ob_get_level()>0){
|
||||
ob_flush();
|
||||
flush();
|
||||
|
||||
$txt='<div style="color:'.$color.';'.$div_style.'">'.$str.'</div>'.$end_str;
|
||||
|
||||
$this->_echo_msg_output($txt, $logFilename);
|
||||
|
||||
if(!$isBackstage){
|
||||
|
||||
if(ob_get_level()>0){
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*保留旧的入口*/
|
||||
public function indexAction(){
|
||||
if(strtolower(request()->controller())=='base'){
|
||||
|
||||
$this->redirect('Admin/Backstage/index');
|
||||
}
|
||||
|
||||
public function echo_msg_exit($str,$color='red',$echo=true,$end_str='',$div_style=''){
|
||||
$this->echo_msg($str,$color,$echo,$end_str,$div_style);
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
private static $echo_msg_end=null;
|
||||
public function _echo_msg_end(){
|
||||
if(!isset(self::$echo_msg_end)){
|
||||
self::$echo_msg_end=true;
|
||||
$this->echo_msg('','',true,\skycaiji\admin\model\Collector::echo_msg_end_js(),'display:none;');
|
||||
}
|
||||
}
|
||||
|
||||
private function _echo_msg_output($txt,$logFilename){
|
||||
$isBackstage=input('?backstage');
|
||||
if(!file_exists($logFilename)){
|
||||
|
||||
if(!$isBackstage){
|
||||
|
||||
echo \skycaiji\admin\model\Collector::echo_msg_end_js();
|
||||
}
|
||||
exit();
|
||||
}
|
||||
if($isBackstage){
|
||||
|
||||
write_dir_file($logFilename,$txt.PHP_EOL,FILE_APPEND);
|
||||
}else{
|
||||
|
||||
echo $txt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function _backstage_cli_collect($cliStr){
|
||||
if(input('?backstage')){
|
||||
|
||||
$logid=input('logid','');
|
||||
ignore_user_abort(true);
|
||||
if(empty($logid)){
|
||||
|
||||
define('CLOSE_ECHO_MSG',true);
|
||||
}
|
||||
if(!IS_CLI){
|
||||
|
||||
if(model('admin/Config')->server_is_cli()){
|
||||
|
||||
if(!empty($logid)){
|
||||
$cliStr.=' --logid '.base64_encode($logid);
|
||||
}
|
||||
cli_command_exec('collect '.$cliStr);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
ignore_user_abort(false);
|
||||
$sUserlogin=session('user_login');
|
||||
if(empty($sUserlogin)){
|
||||
|
||||
define('CLOSE_ECHO_MSG',true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function check_usertoken(){
|
||||
if(g_sc('usertoken')!=input('_usertoken_')){
|
||||
$this->error(lang('usertoken_error'),'');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,8 +76,10 @@ class Collected extends BaseController {
|
|||
$taskList=model('Task')->where(array('id'=>array('in',$taskIds)))->column('name','id');
|
||||
}
|
||||
}
|
||||
$GLOBALS['_sc']['p_name']=lang('collected_list');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Collected/list'),'title'=>'已采集数据'),array('url'=>url('Collected/list'),'title'=>'数据列表')));
|
||||
|
||||
set_g_sc('p_title',lang('collected_list'));
|
||||
set_g_sc('p_name',lang('collected_list'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Collected/list'),'title'=>'已采集数据'),array('url'=>url('Collected/list'),'title'=>'数据列表'))));
|
||||
}
|
||||
$this->assign('search',$search);
|
||||
$this->assign('dataList',$dataList);
|
||||
|
@ -115,7 +117,7 @@ class Collected extends BaseController {
|
|||
$this->success(lang('delete_success'));
|
||||
}elseif($op=='deleteall'){
|
||||
|
||||
$ids=input('ids/a',0,'intval');
|
||||
$ids=input('ids/a',array(),'intval');
|
||||
if(is_array($ids)&&count($ids)>0){
|
||||
$mcollected->where(array('id'=>array('in',$ids)))->delete();
|
||||
}
|
||||
|
@ -124,8 +126,9 @@ class Collected extends BaseController {
|
|||
}
|
||||
/*图表显示*/
|
||||
public function chartAction(){
|
||||
$GLOBALS['_sc']['p_name']='已采集数据:统计图表';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Collected/list'),'title'=>'已采集数据'),array('url'=>url('Collected/chart'),'title'=>'统计图表')));
|
||||
set_g_sc('p_title','已采集数据:统计图表');
|
||||
set_g_sc('p_name','已采集数据:统计图表');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Collected/list'),'title'=>'已采集数据'),array('url'=>url('Collected/chart'),'title'=>'统计图表'))));
|
||||
|
||||
return $this->fetch();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*/
|
||||
|
||||
namespace skycaiji\admin\controller;
|
||||
use skycaiji\admin\model\CacheModel;
|
||||
use skycaiji\admin\model\FuncApp;
|
||||
|
||||
class Collector extends BaseController {
|
||||
public function indexAction(){
|
||||
|
@ -33,7 +35,8 @@ class Collector extends BaseController {
|
|||
}
|
||||
$collData=$mcoll->where(array('task_id'=>$taskData['id'],'module'=>$taskData['module']))->find();
|
||||
if(request()->isPost()){
|
||||
$effective=input('effective');
|
||||
$effective=input('effective');
|
||||
$effectiveEdit=input('effective_edit');
|
||||
if(empty($effective)){
|
||||
|
||||
$this->error(lang('coll_error_empty_effective'));
|
||||
|
@ -44,18 +47,24 @@ class Collector extends BaseController {
|
|||
if(!in_array($module,config('allow_coll_modules'))){
|
||||
$this->error(lang('coll_error_invalid_module'));
|
||||
}
|
||||
$config=input('post.config/a',null,'trim');
|
||||
$config=array_array_map('trim',$config);
|
||||
|
||||
$config=input('post.config/a',array(),'trim');
|
||||
$config=\util\Funcs::array_array_map('trim',$config);
|
||||
|
||||
$acoll=controller('admin/C'.$module,'event');
|
||||
$config=$acoll->setConfig($config);
|
||||
|
||||
$newColl=array('name'=>$name,'module'=>$module,'task_id'=>$taskId,'config'=>serialize($config),'uptime'=>NOW_TIME);
|
||||
$collId=$collData['id'];
|
||||
$newColl=array('name'=>$name,'module'=>$module,'task_id'=>$taskId,'config'=>serialize($config),'uptime'=>time());
|
||||
$collId=0;
|
||||
if(empty($collData)){
|
||||
|
||||
$collId=$mcoll->add_new($newColl);
|
||||
}else{
|
||||
|
||||
$collId=$collData['id'];
|
||||
if(empty($effectiveEdit)){
|
||||
|
||||
$this->error(lang('coll_error_empty_effective'));
|
||||
}
|
||||
$mcoll->edit_by_id($collId,$newColl);
|
||||
}
|
||||
if($collId>0){
|
||||
|
@ -67,15 +76,22 @@ class Collector extends BaseController {
|
|||
}else{
|
||||
if(!empty($collData)){
|
||||
$collData['config']=unserialize($collData['config']);
|
||||
if(!is_array($collData['config'])){
|
||||
$collData['config']=array();
|
||||
}
|
||||
$collData['config']=$mcoll->compatible_config($collData['config']);
|
||||
}else{
|
||||
$collData=array();
|
||||
}
|
||||
$GLOBALS['_sc']['p_name']=lang('coll_set').lang('separator').lang('task_module_'.$taskData['module']);
|
||||
set_g_sc('p_title',lang('coll_set').'_任务:'.$taskData['name']);
|
||||
set_g_sc('p_name',lang('coll_set').lang('separator').lang('task_module_'.$taskData['module']));
|
||||
if(input('?easymode')){
|
||||
$GLOBALS['_sc']['p_name'].=' <small><a href="'.url('Collector/set?task_id='.$taskId).'" onclick="if(window.top){window.top.location.href=$(this).attr(\'href\');return false;}">普通模式</a></small>';
|
||||
set_g_sc('p_name', g_sc('p_name').' <small><a href="'.url('Collector/set?task_id='.$taskId).'" onclick="if(window.top){window.top.location.href=$(this).attr(\'href\');return false;}" title="切换普通模式">普通模式</a></small>');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name'].=' <small><a href="'.url('Cpattern/easymode?task_id='.$taskId).'">简单模式</a></small>';
|
||||
set_g_sc('p_name', g_sc('p_name').' <small><a href="'.url('Cpattern/easymode?task_id='.$taskId).'" title="切换简单模式">简单模式</a></small>');
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Collector/set?task_id='.$taskData['id']),'title'=>lang('coll_set'))));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Collector/set?task_id='.$taskData['id']),'title'=>lang('coll_set')))));
|
||||
$this->assign('collData',$collData);
|
||||
$this->assign('taskData',$taskData);
|
||||
return $this->fetch();
|
||||
|
@ -116,31 +132,6 @@ class Collector extends BaseController {
|
|||
$this->assign('collList',$collList);
|
||||
return $this->fetch('list'.(input('tpl')?'_'.input('tpl'):''));
|
||||
}
|
||||
/*保存到云端*/
|
||||
public function save2storeAction(){
|
||||
$coll_id=input('coll_id/d',0);
|
||||
$mcoll=model('Collector');
|
||||
$collData=$mcoll->where(array('id'=>$coll_id))->find();
|
||||
if(empty($collData)){
|
||||
$this->error(lang('coll_error_empty_coll'));
|
||||
}
|
||||
$collData=$collData->toArray();
|
||||
if(!in_array($collData['module'],config('allow_coll_modules'))){
|
||||
$this->error(lang('coll_error_invalid_module'));
|
||||
}
|
||||
$config=unserialize($collData['config']);
|
||||
if(empty($config)){
|
||||
$this->error('规则不存在');
|
||||
}
|
||||
if(empty($config['source_url'])){
|
||||
$this->error('请先完善起始页网址!');
|
||||
}
|
||||
if(empty($config['field_list'])){
|
||||
$this->error('请先完善字段列表!');
|
||||
}
|
||||
$this->assign('collData',$collData);
|
||||
return $this->fetch();
|
||||
}
|
||||
/*导出规则*/
|
||||
public function exportAction(){
|
||||
$coll_id=input('coll_id/d',0);
|
||||
|
@ -175,11 +166,178 @@ class Collector extends BaseController {
|
|||
header("Content-transfer-encoding: binary");
|
||||
header("Accept-Length: " .mb_strlen($txt));
|
||||
if (preg_match("/MSIE/i", $_SERVER["HTTP_USER_AGENT"])) {
|
||||
header('Content-Disposition: attachment; filename="'.urlencode($name).'.skycaiji"');
|
||||
header('Content-Disposition: attachment; filename="'.urlencode($name).'.scj"');
|
||||
}else{
|
||||
header('Content-Disposition: attachment; filename="'.$name.'.skycaiji"');
|
||||
header('Content-Disposition: attachment; filename="'.$name.'.scj"');
|
||||
}
|
||||
echo $txt;
|
||||
ob_end_flush();
|
||||
}
|
||||
|
||||
|
||||
public function echo_msgAction(){
|
||||
$op=input('op');
|
||||
$mcache=CacheModel::getInstance();
|
||||
$cBackstageName='echo_msg_backstage';
|
||||
$cIntervalName='echo_msg_interval';
|
||||
if($op=='set_backstage'){
|
||||
|
||||
$isBackstage=input('backstage/d',0);
|
||||
$isBackstage=$isBackstage>0?1:0;
|
||||
$mcache->setCache($cBackstageName,$isBackstage);
|
||||
if(model('Config')->server_is_cli()){
|
||||
|
||||
$isBackstage=$isBackstage?'cli后台':'web服务器';
|
||||
}else{
|
||||
|
||||
$isBackstage=$isBackstage?'后台':'实时';
|
||||
}
|
||||
|
||||
$this->success('已设置为'.$isBackstage.'模式,请重试采集','');
|
||||
}elseif($op=='set_interval'){
|
||||
|
||||
$interval=input('interval/d',2);
|
||||
$mcache->setCache($cIntervalName,$interval);
|
||||
$this->success('设置成功','');
|
||||
}elseif($op=='collect'){
|
||||
|
||||
$jsTime=input('js_time',0);
|
||||
$jsTime=substr($jsTime,0,-3);
|
||||
$jsTime=intval($jsTime);
|
||||
|
||||
$differSeconds=time()-$jsTime;
|
||||
|
||||
$isBackstage=$mcache->getCache($cBackstageName,'data');
|
||||
$interval=$mcache->getCache($cIntervalName,'data');
|
||||
$interval=intval($interval);
|
||||
if($interval<=0){
|
||||
$interval=2;
|
||||
}
|
||||
$this->assign('is_backstage',$isBackstage);
|
||||
$this->assign('interval',$interval);
|
||||
$this->assign('server_is_cli',model('Config')->server_is_cli());
|
||||
$this->assign('differ_seconds',$differSeconds);
|
||||
return $this->fetch('echo_msg_collect');
|
||||
}elseif($op=='read'){
|
||||
|
||||
$list=array();
|
||||
$logid=input('logid','');
|
||||
$line=input('line/d');
|
||||
$line=empty($line)?0:($line+1);
|
||||
|
||||
$filename=\skycaiji\admin\model\Collector::echo_msg_log_filename($logid);
|
||||
if(file_exists($filename)){
|
||||
$max=30;
|
||||
$num=0;
|
||||
if(class_exists('SplFileObject')){
|
||||
|
||||
$sfo = new \SplFileObject($filename, 'r');
|
||||
if($sfo->seek($line)==0){
|
||||
while (!$sfo->eof()&&$num<$max) {
|
||||
$txt=$sfo->current();
|
||||
$list[$sfo->key()]=$txt;
|
||||
$sfo->next();
|
||||
$num++;
|
||||
}
|
||||
}
|
||||
$sfo=null;
|
||||
unset($sfo);
|
||||
}else{
|
||||
|
||||
$fp = fopen($filename,'r');
|
||||
while (!feof($fp)&&$num<$max) {
|
||||
$txt=fgets($fp);
|
||||
if($num>=$line){
|
||||
|
||||
$list[$num]=$txt;
|
||||
}
|
||||
$num++;
|
||||
}
|
||||
fclose($fp);
|
||||
unset($fp);
|
||||
}
|
||||
|
||||
$isEnd=false;
|
||||
foreach ($list as $k=>$txt){
|
||||
if(!$isEnd&&strpos($txt,'data-echo-msg-is-end')!==false){
|
||||
|
||||
$isEnd=true;
|
||||
}
|
||||
$txt=preg_replace('/<[^<>]*\bsection\b[^<>]*>/i', '', $txt);
|
||||
$list[$k]=$txt;
|
||||
}
|
||||
if($isEnd){
|
||||
if(file_exists($filename)){
|
||||
unlink($filename);
|
||||
}
|
||||
}
|
||||
}elseif($line>0){
|
||||
|
||||
$list[$line]=\skycaiji\admin\model\Collector::echo_msg_end_js();
|
||||
}
|
||||
|
||||
$list=array_filter($list);
|
||||
$data=array('list'=>$list,'line'=>0);
|
||||
if(!empty($list)){
|
||||
|
||||
$data['line']=max(array_keys($list));
|
||||
$data['line']=intval($data['line']);
|
||||
if($data['line']<0){
|
||||
$data['line']=0;
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('','',$data);
|
||||
}elseif($op=='stop'){
|
||||
|
||||
$logid=input('logid','');
|
||||
$filename=\skycaiji\admin\model\Collector::echo_msg_log_filename($logid);
|
||||
if(file_exists($filename)){
|
||||
unlink($filename);
|
||||
}
|
||||
$this->success('','');
|
||||
}
|
||||
}
|
||||
|
||||
public function plugin_funcAction(){
|
||||
$module=input('module');
|
||||
if(empty($module)){
|
||||
$this->error('模块错误');
|
||||
}
|
||||
$mfuncApp=new FuncApp();
|
||||
|
||||
$cacheName='cache_plugin_func_method_'.$module;
|
||||
$cacheFuncs=cache($cacheName);
|
||||
|
||||
$enableApps=$mfuncApp->where(array('module'=>$module,'enable'=>1))->column('uptime','app');
|
||||
|
||||
foreach ($enableApps as $k=>$v){
|
||||
$appFilename=$mfuncApp->filename($module, $k);
|
||||
if(file_exists($appFilename)){
|
||||
$v.=','.filemtime($appFilename);
|
||||
}
|
||||
$enableApps[$k]=$v;
|
||||
}
|
||||
ksort($enableApps);
|
||||
$enableApps=md5(serialize($enableApps));
|
||||
|
||||
$apps=array();
|
||||
if(empty($cacheFuncs)||$enableApps!=$cacheFuncs['key']||abs(time()-$cacheFuncs['time'])>3600){
|
||||
|
||||
$appList=$mfuncApp->where(array('module'=>$module,'enable'=>1))->column('uptime','app');
|
||||
$apps=array();
|
||||
if(!empty($appList)){
|
||||
foreach ($appList as $k=>$v){
|
||||
$appClass=$mfuncApp->get_app_class($module,$k,array('comment_cut'=>1,'method_params'=>1));
|
||||
if(!empty($appClass['methods'])&&is_array($appClass['methods'])){
|
||||
$apps[$k]=$appClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
cache($cacheName,array('list'=>$apps,'time'=>time(),'key'=>md5(serialize($appList))));
|
||||
}else{
|
||||
$apps=$cacheFuncs['list'];
|
||||
}
|
||||
$this->success('',null,$apps);
|
||||
}
|
||||
}
|
|
@ -11,16 +11,14 @@
|
|||
|
||||
namespace skycaiji\admin\controller;
|
||||
|
||||
use skycaiji\admin\model\FuncApp;
|
||||
/*采集器:规则采集*/
|
||||
class Cpattern extends BaseController {
|
||||
/**
|
||||
* 起始页网址
|
||||
*/
|
||||
public function sourceAction(){
|
||||
$is_sub=input('sub');
|
||||
if(request()->isPost()&&$is_sub){
|
||||
$source=input('source/a','','trim');
|
||||
if(request()->isPost()&&input('is_submit')){
|
||||
$source=input('source/a',array(),'trim');
|
||||
if($source['type']=='custom'){
|
||||
|
||||
if(preg_match_all('/^\w+\:\/\/[^\r\n]+/im',$source['urls'],$urls)){
|
||||
|
@ -157,9 +155,9 @@ class Cpattern extends BaseController {
|
|||
* 字段
|
||||
*/
|
||||
public function fieldAction(){
|
||||
if(request()->isPost()){
|
||||
if(request()->isPost()&&input('is_submit')){
|
||||
$objid=input('post.objid');
|
||||
$field=input('post.field/a',null,'trim');
|
||||
$field=input('post.field/a',array(),'trim');
|
||||
if(empty($field['name'])){
|
||||
$this->error('请输入字段名称');
|
||||
}
|
||||
|
@ -172,7 +170,6 @@ class Cpattern extends BaseController {
|
|||
case 'auto':if(empty($field['auto']))$this->error('请选择自动获取的类型');break;
|
||||
case 'xpath':if(empty($field['xpath']))$this->error('XPath规则不能为空!');break;
|
||||
case 'json':if(empty($field['json']))$this->error('提取规则不能为空!');break;
|
||||
case 'page':if(empty($field['page']))$this->error('请选择页面!');if(empty($field['page_rule']))$this->error('规则不能为空!');break;
|
||||
case 'num':
|
||||
$randNum=0;
|
||||
$field['num_start']=intval($field['num_start']);
|
||||
|
@ -194,12 +191,11 @@ class Cpattern extends BaseController {
|
|||
'auto' =>'auto',
|
||||
'xpath' =>array('xpath','xpath_multi','xpath_multi_type','xpath_multi_str','xpath_attr','xpath_attr_custom'),
|
||||
'json' =>array('json','json_arr','json_arr_implode','json_loop'),
|
||||
'page' =>array('page','page_rule','page_rule_merge','page_rule_multi','page_rule_multi_str'),
|
||||
'words' =>'words',
|
||||
'num' => array('num_start','num_end'),
|
||||
'time' => array ('time_format','time_start','time_end','time_stamp'),
|
||||
'list' => 'list',
|
||||
'extract' =>array('extract','extract_module','extract_rule','extract_xpath','extract_xpath_attr','extract_xpath_attr_custom','extract_json','extract_json_arr','extract_json_arr_implode'),
|
||||
'extract' =>array('extract','extract_module','extract_rule','extract_rule_merge','extract_rule_multi','extract_rule_multi_str','extract_xpath','extract_xpath_attr','extract_xpath_attr_custom','extract_xpath_multi','extract_xpath_multi_str','extract_json','extract_json_arr','extract_json_arr_implode'),
|
||||
'merge' => 'merge',
|
||||
'sign' => 'sign'
|
||||
);
|
||||
|
@ -241,9 +237,21 @@ class Cpattern extends BaseController {
|
|||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 数据处理
|
||||
*/
|
||||
/*复制字段*/
|
||||
public function clone_fieldAction(){
|
||||
if(request()->isPost()){
|
||||
$field=input('field','','url_b64decode');
|
||||
$field=$field?json_decode($field,true):array();
|
||||
$process=input('process','','url_b64decode');
|
||||
$process=$process?json_decode($process,true):'';
|
||||
|
||||
$this->success('',null,array('field'=>$field,'process'=>$process));
|
||||
}else{
|
||||
$this->error('复制失败');
|
||||
}
|
||||
}
|
||||
|
||||
/*数据处理*/
|
||||
public function processAction(){
|
||||
$type=input('type');
|
||||
|
||||
|
@ -252,9 +260,9 @@ class Cpattern extends BaseController {
|
|||
|
||||
|
||||
$transApiLangs=null;
|
||||
if(!empty($GLOBALS['_sc']['c']['translate'])&&!empty($GLOBALS['_sc']['c']['translate']['open'])){
|
||||
if(!is_empty(g_sc_c('translate'))&&!is_empty(g_sc_c('translate','open'))){
|
||||
|
||||
$transApiLangs=\util\Translator::get_api_langs($GLOBALS['_sc']['c']['translate']['api']);
|
||||
$transApiLangs=\util\Translator::get_api_langs(g_sc_c('translate','api'));
|
||||
$transApiLangs=$transApiLangs?$transApiLangs:null;
|
||||
}
|
||||
$this->assign('transApiLangs',$transApiLangs);
|
||||
|
@ -270,16 +278,11 @@ class Cpattern extends BaseController {
|
|||
return $this->fetch();
|
||||
}elseif($op=='sub'){
|
||||
|
||||
$process=input('process/a',null,'trim');
|
||||
$process=array_array_map('trim', $process);
|
||||
$process=trim_input_array('process');
|
||||
if(empty($process)){
|
||||
$process='';
|
||||
}else{
|
||||
foreach($process as $k=>$v){
|
||||
if(!empty($v['title'])){
|
||||
$process[$k]['title']=str_replace(array("'",'"'),'',strip_tags($v['title']));
|
||||
}
|
||||
}
|
||||
$process=controller('admin/Cpattern','event')->set_process($process);
|
||||
}
|
||||
$objid=input('objid','');
|
||||
$this->success('',null,array('process'=>$process,'process_json'=>empty($process)?'':json_encode($process),'objid'=>$objid));
|
||||
|
@ -290,45 +293,53 @@ class Cpattern extends BaseController {
|
|||
return $this->fetch();
|
||||
}elseif($op=='load'){
|
||||
|
||||
$process=input('process/a',null,'trim');
|
||||
$process=array_array_map('trim', $process);
|
||||
$process=trim_input_array('process');
|
||||
$this->assign('process',$process);
|
||||
return $this->fetch('process_load');
|
||||
}
|
||||
}
|
||||
}
|
||||
/*获取函数插件列表*/
|
||||
public function process_funcAction(){
|
||||
$module=input('module');
|
||||
if(empty($module)){
|
||||
$this->error('模块错误');
|
||||
}
|
||||
$mfuncApp=new FuncApp();
|
||||
|
||||
$cacheName='cpattern_process_func_methods_'.$module;
|
||||
$cacheFuncs=cache($cacheName);
|
||||
|
||||
$enableApps=$mfuncApp->where(array('module'=>$module,'enable'=>1))->column('uptime','app');
|
||||
$enableApps=md5(serialize($enableApps));
|
||||
|
||||
$apps=array();
|
||||
if(empty($cacheFuncs)||$enableApps!=$cacheFuncs['key']||abs(time()-$cacheFuncs['time'])>600){
|
||||
|
||||
$appList=$mfuncApp->where(array('module'=>$module,'enable'=>1))->column('uptime','app');
|
||||
$apps=array();
|
||||
if(!empty($appList)){
|
||||
foreach ($appList as $k=>$v){
|
||||
$appClass=$mfuncApp->get_app_class($module, $k);
|
||||
if(!empty($appClass['methods'])){
|
||||
$apps[$k]=$appClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
cache($cacheName,array('list'=>$apps,'time'=>time(),'key'=>md5(serialize($appList))));
|
||||
}else{
|
||||
$apps=$cacheFuncs['list'];
|
||||
}
|
||||
$this->success('',null,$apps);
|
||||
/*复制数据处理*/
|
||||
public function clone_processAction(){
|
||||
$op=input('op','');
|
||||
if(empty($op)||$op=='copy'){
|
||||
|
||||
if(request()->isPost()){
|
||||
|
||||
$process=trim_input_array('process');
|
||||
if(is_array($process)){
|
||||
|
||||
$process=reset($process);
|
||||
}else{
|
||||
$process=array();
|
||||
}
|
||||
|
||||
$msg='';
|
||||
if($op=='copy'){
|
||||
|
||||
cache('cpattern_clone_process_data',$process);
|
||||
$msg='已拷贝,可在任意数据处理中粘贴';
|
||||
}else{
|
||||
$msg='已复制';
|
||||
}
|
||||
|
||||
$this->success($msg,null,$process);
|
||||
}else{
|
||||
$this->error('无效的操作');
|
||||
}
|
||||
}elseif($op=='paste'){
|
||||
|
||||
|
||||
$process=cache('cpattern_clone_process_data');
|
||||
|
||||
if(!empty($process)){
|
||||
$this->success('已粘贴',null,$process);
|
||||
}else{
|
||||
$this->error('请先拷贝一个处理内容');
|
||||
}
|
||||
}else{
|
||||
$this->error('无效的操作');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 内容分页
|
||||
|
@ -337,7 +348,7 @@ class Cpattern extends BaseController {
|
|||
public function paging_fieldAction(){
|
||||
if(request()->isPost()){
|
||||
$objid=input('post.objid');
|
||||
$pagingField=input('post.paging_field/a',null,'trim');
|
||||
$pagingField=trim_input_array('post.paging_field');
|
||||
if(empty($pagingField['field'])){
|
||||
$this->error('请选择字段');
|
||||
}
|
||||
|
@ -348,18 +359,21 @@ class Cpattern extends BaseController {
|
|||
$pagingField=$pagingField?json_decode($pagingField,true):'';
|
||||
$this->assign('pagingField',$pagingField);
|
||||
$this->assign('objid',$objid);
|
||||
$this->assign('isLoop',input('is_loop'));
|
||||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
/*多级网址规则*/
|
||||
public function level_urlAction(){
|
||||
if(request()->isPost()){
|
||||
if(request()->isPost()&&input('is_submit')){
|
||||
$objid=input('post.objid');
|
||||
$level_url=input('post.level_url/a',null,'trim');
|
||||
$level_url=trim_input_array('post.level_url');
|
||||
if(empty($level_url['name'])){
|
||||
$this->error('请输入名称');
|
||||
}
|
||||
$this->_check_name($level_url['name'],'多级名称');
|
||||
$this->_check_name($level_url['name'],'多级页名称');
|
||||
|
||||
$level_url=controller('admin/Cpattern','event')->set_config_url_web($level_url);
|
||||
|
||||
$this->success('',null,array('level_url'=>$level_url,'objid'=>$objid));
|
||||
}else{
|
||||
|
@ -371,11 +385,22 @@ class Cpattern extends BaseController {
|
|||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
/*复制多级页*/
|
||||
public function clone_level_urlAction(){
|
||||
if(request()->isPost()){
|
||||
$levelUrl=input('level_url','','url_b64decode');
|
||||
$levelUrl=$levelUrl?json_decode($levelUrl,true):array();
|
||||
|
||||
$this->success('',null,array('level_url'=>$levelUrl));
|
||||
}else{
|
||||
$this->error('复制失败');
|
||||
}
|
||||
}
|
||||
/*关联网址规则*/
|
||||
public function relation_urlAction(){
|
||||
if(request()->isPost()){
|
||||
if(request()->isPost()&&input('is_submit')){
|
||||
$objid=input('post.objid');
|
||||
$relation_url=input('post.relation_url/a',null,'trim');
|
||||
$relation_url=trim_input_array('post.relation_url');
|
||||
if(empty($relation_url['name'])){
|
||||
$this->error('请输入名称');
|
||||
}
|
||||
|
@ -384,6 +409,9 @@ class Cpattern extends BaseController {
|
|||
if(empty($relation_url['url_rule'])){
|
||||
$this->error('请输入提取网址规则');
|
||||
}
|
||||
|
||||
$relation_url=controller('admin/Cpattern','event')->set_config_url_web($relation_url);
|
||||
|
||||
$this->success('',null,array('relation_url'=>$relation_url,'objid'=>$objid));
|
||||
}else{
|
||||
$relation_url=input('relation_url','','url_b64decode');
|
||||
|
@ -394,374 +422,243 @@ class Cpattern extends BaseController {
|
|||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
/*测试*/
|
||||
public function testAction(){
|
||||
set_time_limit(600);
|
||||
|
||||
$coll_id=input('coll_id/d',0);
|
||||
$mcoll=model('Collector');
|
||||
$collData=$mcoll->where(array('id'=>$coll_id))->find();
|
||||
if(empty($collData)){
|
||||
$this->error(lang('coll_error_empty_coll'));
|
||||
}
|
||||
if(!in_array($collData['module'],config('allow_coll_modules'))){
|
||||
$this->error(lang('coll_error_invalid_module'));
|
||||
}
|
||||
$this->assign('collData',$collData);
|
||||
|
||||
|
||||
$eCpattern=controller('admin/Cpattern','event');
|
||||
$eCpattern->init($collData);
|
||||
|
||||
$op=input('op');
|
||||
$taskData=model('Task')->getById($eCpattern->collector['task_id']);
|
||||
model('Task')->loadConfig($taskData);
|
||||
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Collector/set?task_id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Cpattern/test&op='.$op.'&coll_id='.$coll_id),'title'=>'测试')));
|
||||
|
||||
if('source_urls'==$op){
|
||||
|
||||
$source_urls=array();
|
||||
foreach ($eCpattern->config['source_url'] as $k => $v) {
|
||||
if(empty($v)){
|
||||
continue;
|
||||
}
|
||||
$source_urls[$v] = $eCpattern->convert_source_url ( $v );
|
||||
}
|
||||
if(!$eCpattern->config['source_is_url']){
|
||||
|
||||
$source_urls1=array();
|
||||
foreach ($source_urls as $k=>$v){
|
||||
if (is_array ( $v )) {
|
||||
$source_urls1 = array_merge ( $source_urls1, $v );
|
||||
} else {
|
||||
$source_urls1 [] = $v;
|
||||
}
|
||||
}
|
||||
$source_urls=$source_urls1;
|
||||
}
|
||||
$eCpattern->assign('source_urls',$source_urls);
|
||||
$eCpattern->assign('config',$eCpattern->config);
|
||||
return $eCpattern->fetch('cpattern:test_source_urls');
|
||||
}elseif('cont_urls'==$op){
|
||||
|
||||
$source_url=input('source_url','','trim');
|
||||
$curLevel=input('level/d',0);
|
||||
$curLevel=$curLevel>0?$curLevel:0;
|
||||
|
||||
$levelData=$eCpattern->collLevelUrls($source_url,$curLevel);
|
||||
|
||||
$eCpattern->success('',null,array('urls'=>$levelData['urls'],'levelName'=>$levelData['levelName'],'nextLevel'=>$levelData['nextLevel']));
|
||||
}elseif('cont_url'==$op){
|
||||
|
||||
$GLOBALS['_sc']['p_name']='测试抓取';
|
||||
$cont_url=input('cont_url','','trim');
|
||||
$test=input('test');
|
||||
|
||||
$url_post=$eCpattern->config['url_post'];
|
||||
|
||||
$input_urls=array();
|
||||
foreach ($eCpattern->config['new_field_list'] as $field){
|
||||
if(empty($field['field']['source'])){
|
||||
|
||||
if($field['field']['module']=='sign'){
|
||||
if(empty($eCpattern->config['level_urls'])){
|
||||
$input_urls['source_url']=input('source_url','');
|
||||
}else{
|
||||
|
||||
$endLevelNum=count($eCpattern->config['level_urls']);
|
||||
$endLevel=$eCpattern->config['level_urls'][$endLevelNum-1];
|
||||
$input_urls['level_url'][$endLevelNum]=array('level'=>$endLevelNum,'name'=>$endLevel['name'],'url'=>input('level_'.$endLevelNum));
|
||||
}
|
||||
}
|
||||
}elseif('source_url'==strtolower($field['field']['source'])){
|
||||
|
||||
$input_urls['source_url']=input('source_url','');
|
||||
}elseif(preg_match('/level_url:/i', $field['field']['source'])){
|
||||
|
||||
foreach($eCpattern->config['level_urls'] as $levIx=>$levVal){
|
||||
if($field['field']['source']==('level_url:'.$levVal['name'])){
|
||||
|
||||
$level=$levIx+1;
|
||||
if($field['field']['module']=='sign'){
|
||||
|
||||
if($level==1){
|
||||
|
||||
$input_urls['source_url']=input('source_url','');
|
||||
}else{
|
||||
|
||||
$prevLevel=$level-1;
|
||||
$input_urls['level_url'][$prevLevel]=array('level'=>$prevLevel,'name'=>$eCpattern->config['level_urls'][$prevLevel-1]['name'],'url'=>input('level_'.$prevLevel));
|
||||
}
|
||||
}else{
|
||||
|
||||
$input_urls['level_url'][$level]=array('level'=>$level,'name'=>$levVal['name'],'url'=>input('level_'.$level));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$eCpattern->assign('cont_url',$cont_url);
|
||||
$eCpattern->assign('url_post',$url_post);
|
||||
$eCpattern->assign('input_urls',$input_urls);
|
||||
$eCpattern->assign('test',$test);
|
||||
if(request()->isAjax()){
|
||||
return view('cpattern:test_cont_url_ajax');
|
||||
}else{
|
||||
return $eCpattern->fetch('cpattern:test_cont_url');
|
||||
}
|
||||
}elseif(in_array($op, array('get_fields','get_paging_urls','get_relation_urls','get_html'))){
|
||||
|
||||
$cont_url=input('cont_url','','trim');
|
||||
if(!preg_match('/^\w+\:\/\//',$cont_url)){
|
||||
|
||||
$cont_url='http://'.$cont_url;
|
||||
}
|
||||
$html='get_fields'==$op?'':$eCpattern->get_html($cont_url,false,$eCpattern->config['url_post']);
|
||||
if('get_fields'==$op){
|
||||
|
||||
if(input('?source_url')){
|
||||
|
||||
$eCpattern->cur_source_url=input('source_url');
|
||||
}
|
||||
foreach (input('param.') as $k=>$v){
|
||||
|
||||
if(preg_match('/^level_(\d+)$/',$k,$mLevel)){
|
||||
|
||||
$mLevel=intval($mLevel[1])-1;
|
||||
$eCpattern->cur_level_urls[$eCpattern->config['level_urls'][$mLevel]['name']]=$v;
|
||||
}
|
||||
}
|
||||
|
||||
$signLevels=array();
|
||||
$signCont=false;
|
||||
foreach($eCpattern->config['new_field_list'] as $fieldConfig){
|
||||
if($fieldConfig['field']['module']=='sign'){
|
||||
|
||||
if(empty($fieldConfig['field']['source'])){
|
||||
$signCont=true;
|
||||
}elseif(preg_match('/^level_url:(.*+)$/i', $fieldConfig['field']['source'],$levelName)){
|
||||
|
||||
$levelName=$levelName[1];
|
||||
$signLevels[$levelName]=$levelName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($signLevels)){
|
||||
|
||||
foreach ($eCpattern->config['level_urls'] as $k=>$v){
|
||||
if(in_array($v['name'],$signLevels)){
|
||||
if($k==0){
|
||||
|
||||
$eCpattern->getLevelUrls($eCpattern->cur_source_url,$k+1,true);
|
||||
}else{
|
||||
|
||||
$prevLevelUrl=$eCpattern->config['level_urls'][$k-1];
|
||||
$eCpattern->getLevelUrls($eCpattern->cur_level_urls[$prevLevelUrl['name']],$k+1,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($signCont){
|
||||
|
||||
if(empty($eCpattern->config['level_urls'])){
|
||||
|
||||
$eCpattern->getContUrls($eCpattern->cur_source_url);
|
||||
}else{
|
||||
|
||||
$endLevelNum=count($eCpattern->config['level_urls']);
|
||||
$endLevel=$eCpattern->config['level_urls'][$endLevelNum-1];
|
||||
$eCpattern->getContUrls($eCpattern->cur_level_urls[$endLevel['name']]);
|
||||
}
|
||||
}
|
||||
|
||||
$val_list=$eCpattern->getFields($cont_url);
|
||||
if(empty($eCpattern->first_loop_field)){
|
||||
|
||||
$val_list=array($val_list);
|
||||
}
|
||||
|
||||
$md5Url=md5($cont_url);
|
||||
$msg='';
|
||||
if(isset($eCpattern->exclude_cont_urls[$md5Url])){
|
||||
if(empty($eCpattern->first_loop_field)){
|
||||
|
||||
$msg=reset($eCpattern->exclude_cont_urls[$md5Url]);
|
||||
$msg=$eCpattern->exclude_url_msg($msg);
|
||||
$this->error('中断采集 > '.$msg);
|
||||
}else{
|
||||
|
||||
$num=0;
|
||||
foreach ($eCpattern->exclude_cont_urls[$md5Url] as $k=>$v){
|
||||
$num+=count((array)$v);
|
||||
}
|
||||
$msg='通过数据处理筛除了'.$num.'条数据';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($val_list as $v_k=>$vals){
|
||||
foreach ($vals as $k=>$v){
|
||||
$vals[$k]=$v['value'];
|
||||
}
|
||||
$val_list[$v_k]=$vals;
|
||||
}
|
||||
$eCpattern->success($msg,null,$val_list);
|
||||
}elseif('get_paging_urls'==$op){
|
||||
|
||||
$paging_urls=$eCpattern->getPagingUrls($cont_url,$html,true);
|
||||
if(empty($paging_urls)){
|
||||
$eCpattern->error('没有抓取到分页链接');
|
||||
}else{
|
||||
$eCpattern->success('',null,$paging_urls);
|
||||
}
|
||||
}elseif('get_html'==$op){
|
||||
if(empty($html)){
|
||||
exit('没有抓取到源码');
|
||||
}else{
|
||||
|
||||
exit($html);
|
||||
}
|
||||
}elseif('get_relation_urls'==$op){
|
||||
|
||||
$url_list=array();
|
||||
foreach ($eCpattern->config['new_relation_urls'] as $k=>$v){
|
||||
$url_list[$v['name']]=$eCpattern->getRelationUrl($v['name'], $cont_url, $html);
|
||||
}
|
||||
if(empty($url_list)){
|
||||
$eCpattern->error('没有关联页');
|
||||
}else{
|
||||
$eCpattern->success('',null,$url_list);
|
||||
}
|
||||
}
|
||||
}elseif('match'==$op){
|
||||
|
||||
$GLOBALS['_sc']['p_name']='模拟匹配';
|
||||
if(request()->isPost()){
|
||||
$type=strtolower(input('type'));
|
||||
$content=input('content','','trim');
|
||||
$match=input('match','','trim');
|
||||
if(empty($content)){
|
||||
$eCpattern->error('请输入网址或内容');
|
||||
}
|
||||
if(empty($match)){
|
||||
$eCpattern->error('请输入规则');
|
||||
}
|
||||
if(preg_match('/^\w+\:\/\//', $content)){
|
||||
|
||||
$content=$eCpattern->get_html($content);
|
||||
}
|
||||
if(empty($content)){
|
||||
$eCpattern->error('内容空');
|
||||
}
|
||||
$val='';
|
||||
switch ($type){
|
||||
case 'rule':
|
||||
|
||||
$match=$eCpattern->convert_sign_match($match);
|
||||
$match=preg_replace('/\\\*([\'\/])/', "\\\\$1",$match);
|
||||
$match=str_replace('(*)', '[\s\S]*?', $match);
|
||||
|
||||
$rule_merge=$eCpattern->set_merge_default($match, '');
|
||||
$val=$eCpattern->field_module_rule(array('reg_rule'=>$match,'rule_merge'=>$rule_merge), $content);
|
||||
|
||||
if(empty($val)){
|
||||
if(preg_match('/'.$match.'/i', $content,$val)){
|
||||
$val=$val[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'xpath':
|
||||
$val=$eCpattern->field_module_xpath(array('xpath'=>$match,'xpath_attr'=>''), $content);
|
||||
break;
|
||||
case 'json':
|
||||
$val=$eCpattern->field_module_json(array('json'=>$match,'json_arr_implode'=>"\r\n"), $content);
|
||||
$val=trim($val);
|
||||
break;
|
||||
}
|
||||
if(empty($val)){
|
||||
$eCpattern->error('没有获取到数据');
|
||||
}else{
|
||||
$eCpattern->success($val);
|
||||
}
|
||||
}else{
|
||||
if(request()->isAjax()){
|
||||
return view('cpattern:test_match_ajax');
|
||||
}else{
|
||||
return $eCpattern->fetch('cpattern:test_match');
|
||||
}
|
||||
}
|
||||
}elseif('elements'==$op){
|
||||
|
||||
$cont_url=input('cont_url','','trim');
|
||||
|
||||
$this->redirect('Cpattern/browser?coll_id='.$coll_id.'&url='.rawurlencode($cont_url));
|
||||
}
|
||||
/*复制关联页*/
|
||||
public function clone_relation_urlAction(){
|
||||
if(request()->isPost()){
|
||||
$relationUrl=input('relation_url','','url_b64decode');
|
||||
$relationUrl=$relationUrl?json_decode($relationUrl,true):array();
|
||||
|
||||
$this->success('',null,array('relation_url'=>$relationUrl));
|
||||
}else{
|
||||
$this->error('复制失败');
|
||||
}
|
||||
}
|
||||
/*编辑规则:简单模式*/
|
||||
public function easymodeAction(){
|
||||
$taskId=input('task_id/d',0);
|
||||
$collId=model('Collector')->where('task_id',$taskId)->value('id');
|
||||
$this->assign('taskId',$taskId);
|
||||
$this->assign('collId',$collId);
|
||||
return $this->fetch();
|
||||
}
|
||||
/*浏览器*/
|
||||
public function browserAction(){
|
||||
|
||||
$coll_id=input('coll_id/d',0);
|
||||
$mcoll=model('Collector');
|
||||
$collData=$mcoll->where(array('id'=>$coll_id))->find();
|
||||
|
||||
$taskData=model('Task')->getById($taskId);
|
||||
|
||||
$collId=$mcoll->where('task_id',$taskId)->value('id');
|
||||
$collData=$mcoll->where(array('id'=>$collId))->find();
|
||||
if(empty($collData)){
|
||||
$collData=array();
|
||||
$collData=array();
|
||||
}else{
|
||||
$collData=$collData->toArray();
|
||||
$collData=$collData->toArray();
|
||||
}
|
||||
|
||||
|
||||
$eCpattern=controller('admin/Cpattern','event');
|
||||
$eCpattern->init($collData);
|
||||
|
||||
$url=input('url','','trim');
|
||||
if(!preg_match('/^\w+\:\/\//',$url)){
|
||||
|
||||
$url='http://'.$url;
|
||||
}
|
||||
$html=$eCpattern->get_html($url,false,$eCpattern->config['url_post']);
|
||||
$pageSources=$eCpattern->page_source_options();
|
||||
|
||||
$jsonHtml=convert_html2json($html,true);
|
||||
set_g_sc('p_title','简单模式_任务:'.$taskData['name']);
|
||||
|
||||
$config=$eCpattern->config;
|
||||
$config=is_array($config)?$config:array();
|
||||
|
||||
|
||||
if(empty($jsonHtml)){
|
||||
|
||||
$html=preg_replace('/<script[^<>]*?>[\s\S]*?<\/script>/i', '', $html);
|
||||
$html=preg_replace('/<meta[^<>]*charset[^<>]*?>/i', '', $html);
|
||||
$html=preg_replace('/<meta[^<>]*http-equiv\s*=\s*[\'\"]{0,1}refresh\b[\'\"]{0,1}[^<>]*?>/i', '', $html);
|
||||
header("Content-type:text/html;charset=utf-8");
|
||||
$eCpattern->assign('html',$html);
|
||||
$eCpattern->assign('config',$config);
|
||||
|
||||
return $eCpattern->fetch('cpattern:browser');
|
||||
}else{
|
||||
|
||||
$GLOBALS['_sc']['p_name']='分析网页';
|
||||
$eCpattern->assign('jsonHtml',$jsonHtml);
|
||||
return $eCpattern->fetch('cpattern:browser_json');
|
||||
}
|
||||
$this->assign('taskId',$taskId);
|
||||
$this->assign('collId',$collId);
|
||||
$this->assign('pageSources',$pageSources);
|
||||
return $this->fetch();
|
||||
}
|
||||
/*获取父级页面的标签列表*/
|
||||
public function parentPageSignsAction(){
|
||||
if(request()->isPost()){
|
||||
$level_urls=input('level_urls/a',array(),'url_b64decode');
|
||||
$relation_urls=input('relation_urls/a',array(),'url_b64decode');
|
||||
$urlConfig=input('url_config/a',array(),'trim');
|
||||
$pageConfig=input('page_config/a',array(),'trim');
|
||||
$isAreaOrUrl=input('is_area_or_url','');
|
||||
|
||||
$pageType=input('page_type','','trim');
|
||||
|
||||
$eCpattern=controller('admin/Cpattern','event');
|
||||
|
||||
$levelSigns=array();
|
||||
$relationSigns=array();
|
||||
$urlSigns=array();
|
||||
$pageSigns=array();
|
||||
|
||||
$relationUrls=array();
|
||||
|
||||
foreach ($level_urls as $k=>$v){
|
||||
$v=$v?json_decode($v,true):array();
|
||||
$levelSigns[$v['name']]=array(
|
||||
'area'=>$this->_get_rule_signs($v['area'],'',true,false),
|
||||
'url'=>$this->_get_rule_signs('',$v['url_rule'],false,true),
|
||||
);
|
||||
}
|
||||
|
||||
if($pageType=='relation_url'){
|
||||
|
||||
foreach ($relation_urls as $k=>$v){
|
||||
$v=$v?json_decode($v,true):array();
|
||||
$relationSigns[$v['name']]=array(
|
||||
'area'=>$this->_get_rule_signs($v['area'],'',true,false),
|
||||
'url'=>$this->_get_rule_signs('',$v['url_rule'],false,true),
|
||||
);
|
||||
$relationUrls[$v['name']]=$v;
|
||||
}
|
||||
}
|
||||
|
||||
if($pageType=='relation_url'||$pageType=='url'){
|
||||
if($pageType=='url'&&$isAreaOrUrl=='area'){
|
||||
|
||||
$urlSigns=array(
|
||||
'area'=>$this->_get_rule_signs($urlConfig['area'],'',true,false),
|
||||
);
|
||||
}else{
|
||||
$urlSigns=array(
|
||||
'area'=>$this->_get_rule_signs($urlConfig['area'],'',true,false),
|
||||
'url'=>$this->_get_rule_signs('',$urlConfig['url_rule'],false,true),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if($isAreaOrUrl=='area'){
|
||||
$pageSigns=array(
|
||||
'area'=>$this->_get_rule_signs($pageConfig['area'],'',true,false),
|
||||
);
|
||||
}else{
|
||||
$pageSigns=array(
|
||||
'area'=>$this->_get_rule_signs($pageConfig['area'],'',true,false),
|
||||
'url'=>$this->_get_rule_signs('',$pageConfig['url_rule'],false,true),
|
||||
);
|
||||
}
|
||||
|
||||
if($pageType=='level_url'){
|
||||
|
||||
if($pageConfig['name']&&isset($levelSigns[$pageConfig['name']])){
|
||||
|
||||
$newLevelSigns=array();
|
||||
foreach($levelSigns as $k=>$v){
|
||||
if($pageConfig['name']==$k){
|
||||
|
||||
$newLevelSigns['_cur_']=$pageSigns;
|
||||
break;
|
||||
}else{
|
||||
$newLevelSigns[$k]=$v;
|
||||
}
|
||||
}
|
||||
$levelSigns=$newLevelSigns;
|
||||
}else{
|
||||
|
||||
$levelSigns['_cur_']=$pageSigns;
|
||||
}
|
||||
}elseif($pageType=='relation_url'){
|
||||
|
||||
$newRelationSigns=array();
|
||||
$newRelationSigns['_cur_']=$pageSigns;
|
||||
$relationUrls[$pageConfig['name']]=$pageConfig;
|
||||
$relationParentPages=$eCpattern->relation_parent_pages($pageConfig['name'],$relationUrls);
|
||||
foreach ($relationParentPages as $relationParentPage){
|
||||
|
||||
$newRelationSigns[$relationParentPage]=$relationSigns[$relationParentPage];
|
||||
}
|
||||
$relationSigns=$newRelationSigns;
|
||||
}
|
||||
|
||||
$levelSigns=array_reverse($levelSigns,true);
|
||||
|
||||
$allSigns=array();
|
||||
|
||||
foreach ($relationSigns as $k=>$v){
|
||||
if($k=='_cur_'){
|
||||
$allSigns[]=array('name'=>'当前关联页','signs'=>$v,'cur'=>true);
|
||||
}else{
|
||||
$allSigns[]=array('name'=>'关联页:'.$k,'signs'=>$v);
|
||||
}
|
||||
}
|
||||
if($pageType=='relation_url'||$pageType=='url'){
|
||||
$allSigns[]=array('name'=>($pageType=='url'?'当前':'').'内容页','signs'=>$urlSigns,'cur'=>($pageType=='url'?true:false));
|
||||
}
|
||||
foreach ($levelSigns as $k=>$v){
|
||||
if($k=='_cur_'){
|
||||
$allSigns[]=array('name'=>'当前多级页','signs'=>$v,'cur'=>true);
|
||||
}else{
|
||||
$allSigns[]=array('name'=>'多级页:'.$k,'signs'=>$v);
|
||||
}
|
||||
}
|
||||
$existSigns=array();
|
||||
|
||||
foreach ($allSigns as $ask=>$asv){
|
||||
$asv=is_array($asv)?$asv:array();
|
||||
$signs=$asv['signs'];
|
||||
$newSigns=array('area'=>array(),'url'=>array(),'area_global'=>array(),'url_global'=>array());
|
||||
if(!is_array($signs)){
|
||||
$signs=array();
|
||||
}
|
||||
if(!is_array($signs['area'])){
|
||||
$signs['area']=array();
|
||||
}
|
||||
if(!is_array($signs['url'])){
|
||||
$signs['url']=array();
|
||||
}
|
||||
|
||||
foreach ($signs['url'] as $k=>$v){
|
||||
if(!in_array($v, $existSigns)){
|
||||
|
||||
$existSigns[]=$v;
|
||||
$newSigns['url_global'][]=$v;
|
||||
}
|
||||
}
|
||||
foreach ($signs['area'] as $k=>$v){
|
||||
if(!in_array($v, $existSigns)){
|
||||
|
||||
$existSigns[]=$v;
|
||||
$newSigns['area_global'][]=$v;
|
||||
}
|
||||
}
|
||||
|
||||
$newSigns['area']=$signs['area'];
|
||||
$newSigns['url']=$signs['url'];
|
||||
|
||||
$asv['signs']=$newSigns;
|
||||
|
||||
$allSigns[$ask]=$asv;
|
||||
}
|
||||
|
||||
$this->success('',null,$allSigns);
|
||||
}else{
|
||||
$this->error();
|
||||
}
|
||||
}
|
||||
/*名称命名规范*/
|
||||
public function _check_name($name,$nameStr=''){
|
||||
if(!preg_match('/^[\x{4e00}-\x{9fa5}\w\-]+$/u', $name)){
|
||||
$this->error(($nameStr?$nameStr:'名称').'只能由汉字、字母、数字和下划线组成');
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
if(!preg_match('/^[\x{4e00}-\x{9fa5}\w\-]+$/u', $name)){
|
||||
$this->error(($nameStr?$nameStr:'名称').'只能由汉字、字母、数字和下划线组成');
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function _get_rule_signs($areaRule,$urlRule,$areaDef=true,$urlDef=true){
|
||||
$eCpattern=controller('admin/Cpattern','event');
|
||||
|
||||
$areaRule=$areaRule?$areaRule:'';
|
||||
$urlRule=$urlRule?$urlRule:'';
|
||||
|
||||
$areaRule=$eCpattern->convert_sign_match($areaRule);
|
||||
$urlRule=$eCpattern->convert_sign_match($urlRule);
|
||||
|
||||
$areaSigns=$eCpattern->rule_str_signs($areaRule);
|
||||
$urlSigns=$eCpattern->rule_str_signs($urlRule);
|
||||
|
||||
if(empty($areaSigns)){
|
||||
$areaSigns=$areaDef?array(cp_sign('match')):array();
|
||||
}
|
||||
if(empty($urlSigns)){
|
||||
$urlSigns=$urlDef?array(cp_sign('match')):array();
|
||||
}
|
||||
|
||||
foreach ($areaSigns as $k=>$v){
|
||||
if(in_array($v,$urlSigns)){
|
||||
|
||||
unset($areaSigns[$k]);
|
||||
}
|
||||
}
|
||||
return array_merge($areaSigns,$urlSigns);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -66,9 +66,9 @@ class Develop extends BaseController {
|
|||
$this->error('cms程序名必须由字母或数字组成且首位不能为数字!');
|
||||
}
|
||||
if(empty($identifier)){
|
||||
$this->error('请输入插件功能标识');
|
||||
$this->error('请输入功能标识');
|
||||
}elseif(!preg_match('/^[a-z][a-z0-9]*$/i', $identifier)){
|
||||
$this->error('插件功能标识必须由字母或数字组成且首位不能为数字!');
|
||||
$this->error('功能标识必须由字母或数字组成且首位不能为数字!');
|
||||
}
|
||||
if(empty($copyright)){
|
||||
$this->error('请输入作者版权');
|
||||
|
@ -82,7 +82,7 @@ class Develop extends BaseController {
|
|||
$appName=ucfirst(input('app'));
|
||||
}
|
||||
|
||||
$params=input('params/a');
|
||||
$params=input('params/a',array());
|
||||
if(empty($params)||!is_array($params)){
|
||||
$this->error('请添加参数');
|
||||
}
|
||||
|
@ -162,9 +162,9 @@ class Develop extends BaseController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_name']='开发CMS发布插件 <small><a href="https://www.skycaiji.com/manual/doc/cms" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/ReleaseApp'),'title'=>'CMS发布插件'),array('url'=>url('Develop/releaseCms'),'title'=>'开发CMS发布插件')));
|
||||
set_g_sc('p_title','开发CMS发布插件');
|
||||
set_g_sc('p_name','开发CMS发布插件 <small><a href="https://www.skycaiji.com/manual/doc/cms" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/ReleaseApp'),'title'=>'CMS发布插件'),array('url'=>url('Develop/releaseCms'),'title'=>'开发CMS发布插件'))));
|
||||
|
||||
$this->assign('config',$config);
|
||||
$this->assign('is_old_plugin',$is_old_plugin);
|
||||
|
@ -174,8 +174,8 @@ class Develop extends BaseController {
|
|||
/*添加参数*/
|
||||
public function cmsAddParamAction(){
|
||||
if(request()->isPost()){
|
||||
$param=input('param/a');
|
||||
$param=array_array_map('trim', $param);
|
||||
$param=input('param/a',array());
|
||||
$param=\util\Funcs::array_array_map('trim', $param);
|
||||
if(empty($param['key'])){
|
||||
$this->error('请输入变量名');
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ EOF;
|
|||
$this->error('修改失败,该应用不存在!');
|
||||
}
|
||||
$framework=input('framework');
|
||||
$frameworkVersion=input('framework_version/a');
|
||||
$frameworkVersion=input('framework_version/a',array());
|
||||
$frameworkVersion=$frameworkVersion[$framework];
|
||||
|
||||
$config=array(
|
||||
|
@ -422,8 +422,8 @@ EOF;
|
|||
if(!empty($framework)&&empty($frameworkVersion)){
|
||||
$this->error('请选择框架版本');
|
||||
}
|
||||
|
||||
$packs=input('packs/a');
|
||||
|
||||
$packs=input('packs/a',array());
|
||||
if(empty($config['name'])){
|
||||
$this->error('请输入应用名称');
|
||||
}
|
||||
|
@ -443,7 +443,17 @@ EOF;
|
|||
if(!$mapp->right_version($config['version'])){
|
||||
$this->error('版本号格式错误');
|
||||
}
|
||||
|
||||
|
||||
if(empty($install)){
|
||||
$this->error('请输入安装应用接口');
|
||||
}
|
||||
if(empty($uninstall)){
|
||||
$this->error('请输入卸载应用接口');
|
||||
}
|
||||
if(empty($upgrade)){
|
||||
$this->error('请输入升级应用接口');
|
||||
}
|
||||
|
||||
if(is_array($packs)){
|
||||
foreach ($packs as $k=>$v){
|
||||
|
||||
|
@ -561,12 +571,13 @@ EOF;
|
|||
$this->success('修改成功','Develop/app?app='.$app);
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='开发应用程序 <small><a href="https://www.skycaiji.com/manual/doc/app" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
|
||||
set_g_sc('p_title','开发应用程序');
|
||||
set_g_sc('p_name','开发应用程序 <small><a href="https://www.skycaiji.com/manual/doc/app" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>');
|
||||
|
||||
if($appData){
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('App/manage?app='.$appData['app']),'title'=>$appData['config']['name']),array('url'=>url('Develop/app?app='.$appData['app']),'title'=>'开发应用')));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('App/manage?app='.$appData['app']),'title'=>$appData['config']['name']),array('url'=>url('Develop/app?app='.$appData['app']),'title'=>'开发应用'))));
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/app'),'title'=>'应用程序'),array('url'=>url('Develop/app'),'title'=>'开发应用')));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/app'),'title'=>'应用程序'),array('url'=>url('Develop/app'),'title'=>'开发应用'))));
|
||||
}
|
||||
|
||||
$appClass=$mapp->app_class($app);
|
||||
|
@ -596,11 +607,11 @@ EOF;
|
|||
/*添加扩展*/
|
||||
public function appAddPackAction(){
|
||||
if(request()->isPost()){
|
||||
$pack=input('pack/a','','trim');
|
||||
$pack=input('pack/a',array(),'trim');
|
||||
$pack['name']=strip_tags($pack['name']);
|
||||
$pack['type']=strip_tags($pack['type']);
|
||||
$pack['target']=intval($pack['target']);
|
||||
$pack=array_array_map('trim', $pack);
|
||||
$pack=\util\Funcs::array_array_map('trim', $pack);
|
||||
if(empty($pack['name'])){
|
||||
$this->error('请输入名称');
|
||||
}
|
||||
|
@ -631,7 +642,6 @@ EOF;
|
|||
/*下载安装框架*/
|
||||
public function installFrameworkAction(){
|
||||
$app=input('app');
|
||||
$op=input('op');
|
||||
|
||||
if(empty($app)){
|
||||
$this->error('应用app标识错误');
|
||||
|
@ -649,98 +659,48 @@ EOF;
|
|||
if(empty($appClass->config['framework_version'])){
|
||||
$this->error('框架版本错误');
|
||||
}
|
||||
|
||||
|
||||
$appFrameworkPath=$appClass->appFrameworkPath();
|
||||
if(is_dir($appFrameworkPath)){
|
||||
$this->error('该应用已有框架,如需重新设置框架,请先删除:'.$appFrameworkPath);
|
||||
}
|
||||
|
||||
$eachSize=1024*100;
|
||||
$fileUrl='https://www.skycaiji.com/download/framework/'.$appClass->config['framework'].'/'.$appClass->config['framework_version'].'.zip';
|
||||
|
||||
$filePath=RUNTIME_PATH.'/cache_framework/'.$appClass->config['framework'].$appClass->config['framework_version'].'/';
|
||||
|
||||
if('files'==$op){
|
||||
|
||||
$fileHeader=get_headers($fileUrl,true);
|
||||
if(!preg_match('/\s+20\d\s+ok/i',$fileHeader[0])){
|
||||
$this->error('文件获取失败');
|
||||
}
|
||||
$fileSize=$fileHeader['Content-Length'];
|
||||
$list=array();
|
||||
$count=ceil($fileSize/$eachSize);
|
||||
for($i=0;$i<$count;$i++){
|
||||
|
||||
$list[$i]=array('id'=>$i+1,'start'=>$i*$eachSize,'end'=>($i+1)*$eachSize);
|
||||
if($list[$i]['end']>=$fileSize){
|
||||
$list[$i]['end']=$fileSize;
|
||||
}
|
||||
$list[$i]['end']-=1;
|
||||
}
|
||||
$this->success(true,'',array('size'=>$fileSize,'list'=>$list));
|
||||
}elseif('down'==$op){
|
||||
$fileSize=input('size/d');
|
||||
$startSize=input('start_size/d');
|
||||
$endSize=input('end_size/d');
|
||||
$id=input('id/d');
|
||||
|
||||
$fileCont=file_get_contents($filePath.$id);
|
||||
|
||||
if(!empty($fileCont)){
|
||||
|
||||
$this->success();
|
||||
}else{
|
||||
$blockData=$this->_down_file($fileUrl,null,"{$startSize}-{$endSize}");
|
||||
if(empty($blockData)){
|
||||
|
||||
$this->error();
|
||||
}else{
|
||||
write_dir_file($filePath.$id, $blockData);
|
||||
$this->success();
|
||||
}
|
||||
}
|
||||
}elseif('install'==$op){
|
||||
$fileSize=input('size/d');
|
||||
$count=ceil($fileSize/$eachSize);
|
||||
$is_end=true;
|
||||
for($i=1;$i<=$count;$i++){
|
||||
|
||||
if(!file_exists($filePath.$i)){
|
||||
$is_end=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($is_end){
|
||||
|
||||
$error='';
|
||||
$allData='';
|
||||
for($i=1;$i<=$count;$i++){
|
||||
$allData.=file_get_contents($filePath.$i);
|
||||
}
|
||||
write_dir_file($filePath.'framework.zip', $allData);
|
||||
|
||||
try {
|
||||
$zipClass=new \ZipArchive();
|
||||
if($zipClass->open($filePath.'framework.zip')===TRUE){
|
||||
$zipClass->extractTo($appClass->appPath);
|
||||
$zipClass->close();
|
||||
}else{
|
||||
$error='解压失败';
|
||||
}
|
||||
}catch(\Exception $ex){
|
||||
$error='您的服务器不支持ZipArchive解压';
|
||||
}
|
||||
if(!empty($error)){
|
||||
$error.=',请自行将文件'.$filePath.'framework.zip 解压到'.$appClass->appPath.'里';
|
||||
}
|
||||
if($error){
|
||||
$this->error($error);
|
||||
}else{
|
||||
clear_dir($filePath);
|
||||
$this->success('安装成功','Develop/app?app='.$app);
|
||||
}
|
||||
}
|
||||
$this->error();
|
||||
|
||||
$mprov=model('Provider');
|
||||
|
||||
$timestamp=time();
|
||||
$clientinfo=clientinfo();
|
||||
|
||||
$authsign=$mprov->createAuthsign($mprov->getAuthkey(null),$clientinfo['url'],'https://www.skycaiji.com',$timestamp);
|
||||
|
||||
$uriParams=array(
|
||||
'authsign'=>$authsign,
|
||||
'client_url'=>$clientinfo['url'],
|
||||
'timestamp'=>$timestamp,
|
||||
'name'=>$appClass->config['framework'],
|
||||
'version'=>$appClass->config['framework_version'],
|
||||
'block_no'=>input('block_no/d',0)
|
||||
);
|
||||
|
||||
$fileData=curl_skycaiji('/client/download/framework?'.http_build_query($uriParams));
|
||||
$fileData=json_decode($fileData,true);
|
||||
$fileData=is_array($fileData)?$fileData:array();
|
||||
|
||||
if(!$fileData['code']){
|
||||
|
||||
$this->error($fileData['msg']);
|
||||
}
|
||||
$fileData=is_array($fileData['data'])?$fileData['data']:array();
|
||||
$fileData=json_decode(base64_decode($fileData['file']),true);
|
||||
$fileData=is_array($fileData)?$fileData:array();
|
||||
|
||||
$filePath=RUNTIME_PATH.'zip_framework/'.$appClass->config['framework'].$appClass->config['framework_version'];
|
||||
|
||||
$result=\util\Funcs::install_downloaded_zip($fileData, $filePath, $appClass->appPath);
|
||||
|
||||
if($result['success']){
|
||||
$this->success('框架安装成功','Develop/app?app='.$app,$result);
|
||||
}else{
|
||||
$this->error($result['msg']);
|
||||
}
|
||||
}
|
||||
/*开发函数插件*/
|
||||
|
@ -765,7 +725,7 @@ EOF;
|
|||
$copyright=input('copyright');
|
||||
$identifier=input('identifier');
|
||||
$name=input('name');
|
||||
$methods=input('methods/a');
|
||||
$methods=input('methods/a',array());
|
||||
|
||||
if(empty($module)){
|
||||
$this->error('请选择类型');
|
||||
|
@ -813,8 +773,9 @@ EOF;
|
|||
}
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='开发函数插件 <small><a href="https://www.skycaiji.com/manual/doc/func" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/funcApp'),'title'=>'函数插件'),array('url'=>url('Develop/func'),'title'=>'开发函数插件')));
|
||||
set_g_sc('p_title','开发函数插件');
|
||||
set_g_sc('p_name','开发函数插件 <small><a href="https://www.skycaiji.com/manual/doc/func" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/funcApp'),'title'=>'函数插件'),array('url'=>url('Develop/func'),'title'=>'开发函数插件'))));
|
||||
|
||||
if(input('?app')){
|
||||
|
||||
|
@ -832,14 +793,6 @@ EOF;
|
|||
}
|
||||
}
|
||||
|
||||
/*保存到云端*/
|
||||
public function save2storeAction(){
|
||||
$type=input('type');
|
||||
$app=input('app');
|
||||
$pluginData=$this->_get_plugin_data($type,$app);
|
||||
$this->assign('pluginData',$pluginData);
|
||||
return $this->fetch();
|
||||
}
|
||||
/*导出插件*/
|
||||
public function exportAction(){
|
||||
$type=input('type');
|
||||
|
@ -859,9 +812,9 @@ EOF;
|
|||
header("Content-transfer-encoding: binary");
|
||||
header("Accept-Length: " .mb_strlen($txt));
|
||||
if (preg_match("/MSIE/i", $_SERVER["HTTP_USER_AGENT"])) {
|
||||
header('Content-Disposition: attachment; filename="'.urlencode($name).'.skycaiji"');
|
||||
header('Content-Disposition: attachment; filename="'.urlencode($name).'.scj"');
|
||||
}else{
|
||||
header('Content-Disposition: attachment; filename="'.$name.'.skycaiji"');
|
||||
header('Content-Disposition: attachment; filename="'.$name.'.scj"');
|
||||
}
|
||||
echo $txt;
|
||||
ob_end_flush();
|
||||
|
@ -894,8 +847,9 @@ EOF;
|
|||
|
||||
if(!empty($pluginDb['provider_id'])){
|
||||
|
||||
$provData=model('Provider')->where('id',$pluginDb['provider_id'])->find();
|
||||
$pluginData['store_url']=$provData['url'].'/client/plugin/detail?app='.$pluginDb['app'];
|
||||
$mprov=model('Provider');
|
||||
$provData=$mprov->where('id',$pluginDb['provider_id'])->find();
|
||||
$pluginData['store_url']=\skycaiji\admin\model\Provider::create_store_url($provData['url'],'client/addon/plugin',array('app'=>$pluginDb['app']));
|
||||
}
|
||||
|
||||
if(empty($pluginData['name'])){
|
||||
|
@ -965,36 +919,4 @@ EOF;
|
|||
}
|
||||
}
|
||||
}
|
||||
/*获取内容*/
|
||||
public function _down_file($url, $header=null,$size) {
|
||||
$useragents=array(
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
|
||||
);
|
||||
static $useragent;
|
||||
if(empty($useragent)){
|
||||
$useragent=$useragents[array_rand($useragents)];
|
||||
}
|
||||
|
||||
$ch = curl_init ();
|
||||
curl_setopt ( $ch, CURLOPT_URL, $url );
|
||||
curl_setopt ( $ch, CURLOPT_TIMEOUT, 100 );
|
||||
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
|
||||
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
|
||||
curl_setopt ( $ch, CURLOPT_HEADER, 0 );
|
||||
curl_setopt ( $ch, CURLOPT_USERAGENT, $useragent);
|
||||
|
||||
|
||||
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
|
||||
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
|
||||
|
||||
if (! empty ( $header )) {
|
||||
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header );
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_RANGE, $size);
|
||||
|
||||
$bytes = curl_exec ( $ch );
|
||||
curl_close ( $ch );
|
||||
return $bytes;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ class Index extends BaseController{
|
|||
/*后台运行采集,会无限运行下去*/
|
||||
public function backstageAction(){
|
||||
$key=input('key');
|
||||
$cacheKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
|
||||
$cacheKey=CacheModel::getInstance()->getCache('collect_backstage_key', 'data');
|
||||
if(empty($key)||$key!=$cacheKey){
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ class Index extends BaseController{
|
|||
$this->error('不是后台运行方式');
|
||||
}
|
||||
|
||||
if($caijiConfig['server']=='cli'){
|
||||
if($mconfig->server_is_cli(true,$caijiConfig['server'])){
|
||||
|
||||
cli_command_exec('collect backstage');
|
||||
}else{
|
||||
|
@ -56,6 +56,8 @@ class Index extends BaseController{
|
|||
ignore_user_abort(true);
|
||||
set_time_limit(0);
|
||||
|
||||
CacheModel::getInstance()->setCache('collect_backstage_time',time());
|
||||
|
||||
try{
|
||||
get_html(url('Admin/Api/collect?backstage=1',null,false,true),null,array('timeout'=>3));
|
||||
}catch(\Exception $ex){
|
||||
|
@ -71,7 +73,7 @@ class Index extends BaseController{
|
|||
|
||||
|
||||
|
||||
$cacheKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
|
||||
$cacheKey=CacheModel::getInstance()->getCache('collect_backstage_key', 'data');
|
||||
if(empty($key)||$key!=$cacheKey){
|
||||
|
||||
|
||||
|
@ -111,16 +113,25 @@ class Index extends BaseController{
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
/*访问执行采集*/
|
||||
public function caijiAction(){
|
||||
if(empty($GLOBALS['_sc']['c']['caiji']['auto'])){
|
||||
if(is_empty(g_sc_c('caiji','auto'))){
|
||||
$this->error('请先开启自动采集','Admin/Setting/caiji');
|
||||
}
|
||||
|
||||
$checkCollectWait=\skycaiji\admin\model\Config::check_collect_wait();
|
||||
if($checkCollectWait){
|
||||
$this->error($checkCollectWait['msg'],'Admin/Index/caiji',null,$checkCollectWait['wait']);
|
||||
}
|
||||
|
||||
@get_html(url('Admin/Api/collect?backstage=1',null,false,true),null,array('timeout'=>3));
|
||||
$waitTime=$GLOBALS['_sc']['c']['caiji']['interval']*60;
|
||||
|
||||
$waitTime=g_sc('c_caiji_interval')*60;
|
||||
$waitTime=$waitTime>0?$waitTime:60;
|
||||
$this->success('正在采集...','Admin/Index/caiji',null,$waitTime);
|
||||
}
|
||||
|
||||
/*任务api发布*/
|
||||
public function apiTaskAction(){
|
||||
controller('admin/Api','controller')->taskAction();
|
||||
|
@ -128,25 +139,30 @@ class Index extends BaseController{
|
|||
|
||||
public function loginAction(){
|
||||
if(request()->isPost()){
|
||||
if(!check_usertoken()){
|
||||
$this->error(lang('usertoken_error'),'Admin/Index/login');
|
||||
}
|
||||
|
||||
$mcacheLogin=CacheModel::getInstance('login');
|
||||
$config_login=$GLOBALS['_sc']['c']['site']['login'];
|
||||
$config_login=g_sc_c('site','login');
|
||||
$clientIpMd5=md5(request()->ip());
|
||||
$nowTime=time();
|
||||
if(!empty($config_login['limit'])){
|
||||
|
||||
$ipLoginData=$mcacheLogin->getCache($clientIpMd5,'data');
|
||||
if((NOW_TIME-$ipLoginData['lastdate'])<($config_login['time']*3600)&&$ipLoginData['failed']>=$config_login['failed']){
|
||||
try{
|
||||
$ipLoginData=$mcacheLogin->getCache($clientIpMd5,'data');
|
||||
if(!is_array($ipLoginData)){
|
||||
$ipLoginData=array();
|
||||
}
|
||||
}catch (\Exception $ex){
|
||||
|
||||
$this->error($ex->getMessage());
|
||||
}
|
||||
if(($nowTime-$ipLoginData['lastdate'])<($config_login['time']*3600)&&$ipLoginData['failed']>=$config_login['failed']){
|
||||
|
||||
$this->error("您已登录失败{$ipLoginData['failed']}次,被锁定{$config_login['time']}小时");
|
||||
}
|
||||
}
|
||||
if(input('post.sublogin')){
|
||||
$username=strtolower(trim(input('post.username')));
|
||||
$username=User::lower_username(input('post.username'));
|
||||
$pwd=trim(input('post.password'));
|
||||
if($GLOBALS['_sc']['c']['site']['verifycode']){
|
||||
if(g_sc_c('site','verifycode')){
|
||||
|
||||
$verifycode=trim(input('post.verifycode'));
|
||||
$check=check_verify($verifycode);
|
||||
|
@ -155,7 +171,6 @@ class Index extends BaseController{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
$check=User::right_username($username);
|
||||
if(!$check['success']){
|
||||
$this->error($check['msg']);
|
||||
|
@ -164,9 +179,14 @@ class Index extends BaseController{
|
|||
if(!$check['success']){
|
||||
$this->error($check['msg']);
|
||||
}
|
||||
|
||||
|
||||
$muser=new \skycaiji\admin\model\User();
|
||||
$userData=$muser->where('username',$username)->find();
|
||||
try{
|
||||
$userData=$muser->where('username',$username)->find();
|
||||
}catch (\Exception $ex){
|
||||
|
||||
$this->error($ex->getMessage());
|
||||
}
|
||||
if(empty($userData)||$userData['password']!=\skycaiji\admin\model\User::pwd_encrypt($pwd,$userData['salt'])){
|
||||
|
||||
if(!empty($config_login['limit'])){
|
||||
|
@ -174,17 +194,17 @@ class Index extends BaseController{
|
|||
$ipLoginData=$mcacheLogin->getCache($clientIpMd5,'data');
|
||||
if(!empty($ipLoginData)){
|
||||
|
||||
if((NOW_TIME-$ipLoginData['lastdate'])<($config_login['time']*3600)){
|
||||
if(($nowTime-$ipLoginData['lastdate'])<($config_login['time']*3600)){
|
||||
|
||||
$ipLoginData['failed']++;
|
||||
}else{
|
||||
|
||||
$ipLoginData['lastdate']=NOW_TIME;
|
||||
$ipLoginData['lastdate']=$nowTime;
|
||||
$ipLoginData['failed']=1;
|
||||
}
|
||||
}else{
|
||||
|
||||
$ipLoginData['lastdate']=NOW_TIME;
|
||||
$ipLoginData['lastdate']=$nowTime;
|
||||
$ipLoginData['failed']=1;
|
||||
}
|
||||
$ipLoginData['ip']=request()->ip();
|
||||
|
@ -196,17 +216,10 @@ class Index extends BaseController{
|
|||
|
||||
if(input('post.auto')){
|
||||
|
||||
cookie('login_history',$username.'|'.md5($username.$userData['password']),array('expire'=>3600*24*15));
|
||||
cookie('login_history',intval($userData['uid']).'|'.$muser->generate_key($userData),array('expire'=>3600*24*15));
|
||||
}
|
||||
session('user_id',$userData['uid']);
|
||||
|
||||
$userGroup=model('Usergroup')->getById($userData['groupid']);
|
||||
|
||||
if(model('Usergroup')->is_admin($userGroup)){
|
||||
session('is_admin',true);
|
||||
}else{
|
||||
session('is_admin',null);
|
||||
}
|
||||
$muser->setLoginSession($userData);
|
||||
|
||||
$serverinfo=input('_serverinfo');
|
||||
if(empty($serverinfo)){
|
||||
|
@ -232,16 +245,19 @@ class Index extends BaseController{
|
|||
/*退出*/
|
||||
public function logoutAction(){
|
||||
\think\Cookie::delete('login_history');
|
||||
unset($GLOBALS['_sc']['user']);
|
||||
session('user_id',null);
|
||||
session('is_admin',null);
|
||||
set_g_sc('user',null);
|
||||
model('User')->setLoginSession(null);
|
||||
$this->success(lang('op_success'),'Admin/Index/index');
|
||||
}
|
||||
/*验证码*/
|
||||
public function verifyAction(){
|
||||
$len=g_sc_c('site','verifycode_len');
|
||||
$len=intval($len);
|
||||
$len=min(max(3,$len),20);
|
||||
|
||||
$config=array(
|
||||
'fontSize'=>30,
|
||||
'length'=>3,
|
||||
'length'=>$len,
|
||||
'fontttf'=>'5.ttf',
|
||||
'useCurve'=>true,
|
||||
'useNoise'=>true
|
||||
|
@ -251,6 +267,28 @@ class Index extends BaseController{
|
|||
$captcha = new \think\captcha\Captcha($config);
|
||||
return $captcha->entry();
|
||||
}
|
||||
|
||||
public function verify_img_errorAction(){
|
||||
|
||||
$LocSystem=new \skycaiji\install\event\LocSystem();
|
||||
$LocSystem=$LocSystem->environmentPhp();
|
||||
$gd=$LocSystem['gd'];
|
||||
$error='';
|
||||
if(empty($gd['loaded'])){
|
||||
|
||||
$error='php未启用gd模块';
|
||||
}elseif(!empty($gd['lack'])){
|
||||
|
||||
$error='php未启用gd模块(需支持'.$gd['lack'].')';
|
||||
}
|
||||
if($error){
|
||||
$error='图片验证码错误:'.$error;
|
||||
$this->error($error);
|
||||
}else{
|
||||
$this->success('');
|
||||
}
|
||||
}
|
||||
|
||||
/*找回密码*/
|
||||
public function find_passwordAction(){
|
||||
$username=trim(input('post.username'));
|
||||
|
@ -281,10 +319,7 @@ class Index extends BaseController{
|
|||
}
|
||||
if($step===1){
|
||||
|
||||
if(!check_usertoken()){
|
||||
$this->error(lang('usertoken_error'),'Admin/Index/find_password');
|
||||
}
|
||||
if($GLOBALS['_sc']['c']['site']['verifycode']){
|
||||
if(g_sc_c('site','verifycode')){
|
||||
|
||||
$verifycode=trim(input('verifycode'));
|
||||
$check=check_verify($verifycode);
|
||||
|
@ -361,25 +396,26 @@ class Index extends BaseController{
|
|||
}else{
|
||||
if($step===2){
|
||||
$emailStatus=array('success'=>false,'msg'=>'');
|
||||
if(empty($GLOBALS['_sc']['c']['email'])){
|
||||
if(is_empty(g_sc_c('email'))){
|
||||
$emailStatus['msg']=lang('config_error_none_email');
|
||||
}else{
|
||||
$waitTime=60;
|
||||
$waitSname='send_yzm_wait';
|
||||
|
||||
$passTime=abs(NOW_TIME-session($waitSname));
|
||||
$nowTime=time();
|
||||
$passTime=abs($nowTime-session($waitSname));
|
||||
if($passTime<=$waitTime){
|
||||
$emailStatus['msg']=lang('find_pwd_email_wait',array('seconds'=>$waitTime-$passTime));
|
||||
}else{
|
||||
$expire=config('yzm_expire');
|
||||
$minutes=floor($expire/60);
|
||||
$yzm=mt_rand(100000,999999);
|
||||
session($waitSname,NOW_TIME);
|
||||
$mailReturn=send_mail($GLOBALS['_sc']['c']['email'], $stepSession['user']['email'], $stepSession['user']['username'],lang('find_pwd_email_subject'),lang('find_pwd_email_body',array('yzm'=>$yzm,'minutes'=>$minutes)));
|
||||
session($waitSname,$nowTime);
|
||||
$mailReturn=send_mail(g_sc_c('email'), $stepSession['user']['email'], $stepSession['user']['username'],lang('find_pwd_email_subject'),lang('find_pwd_email_body',array('yzm'=>$yzm,'minutes'=>$minutes)));
|
||||
if($mailReturn===true){
|
||||
$yzmSname='send_yzm.'.md5($username);
|
||||
session(array('name'=>$yzmSname,'expire'=>$expire));
|
||||
session($yzmSname,array('yzm'=>$yzm,'time'=>NOW_TIME));
|
||||
session($yzmSname,array('yzm'=>$yzm,'time'=>$nowTime));
|
||||
$emailStatus['success']=true;
|
||||
$emailStatus['msg']=lang('find_pwd_sended',array('email'=>preg_replace('/.{2}\@/', '**@', $stepSession['user']['email'])));
|
||||
}else{
|
||||
|
@ -402,18 +438,4 @@ class Index extends BaseController{
|
|||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
/*验证站点*/
|
||||
public function site_certificationAction(){
|
||||
$keyFile=cache('site_certification');
|
||||
$key=$keyFile['key'];
|
||||
if(abs(NOW_TIME-$keyFile['time'])>60){
|
||||
|
||||
$key='';
|
||||
}
|
||||
exit($key);
|
||||
}
|
||||
/*客户端信息*/
|
||||
public function clientinfoAction(){
|
||||
return json(clientinfo());
|
||||
}
|
||||
}
|
|
@ -17,37 +17,54 @@ class Mystore extends BaseController {
|
|||
$this->redirect('Mystore/store');
|
||||
}
|
||||
public function storeAction(){
|
||||
$url=input('url','','strip_tags');
|
||||
if(!empty($url)&&!is_official_url($url)){
|
||||
set_g_sc('p_title','云平台');
|
||||
|
||||
$url=input('url','','trim');
|
||||
|
||||
$notSafe='';
|
||||
|
||||
if(!empty($url)&&!\skycaiji\admin\model\Provider::is_official_url($url)){
|
||||
|
||||
$provData=model('Provider')->where('url',$url)->find();
|
||||
set_g_sc('p_title','第三方平台');
|
||||
if(empty($provData)){
|
||||
$this->error($url.' 平台未添加');
|
||||
$this->error($url.' 平台未添加','');
|
||||
}
|
||||
if(empty($provData['enable'])){
|
||||
$this->error($url.' 已设置为拒绝访问');
|
||||
$this->error($url.' 已设置为拒绝访问','');
|
||||
}
|
||||
$url=$provData['url'];
|
||||
set_g_sc('p_title','第三方:'.$provData['title']);
|
||||
|
||||
$url.=strpos($url, '?')===false?'?':'&';
|
||||
$url.='clientinfo='.urlencode($GLOBALS['_sc']['clientinfo']);
|
||||
|
||||
$this->assign('provData',$provData);
|
||||
$storeData=curl_skycaiji('/client/info/store?url='.rawurlencode($url).'&clientinfo='.rawurlencode(g_sc('clientinfo')));
|
||||
$storeData=json_decode($storeData,true);
|
||||
if(!is_array($storeData)){
|
||||
$storeData=array();
|
||||
}
|
||||
if(empty($storeData)||empty($storeData['safe'])){
|
||||
|
||||
$notSafe=empty($storeData)?'安全检测失败,是否继续访问?':$storeData['msg'];
|
||||
}
|
||||
}
|
||||
if(empty($url)){
|
||||
$url='https://www.skycaiji.com/store';
|
||||
}
|
||||
|
||||
if(!empty($url)){
|
||||
|
||||
$url=\skycaiji\admin\model\Provider::create_store_url(null,'store');
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('store');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/store'),'title'=>lang('store'))));
|
||||
$url.=(strpos($url,'?')===false?'?':'&').'clientinfo='.rawurlencode(g_sc('clientinfo'));
|
||||
|
||||
$this->assign('url',$url);
|
||||
return $this->fetch();
|
||||
if(empty($notSafe)){
|
||||
|
||||
$this->redirect($url);
|
||||
}else{
|
||||
|
||||
set_g_sc('p_name',lang('store'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/store'),'title'=>lang('store')))));
|
||||
$this->assign('storeInfo',array('url'=>$url,'notSafe'=>$notSafe));
|
||||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
|
||||
public function ruleAction(){
|
||||
$mrule=model('Rule');
|
||||
$type=input('type','collect');
|
||||
|
@ -79,19 +96,22 @@ class Mystore extends BaseController {
|
|||
foreach ($ruleList as $k=>$v){
|
||||
$provList[$v['provider_id']]=$v['provider_id'];
|
||||
}
|
||||
$provList=model('Provider')->where('id','in',$provList)->column('*','id');
|
||||
$mprov=model('Provider');
|
||||
$provList=$mprov->where('id','in',$provList)->column('*','id');
|
||||
foreach ($ruleList as $k=>$v){
|
||||
$url='https://www.skycaiji.com';
|
||||
$url='';
|
||||
if(!empty($v['provider_id'])&&!empty($provList[$v['provider_id']])){
|
||||
|
||||
$url=$provList[$v['provider_id']]['url'];
|
||||
$ruleList[$k]['_is_provider']=true;
|
||||
}
|
||||
$ruleList[$k]['store_url']=$url.'/client/rule/detail?id='.$v['store_id'];
|
||||
$ruleList[$k]['_store_url']=\skycaiji\admin\model\Provider::create_store_url($url,'client/addon/rule',array('id'=>$v['store_id']));
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_name']='已下载';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/rule'),'title'=>'已下载:'.lang('rule_'.$type))));
|
||||
|
||||
set_g_sc('p_title',lang('rule_'.$type));
|
||||
set_g_sc('p_name','已下载');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/rule'),'title'=>'已下载:'.lang('rule_'.$type)))));
|
||||
|
||||
$this->assign('ruleList',$ruleList);
|
||||
|
||||
|
@ -117,7 +137,7 @@ class Mystore extends BaseController {
|
|||
$this->success(lang('delete_success'));
|
||||
}elseif($op=='deleteall'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
if(is_array($ids)&&count($ids)>0){
|
||||
$mrule->where(array('id'=>array('in',$ids)))->delete();
|
||||
}
|
||||
|
@ -133,7 +153,7 @@ class Mystore extends BaseController {
|
|||
}
|
||||
}elseif($op=='check_store_update'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
|
||||
if(!empty($ids)){
|
||||
$ruleList=model('Rule')->where(array('id'=>array('in',$ids)))->select();
|
||||
|
@ -163,21 +183,7 @@ class Mystore extends BaseController {
|
|||
}
|
||||
|
||||
foreach ($provStoreIds as $provId=>$storeIds){
|
||||
$url='';
|
||||
$storeIds=implode(',',$storeIds);
|
||||
$storeIds=rawurlencode($storeIds);
|
||||
if(empty($provId)){
|
||||
|
||||
$url='https://www.skycaiji.com';
|
||||
}elseif(!empty($provList[$provId])){
|
||||
|
||||
$url=$provList[$provId]['url'];
|
||||
}
|
||||
$url.='/client/rule/update?ids='.$storeIds;
|
||||
|
||||
$uptimeList=get_html($url,null,array('timeout'=>2));
|
||||
$uptimeList=json_decode($uptimeList,true);
|
||||
|
||||
$uptimeList=$this->_get_store_uptimes($provList[$provId],'rule',$storeIds);
|
||||
if(!empty($uptimeList)){
|
||||
|
||||
foreach ($uptimeList as $storeId=>$storeUptime){
|
||||
|
@ -225,23 +231,28 @@ class Mystore extends BaseController {
|
|||
$provList[$v['provider_id']]=$v['provider_id'];
|
||||
}
|
||||
}
|
||||
$provList=model('Provider')->where('id','in',$provList)->column('*','id');
|
||||
|
||||
$mprov=model('Provider');
|
||||
|
||||
$provList=$mprov->where('id','in',$provList)->column('*','id');
|
||||
|
||||
foreach ($appList as $k=>$v){
|
||||
$url='https://www.skycaiji.com';
|
||||
$url='';
|
||||
if(!empty($v['provider_id'])&&!empty($provList[$v['provider_id']])){
|
||||
|
||||
$url=$provList[$v['provider_id']]['url'];
|
||||
$url=$provList[$v['provider_id']]['url'];
|
||||
$appList[$k]['_is_provider']=true;
|
||||
}
|
||||
$appList[$k]['store_url']=$url.'/client/plugin/detail?app='.$v['app'];
|
||||
$appList[$k]['_store_url']=\skycaiji\admin\model\Provider::create_store_url($url,'client/addon/plugin',array('app'=>$v['app']));
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_name']='已下载';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/releaseApp'),'title'=>'已下载:发布插件')));
|
||||
set_g_sc('p_title','发布插件');
|
||||
set_g_sc('p_name','已下载');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/releaseApp'),'title'=>'已下载:发布插件'))));
|
||||
|
||||
$this->assign('appList',$appList);
|
||||
return $this->fetch('releaseApp');
|
||||
return $this->fetch('release_app');
|
||||
}
|
||||
public function releaseAppOpAction(){
|
||||
$id=input('id/d',0);
|
||||
|
@ -259,7 +270,7 @@ class Mystore extends BaseController {
|
|||
$this->success(lang('delete_success'));
|
||||
}elseif($op=='deleteall'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
if(is_array($ids)&&count($ids)>0){
|
||||
foreach ($ids as $idv){
|
||||
$this->_deleteReleaseApp($idv);
|
||||
|
@ -271,7 +282,7 @@ class Mystore extends BaseController {
|
|||
$this->_auto_check_plugin();
|
||||
}elseif($op=='check_store_update'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
|
||||
$appList=model('ReleaseApp')->where(array('module'=>'cms','id'=>array('in',$ids)))->column('*','app');
|
||||
$updateList=$this->_check_store_plugin_update($appList);
|
||||
|
@ -386,10 +397,57 @@ class Mystore extends BaseController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_name']='应用程序';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/app'),'title'=>'应用程序')));
|
||||
|
||||
|
||||
foreach ($dbApps as $k=>$v){
|
||||
$storeUrl='';
|
||||
if(!empty($provList[$v['provider_id']])){
|
||||
$storeUrl=$provList[$v['provider_id']]['url'];
|
||||
$dbApps[$k]['_is_provider']=true;
|
||||
}
|
||||
$dbApps[$k]['_store_url']=\skycaiji\admin\model\Provider::create_store_url($storeUrl,'client/addon/app',array('app'=>$k));
|
||||
|
||||
if(is_array($v['config'])){
|
||||
|
||||
if(is_array($v['config']['packs'])){
|
||||
$dbApps[$k]['_nav_packs']=$mapp->convert_packs($v['config']['packs'],$v['app'],'nav');
|
||||
}
|
||||
|
||||
$content='';
|
||||
if($v['config']['author']){
|
||||
$content='作者:'.htmlspecialchars($v['config']['author'],ENT_QUOTES);
|
||||
}
|
||||
if($v['config']['desc']){
|
||||
$content.=($content?'<br>描述:':'').htmlspecialchars($v['config']['desc'],ENT_QUOTES);
|
||||
}
|
||||
$dbApps[$k]['_content']=$content;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($pathApps as $k=>$v){
|
||||
$storeUrl='';
|
||||
if(!empty($provList[$v['provider_id']])){
|
||||
$storeUrl=$provList[$v['provider_id']]['url'];
|
||||
$pathApps[$k]['_is_provider']=true;
|
||||
}
|
||||
$pathApps[$k]['_store_url']=\skycaiji\admin\model\Provider::create_store_url($storeUrl,'client/addon/app',array('app'=>$k));
|
||||
|
||||
if(is_array($v['config'])){
|
||||
|
||||
$content='';
|
||||
if($v['config']['author']){
|
||||
$content='作者:'.htmlspecialchars($v['config']['author'],ENT_QUOTES);
|
||||
}
|
||||
if($v['config']['desc']){
|
||||
$content.=($content?'<br>描述:':'').htmlspecialchars($v['config']['desc'],ENT_QUOTES);
|
||||
}
|
||||
$pathApps[$k]['_content']=$content;
|
||||
}
|
||||
}
|
||||
|
||||
set_g_sc('p_title','应用程序');
|
||||
set_g_sc('p_name','应用程序');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/app'),'title'=>'应用程序'))));
|
||||
|
||||
$this->assign('pagenav',$pagenav);
|
||||
$this->assign('dbApps',$dbApps);
|
||||
$this->assign('pathApps',$pathApps);
|
||||
|
@ -412,7 +470,7 @@ class Mystore extends BaseController {
|
|||
}
|
||||
}elseif($op=='check_store_update'){
|
||||
|
||||
$apps=input('apps/a');
|
||||
$apps=input('apps/a',array());
|
||||
|
||||
$mprov=model('Provider');
|
||||
$appList=array();
|
||||
|
@ -438,31 +496,13 @@ class Mystore extends BaseController {
|
|||
|
||||
$provList=$mprov->where('id','in',$provList)->column('*','id');
|
||||
foreach($provApps as $provId=>$apps){
|
||||
$apps=implode(',',$apps);
|
||||
$apps=rawurlencode($apps);
|
||||
$url='';
|
||||
$appUrl='';
|
||||
$isProv=false;
|
||||
if(!empty($provList[$provId])){
|
||||
$verList=$this->_get_store_uptimes($provList[$provId],'app',$apps);
|
||||
if(!empty($verList)){
|
||||
|
||||
$url=$provList[$provId]['url'];
|
||||
$isProv=true;
|
||||
}else{
|
||||
|
||||
$url='https://www.skycaiji.com';
|
||||
}
|
||||
$appUrl=$url;
|
||||
$url.='/client/app/update?apps='.$apps;
|
||||
|
||||
$storeList=get_html($url,null,array('timeout'=>2));
|
||||
$storeList=json_decode($storeList,true);
|
||||
|
||||
if(!empty($storeList)){
|
||||
|
||||
foreach ($storeList as $storeApp=>$storeVer){
|
||||
if(!empty($storeVer)&&version_compare($storeVer,$appList[$app]['version'],'>')){
|
||||
foreach ($verList as $verK=>$verV){
|
||||
if(!empty($verV)&&version_compare($verV,$appList[$app]['version'],'>')){
|
||||
|
||||
$updateList[]=array('app'=>$storeApp,'is_provider'=>$isProv,'app_url'=>$appUrl.'/client/app/detail?app='.rawurlencode($storeApp));
|
||||
$updateList[]=$verK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -471,7 +511,7 @@ class Mystore extends BaseController {
|
|||
if(!empty($updateList)){
|
||||
$this->success('',null,$updateList);
|
||||
}else{
|
||||
$this->error('无更新');
|
||||
$this->error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,20 +544,24 @@ class Mystore extends BaseController {
|
|||
$provList[$v['provider_id']]=$v['provider_id'];
|
||||
}
|
||||
}
|
||||
$provList=model('Provider')->where('id','in',$provList)->column('*','id');
|
||||
|
||||
$mprov=model('Provider');
|
||||
$provList=$mprov->where('id','in',$provList)->column('*','id');
|
||||
|
||||
foreach ($appList as $k=>$v){
|
||||
$url='https://www.skycaiji.com';
|
||||
$url='';
|
||||
if(!empty($v['provider_id'])&&!empty($provList[$v['provider_id']])){
|
||||
|
||||
$url=$provList[$v['provider_id']]['url'];
|
||||
$url=$provList[$v['provider_id']]['url'];
|
||||
$appList[$k]['_is_provider']=true;
|
||||
}
|
||||
$appList[$k]['store_url']=$url.'/client/plugin/detail?app='.$v['app'];
|
||||
$appList[$k]['_store_url']=\skycaiji\admin\model\Provider::create_store_url($url,'client/addon/plugin',array('app'=>$v['app']));
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['p_name']='已下载';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/funcApp'),'title'=>'已下载:函数插件')));
|
||||
set_g_sc('p_title','函数插件');
|
||||
set_g_sc('p_name','已下载');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Mystore/funcApp'),'title'=>'已下载:函数插件'))));
|
||||
|
||||
$this->assign('appList',$appList);
|
||||
$this->assign('modules',$mfuncApp->funcModules);
|
||||
|
@ -528,7 +572,7 @@ class Mystore extends BaseController {
|
|||
$op=input('op');
|
||||
$id=input('id');
|
||||
|
||||
$ops=array('item'=>array('delete','enable','detail'),'list'=>array('deleteall','check_store_update'),'else'=>array('auto_check'));
|
||||
$ops=array('item'=>array('delete','enable','detail','method'),'list'=>array('deleteall','check_store_update'),'else'=>array('auto_check'));
|
||||
if(!in_array($op,$ops['item'])&&!in_array($op,$ops['list'])&&!in_array($op,$ops['else'])){
|
||||
|
||||
$this->error(lang('invalid_op'));
|
||||
|
@ -537,8 +581,20 @@ class Mystore extends BaseController {
|
|||
$mfuncApp=new FuncApp();
|
||||
$appData=$mfuncApp->where('id',$id)->find();
|
||||
if($op=='detail'){
|
||||
$appClass=empty($appData)?array():$mfuncApp->get_app_class($appData['module'], $appData['app']);
|
||||
$this->success('',null,$appClass);
|
||||
$appClass=empty($appData)?array():$mfuncApp->get_app_class($appData['module'], $appData['app'],array('comment_cut'=>1));
|
||||
$this->success('',null,$appClass);
|
||||
}elseif($op=='method'){
|
||||
$methodName=input('name');
|
||||
if(empty($methodName)){
|
||||
$this->error('方法名为空');
|
||||
}
|
||||
$appClass=empty($appData)?array():$mfuncApp->get_app_class($appData['module'], $appData['app'],array('doc_comment'=>1,'method_code'=>1));
|
||||
$methodData=$appClass['methods'][$methodName];
|
||||
if(!is_array($methodData)){
|
||||
$methodData=array();
|
||||
}
|
||||
$this->assign('methodData',$methodData);
|
||||
return $this->fetch('func_method');
|
||||
}elseif($op=='enable'){
|
||||
$enable=input('enable/d');
|
||||
$mfuncApp->where('id',$appData['id'])->update(array('enable'=>$enable));
|
||||
|
@ -554,7 +610,7 @@ class Mystore extends BaseController {
|
|||
$this->success('删除成功');
|
||||
}elseif($op=='deleteall'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
if(is_array($ids)&&count($ids)>0){
|
||||
|
||||
foreach ($ids as $idv){
|
||||
|
@ -576,7 +632,7 @@ class Mystore extends BaseController {
|
|||
$this->_auto_check_plugin();
|
||||
}elseif($op=='check_store_update'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
|
||||
$appList=model('FuncApp')->where(array('id'=>array('in',$ids)))->column('*','app');
|
||||
$updateList=$this->_check_store_plugin_update($appList);
|
||||
|
@ -590,10 +646,7 @@ class Mystore extends BaseController {
|
|||
/*导入插件*/
|
||||
public function uploadAction(){
|
||||
if(request()->isPost()){
|
||||
if(!check_usertoken()){
|
||||
$this->error(lang('usertoken_error'));
|
||||
}
|
||||
if($GLOBALS['_sc']['c']['site']['verifycode']){
|
||||
if(g_sc_c('site','verifycode')){
|
||||
|
||||
$verifycode=trim(input('verifycode'));
|
||||
$check=check_verify($verifycode);
|
||||
|
@ -627,7 +680,7 @@ class Mystore extends BaseController {
|
|||
$pluginDb=$mapp->where('app',$pluginData['app'])->find();
|
||||
if(!empty($pluginDb)){
|
||||
|
||||
$this->error('插件已存在',null,array('js'=>"confirmRight('插件已存在,是否替换?',win_submit_replace)"));
|
||||
$this->error('',null,array('js'=>"confirmRight('插件已存在,是否替换?',win_submit_replace)"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,7 +706,7 @@ class Mystore extends BaseController {
|
|||
$this->error('插件设置为手动检测更新');
|
||||
}
|
||||
}
|
||||
/*检测插件云平台c插件更新*/
|
||||
/*检测插件云平台插件更新*/
|
||||
public function _check_store_plugin_update($appList=array()){
|
||||
$appList1=array();
|
||||
foreach ($appList as $k=>$v){
|
||||
|
@ -678,18 +731,7 @@ class Mystore extends BaseController {
|
|||
}
|
||||
|
||||
foreach ($provApps as $provId=>$apps){
|
||||
$apps=implode(',',$apps);
|
||||
$apps=rawurlencode($apps);
|
||||
$url='https://www.skycaiji.com';
|
||||
if(!empty($provId)&&!empty($provList[$provId])){
|
||||
|
||||
$url=$provList[$provId]['url'];
|
||||
}
|
||||
$url.='/client/plugin/update?apps='.$apps;
|
||||
|
||||
$uptimeList=get_html($url,null,array('timeout'=>2));
|
||||
$uptimeList=json_decode($uptimeList,true);
|
||||
|
||||
$uptimeList=$this->_get_store_uptimes($provList[$provId], 'plugin', $apps);
|
||||
if(!empty($uptimeList)){
|
||||
|
||||
foreach ($uptimeList as $app=>$uptime){
|
||||
|
@ -703,4 +745,36 @@ class Mystore extends BaseController {
|
|||
}
|
||||
return $updateList;
|
||||
}
|
||||
|
||||
public function _get_store_uptimes($provData,$addonCat,$addonIds){
|
||||
$uptimeList=array();
|
||||
if(!empty($addonCat)&&!empty($addonIds)){
|
||||
$mprov=model('Provider');
|
||||
$storeUrl=$mprov->getStoreUrl($provData);
|
||||
$authkey=$mprov->getAuthkey($provData);
|
||||
|
||||
$timestamp=time();
|
||||
|
||||
$clientinfo=clientinfo();
|
||||
$authsign=$mprov->createAuthsign($authkey,$clientinfo['url'],$storeUrl,$timestamp);
|
||||
|
||||
$postParams=array(
|
||||
'authsign'=>$authsign,
|
||||
'client_url'=>$clientinfo['url'],
|
||||
'timestamp'=>$timestamp,
|
||||
'addons'=>array(
|
||||
$addonCat=>implode(',',$addonIds),
|
||||
)
|
||||
);
|
||||
$uptimeList=curl_store($provData?$provData['url']:'','/client/addon/update',null,array('timeout'=>3),$postParams);
|
||||
$uptimeList=json_decode($uptimeList,true);
|
||||
if(is_array($uptimeList)&&$uptimeList['code']&&is_array($uptimeList['data'])){
|
||||
$uptimeList=$uptimeList['data'][$addonCat];
|
||||
$uptimeList=is_array($uptimeList)?$uptimeList:array();
|
||||
}else{
|
||||
$uptimeList=array();
|
||||
}
|
||||
}
|
||||
return $uptimeList;
|
||||
}
|
||||
}
|
|
@ -14,8 +14,8 @@ namespace skycaiji\admin\controller;
|
|||
class Provider extends BaseController {
|
||||
/*第三方平台*/
|
||||
public function listAction(){
|
||||
$url=input('url');
|
||||
$title=input('title');
|
||||
$url=input('url','');
|
||||
$title=input('title','');
|
||||
|
||||
$mprovider=model('Provider');
|
||||
|
||||
|
@ -31,12 +31,19 @@ class Provider extends BaseController {
|
|||
$pagenav=$list->render();
|
||||
$list=$list->all();
|
||||
|
||||
$GLOBALS['_sc']['p_name']='第三方平台';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Provider/list'),'title'=>'第三方平台')));
|
||||
set_g_sc('p_title','第三方平台');
|
||||
set_g_sc('p_name','第三方平台');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Provider/list'),'title'=>'第三方平台'))));
|
||||
|
||||
$this->assign('cacheTip',cache('provider_tip_close'));
|
||||
$this->assign('list',$list);
|
||||
$this->assign('pagenav',$pagenav);
|
||||
|
||||
$this->assign('search',array(
|
||||
'url'=>$url,
|
||||
'title'=>$title
|
||||
));
|
||||
|
||||
return $this->fetch();
|
||||
}
|
||||
public function deleteAction(){
|
||||
|
@ -71,12 +78,15 @@ class Provider extends BaseController {
|
|||
$this->assign('proData',$proData);
|
||||
}
|
||||
if(request()->isPost()){
|
||||
$sameAsPwd=input('same_as_pwd');
|
||||
$url=input('url','','strip_tags');
|
||||
$title=input('title');
|
||||
$sort=input('sort/d',0);
|
||||
$sort=min($sort,999999);
|
||||
$authkey=input('authkey','','trim');
|
||||
$enable=input('enable/d',0);
|
||||
|
||||
$domain=\skycaiji\admin\model\Provider::match_domain($url);
|
||||
$domain=\skycaiji\admin\model\Provider::match_domain_http($url);
|
||||
if(empty($domain)){
|
||||
$this->error('网址格式错误');
|
||||
}
|
||||
|
@ -100,6 +110,11 @@ class Provider extends BaseController {
|
|||
$this->error($domain.' 域名已存在');
|
||||
}
|
||||
|
||||
$check=$mprovider->checkAuthkey($authkey,$sameAsPwd);
|
||||
if(!$check['success']){
|
||||
$this->error($check['msg'],'',$check['data']);
|
||||
}
|
||||
|
||||
if(empty($title)){
|
||||
$html=get_html($url,null,array('timeout'=>3));
|
||||
if(preg_match('/<title[^<>]*>(.*?)<\/title>/i', $html,$title)){
|
||||
|
@ -113,6 +128,7 @@ class Provider extends BaseController {
|
|||
'url'=>$url,
|
||||
'title'=>$title,
|
||||
'domain'=>$domain,
|
||||
'authkey'=>$authkey,
|
||||
'enable'=>$enable,
|
||||
'sort'=>$sort
|
||||
);
|
||||
|
@ -131,13 +147,76 @@ class Provider extends BaseController {
|
|||
}
|
||||
|
||||
public function saveallAction(){
|
||||
$newsort=input('newsort/a');
|
||||
$newsort=input('newsort/a',array());
|
||||
$mprovider=model('Provider');
|
||||
if(is_array($newsort)&&count($newsort)>0){
|
||||
foreach ($newsort as $key=>$val){
|
||||
$mprovider->strict(false)->where('id',intval($key))->update(array('sort'=>intval($val)));
|
||||
$val=min(intval($val),999999);
|
||||
$mprovider->strict(false)->where('id',intval($key))->update(array('sort'=>$val));
|
||||
}
|
||||
}
|
||||
$this->success('保存成功','Provider/list');
|
||||
}
|
||||
|
||||
|
||||
public function tip_closeAction(){
|
||||
cache('provider_tip_close',1);
|
||||
$this->success();
|
||||
}
|
||||
|
||||
|
||||
public function authkeysAction(){
|
||||
$url=input('url','');
|
||||
$title=input('title','');
|
||||
|
||||
$mprovider=model('Provider');
|
||||
|
||||
$cond=array();
|
||||
if(!empty($url)){
|
||||
$cond['url']=array('like','%'.$url.'%');
|
||||
}
|
||||
if(!empty($title)){
|
||||
$cond['title']=array('like','%'.$title.'%');
|
||||
}
|
||||
|
||||
$list=$mprovider->where($cond)->order('sort desc')->paginate(20,false,paginate_auto_config());
|
||||
$pagenav=$list->render();
|
||||
$list=$list->all();
|
||||
|
||||
$this->assign('list',$list);
|
||||
$this->assign('pagenav',$pagenav);
|
||||
|
||||
$this->assign('search',array(
|
||||
'url'=>$url,
|
||||
'title'=>$title
|
||||
));
|
||||
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
|
||||
public function authkeys_saveAction(){
|
||||
if(request()->isPost()){
|
||||
$sameAsPwd=input('same_as_pwd');
|
||||
$authkeys=input('authkeys/a','','trim');
|
||||
$authkeys=is_array($authkeys)?$authkeys:array();
|
||||
|
||||
$mprov=model('Provider');
|
||||
foreach ($authkeys as $provId=>$authkey){
|
||||
$check=$mprov->checkAuthkey($authkey,$sameAsPwd);
|
||||
if(!$check['success']){
|
||||
$check['data']['prov_id']=$provId;
|
||||
$this->error($check['msg'],'',$check['data']);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($authkeys as $provId=>$authkey){
|
||||
model('Provider')->strict(false)->where('id',$provId)->update(array('authkey'=>$authkey));
|
||||
}
|
||||
|
||||
$this->success('修改成功');
|
||||
}else{
|
||||
$this->error('操作失败');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -132,19 +132,20 @@ class Proxy extends BaseController {
|
|||
$mproxy=model('Proxyip');
|
||||
$proxyTypes=$mproxy->proxy_types();
|
||||
if(request()->isPost()){
|
||||
$ip_list=input('ip_list/a','','trim');
|
||||
$user_list=input('user_list/a','','trim');
|
||||
$pwd_list=input('pwd_list/a','','trim');
|
||||
$type_list=input('type_list/a','','trim');
|
||||
$ip_list=input('ip_list/a',array(),'trim');
|
||||
$user_list=input('user_list/a',array(),'trim');
|
||||
$pwd_list=input('pwd_list/a',array(),'trim');
|
||||
$type_list=input('type_list/a',array(),'trim');
|
||||
|
||||
if(!empty($ip_list)){
|
||||
$nowTime=time();
|
||||
foreach($ip_list as $k=>$v){
|
||||
$newData=array(
|
||||
'ip'=>$v,
|
||||
'user'=>$user_list[$k],
|
||||
'pwd'=>$pwd_list[$k],
|
||||
'type'=>$type_list[$k],
|
||||
'addtime'=>NOW_TIME
|
||||
'addtime'=>$nowTime
|
||||
);
|
||||
$mproxy->db()->strict(false)->insert($newData,true);
|
||||
}
|
||||
|
@ -210,16 +211,16 @@ class Proxy extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*清理无效ip*/
|
||||
public function clearInvalidAction(){
|
||||
$mproxy=model('Proxyip');
|
||||
$mproxy->where('invalid',1)->delete();
|
||||
$this->success('清理完成','Setting/proxy');
|
||||
}
|
||||
|
||||
|
||||
/*测试代理接口*/
|
||||
public function testApiAction(){
|
||||
$config=input('config/a','','trim');
|
||||
$config=input('config/a',array(),'trim');
|
||||
$mproxy=model('Proxyip');
|
||||
|
||||
$html=get_html($config['api_url']);
|
||||
|
|
|
@ -25,7 +25,7 @@ class Release extends BaseController{
|
|||
}
|
||||
$releData=$mrele->where(array('task_id'=>$taskData['id']))->find();
|
||||
if(request()->isPost()){
|
||||
$newData=array('task_id'=>$taskData['id'],'addtime'=>NOW_TIME,'config'=>array());
|
||||
$newData=array('task_id'=>$taskData['id'],'addtime'=>time(),'config'=>array());
|
||||
if($releaseId>0){
|
||||
|
||||
$importRele=$mrele->where(array('id'=>$releaseId))->find();
|
||||
|
@ -60,17 +60,31 @@ class Release extends BaseController{
|
|||
$this->error(lang('op_failed'));
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']=lang('rele_set');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Release/set?task_id='.$taskData['id']),'title'=>lang('rele_set'))));
|
||||
set_g_sc('p_title',lang('rele_set').'_任务:'.$taskData['name']);
|
||||
set_g_sc('p_name',lang('rele_set'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Release/set?task_id='.$taskData['id']),'title'=>lang('rele_set')))));
|
||||
|
||||
$this->assign('taskData',$taskData);
|
||||
|
||||
|
||||
if(!empty($releData)){
|
||||
|
||||
$releData=$releData->toArray();
|
||||
$releData['config']=unserialize($releData['config']);
|
||||
$config=$releData['config'];
|
||||
$this->assign('config',$config);
|
||||
$this->assign('releData',$releData);
|
||||
}else{
|
||||
$releData=array();
|
||||
}
|
||||
if(!is_array($releData['config'])){
|
||||
$releData['config']=array();
|
||||
}
|
||||
foreach (config('release_modules') as $v){
|
||||
if(!is_array($releData['config'][$v])){
|
||||
$releData['config'][$v]=array();
|
||||
}
|
||||
}
|
||||
$this->assign('config',$releData['config']);
|
||||
$this->assign('releData',$releData);
|
||||
|
||||
$apiRootUrl=config('root_website');
|
||||
|
||||
if(stripos(\think\Request::instance()->root(),'/index.php?s=')!==false){
|
||||
|
@ -166,7 +180,7 @@ class Release extends BaseController{
|
|||
* 设置可不先入库进行测试绑定
|
||||
* */
|
||||
public function cmsBindAction(){
|
||||
$cmsSet=input('cms/a');
|
||||
$cmsSet=input('cms/a',array());
|
||||
$taskId=input('task_id/d',0);
|
||||
$cmsPath=$cmsSet['path'];
|
||||
if(empty($cmsPath)){
|
||||
|
@ -176,7 +190,13 @@ class Release extends BaseController{
|
|||
$acms=controller('admin/Rcms','event');
|
||||
$cmsName=$acms->cms_name($cmsPath);
|
||||
if(empty($cmsName)){
|
||||
$this->error('未知的cms程序,请确保路径存在,如需指定CMS程序请在路径结尾加上@CMS程序名,例如:@discuz');
|
||||
list($cmsPath,$cmsName)=explode('@', $cmsPath);
|
||||
$msg='未知的cms程序,请确保路径存在,如需指定CMS程序请在路径结尾加上@CMS程序名,例如:@discuz';
|
||||
if(\skycaiji\admin\model\Config::check_basedir_limited($cmsPath)){
|
||||
|
||||
$msg.='<br/>注意:'.lang('error_open_basedir');
|
||||
}
|
||||
$this->error($msg);
|
||||
}
|
||||
$cmsApp=$cmsSet['app'];
|
||||
|
||||
|
@ -221,44 +241,54 @@ class Release extends BaseController{
|
|||
$this->assign('cmsApp',$cmsApp);
|
||||
return $this->fetch('cmsBind');
|
||||
}
|
||||
|
||||
public function testAction(){
|
||||
set_time_limit(600);
|
||||
$releId=input('id/d',0);
|
||||
|
||||
$releData=model('Release')->getById($releId);
|
||||
if(empty($releData)){
|
||||
$this->echo_msg(lang('rele_error_empty_rele'));
|
||||
exit();
|
||||
}
|
||||
|
||||
$taskData=model('Task')->getById($releData['task_id']);
|
||||
if(empty($taskData)){
|
||||
$this->echo_msg(lang('task_error_empty_task'));
|
||||
exit();
|
||||
}
|
||||
model('Task')->loadConfig($taskData);
|
||||
|
||||
$collData=model('Collector')->where(array('task_id'=>$taskData['id'],'module'=>$taskData['module']))->find();
|
||||
if(empty($collData)){
|
||||
$this->echo_msg(lang('coll_error_empty_coll'));
|
||||
exit();
|
||||
}
|
||||
|
||||
$acoll=controller('admin/C'.$collData['module'],'event');
|
||||
$acoll->init($collData);
|
||||
$fieldsList=$acoll->collect(1);
|
||||
if(empty($fieldsList)||!is_array($fieldsList)){
|
||||
$this->echo_msg('没有采集到数据','orange');
|
||||
}else{
|
||||
|
||||
$releObj=controller('admin/R'.strtolower($releData['module']),'event');
|
||||
$releObj->init($releData);
|
||||
if('api'==$releData['module']){
|
||||
|
||||
$releObj->config['api']['cache_time']=0;
|
||||
}
|
||||
$releObj->export($fieldsList);
|
||||
}
|
||||
set_time_limit(600);
|
||||
$releId=input('id/d',0);
|
||||
|
||||
$this->_backstage_cli_collect('test --rele_id '.$releId);
|
||||
|
||||
|
||||
$releData=model('Release')->getById($releId);
|
||||
if(empty($releData)){
|
||||
$this->echo_msg_exit(lang('rele_error_empty_rele'));
|
||||
}
|
||||
|
||||
$mtask=model('Task');
|
||||
$taskData=$mtask->getById($releData['task_id']);
|
||||
if(empty($taskData)){
|
||||
$this->echo_msg_exit(lang('task_error_empty_task'));
|
||||
}
|
||||
|
||||
if(input('?backstage')){
|
||||
|
||||
$mtask->backstage_task($taskData['id']);
|
||||
}
|
||||
|
||||
$mtask->loadConfig($taskData);
|
||||
|
||||
$collData=model('Collector')->where(array('task_id'=>$taskData['id'],'module'=>$taskData['module']))->find();
|
||||
if(empty($collData)){
|
||||
$this->echo_msg_exit(lang('coll_error_empty_coll'));
|
||||
}
|
||||
|
||||
$acoll=controller('admin/C'.$collData['module'],'event');
|
||||
$acoll->init($collData);
|
||||
$fieldsList=$acoll->collect(1);
|
||||
if(empty($fieldsList)||!is_array($fieldsList)){
|
||||
$this->echo_msg('没有采集到数据','orange');
|
||||
}else{
|
||||
|
||||
$releObj=controller('admin/R'.strtolower($releData['module']),'event');
|
||||
$releObj->init($releData);
|
||||
if('api'==$releData['module']){
|
||||
|
||||
$releObj->config['api']['cache_time']=0;
|
||||
}
|
||||
$releObj->doExport($fieldsList);
|
||||
}
|
||||
|
||||
$this->_echo_msg_end();
|
||||
}
|
||||
/*读取数据库表*/
|
||||
public function dbTablesAction(){
|
||||
|
@ -285,7 +315,7 @@ class Release extends BaseController{
|
|||
/*测试连接数据库*/
|
||||
public function dbConnectAction(){
|
||||
$op=input('op');
|
||||
$db=input('db/a','','trim');
|
||||
$db=input('db/a',array(),'trim');
|
||||
|
||||
$no_check=array('db_pwd');
|
||||
if('db_names'==$op){
|
||||
|
|
|
@ -19,11 +19,15 @@ class Setting extends BaseController {
|
|||
if(request()->isPost()){
|
||||
$config=array();
|
||||
$config['verifycode']=input('verifycode/d',0);
|
||||
$config['verifycode_len']=input('verifycode_len/d',0);
|
||||
$config['hidehome']=input('hidehome/d',0);
|
||||
$config['closelog']=input('closelog/d',0);
|
||||
$config['dblong']=input('dblong/d',0);
|
||||
$config['login']=input('login/a');
|
||||
$config['login']=input('login/a',array());
|
||||
$config['closetrans']=input('closetrans/d',0);
|
||||
$config['timezone']=input('timezone','');
|
||||
|
||||
$config['verifycode_len']=min(max(3,$config['verifycode_len']),20);
|
||||
|
||||
if($config['login']['limit']){
|
||||
|
||||
|
@ -38,13 +42,39 @@ class Setting extends BaseController {
|
|||
$mconfig->setConfig('site',$config);
|
||||
$this->success(lang('op_success'),'Setting/site');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']=lang('setting_site');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/site'),'title'=>lang('setting_site'))));
|
||||
set_g_sc('p_title',lang('setting_site'));
|
||||
set_g_sc('p_name',lang('setting_site'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/site'),'title'=>lang('setting_site')))));
|
||||
$siteConfig=$mconfig->getConfig('site','data');
|
||||
$this->assign('showTime','服务器时间:'.date('Y-m-d H:i:s').' , 服务器的协调世界时(UTC):'.gmdate('Y-m-d H:i:s'));
|
||||
$this->assign('siteConfig',$siteConfig);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
public function site_timezoneAction(){
|
||||
if(request()->isPost()){
|
||||
$offset=input('offset/d',0);
|
||||
$jsTime=input('time',0);
|
||||
$jsTime=$jsTime?intval(substr($jsTime,0,-3)):0;
|
||||
if($jsTime<=0){
|
||||
$this->error('时间错误');
|
||||
}
|
||||
if(abs(time()-$jsTime)>60){
|
||||
$this->error('抱歉,您的服务器时间与实际时间不符!');
|
||||
}
|
||||
$timezone='';
|
||||
if($offset==0){
|
||||
$timezone='UTC';
|
||||
}else{
|
||||
|
||||
$timezone='UTC'.($offset>0?'-':'+').abs($offset);
|
||||
}
|
||||
$this->success('','',array('timezone'=>$timezone));
|
||||
}else{
|
||||
$this->error('自动调整失败');
|
||||
}
|
||||
}
|
||||
|
||||
/*采集设置*/
|
||||
public function caijiAction(){
|
||||
$mconfig=model('Config');
|
||||
|
@ -69,18 +99,23 @@ class Setting extends BaseController {
|
|||
$config['num']=input('num/d',0);
|
||||
$config['interval']=input('interval/d',0);
|
||||
$config['timeout']=input('timeout/d',0);
|
||||
$config['html_interval']=input('html_interval/d',0);
|
||||
$config['interval_html']=input('interval_html/d',0);
|
||||
$config['real_time']=input('real_time/d',0);
|
||||
$config['retry']=input('retry/d',0);
|
||||
$config['wait']=input('wait/d',0);
|
||||
|
||||
unset($config['download_img']);
|
||||
|
||||
if($config['server']=='cli'){
|
||||
if($mconfig->server_is_cli(true,$config['server'])){
|
||||
|
||||
$this->_check_userpwd();
|
||||
|
||||
if(!function_exists('proc_open')){
|
||||
$this->error('抱歉cli命令行模式需开启proc_open函数');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mconfig->setConfig('caiji',$config);
|
||||
if($config['auto']){
|
||||
|
||||
|
@ -88,18 +123,24 @@ class Setting extends BaseController {
|
|||
if($config['run']=='backstage'){
|
||||
|
||||
$runkey=md5(time().rand(1, 1000000));
|
||||
CacheModel::getInstance()->setCache('admin_index_backstage_key', $runkey);
|
||||
CacheModel::getInstance()->setCache('collect_backstage_key', $runkey);
|
||||
@get_html(url('Admin/Index/backstage?key='.$runkey,null,false,true),null,array('timeout'=>3));
|
||||
}
|
||||
}
|
||||
$this->success(lang('op_success'),'Setting/caiji');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']=lang('setting_caiji');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji'))));
|
||||
set_g_sc('p_title',lang('setting_caiji'));
|
||||
set_g_sc('p_name',lang('setting_caiji'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')))));
|
||||
$caijiConfig=$mconfig->getConfig('caiji','data');
|
||||
$caijiConfig=is_array($caijiConfig)?$caijiConfig:array();
|
||||
|
||||
if($caijiConfig['html_interval']>0){
|
||||
|
||||
$caijiConfig['interval_html']=intval($caijiConfig['html_interval'])*1000;
|
||||
}
|
||||
|
||||
$phpExeFile=$mconfig->detect_php_exe();
|
||||
$phpExeFile=\skycaiji\admin\model\Config::detect_php_exe();
|
||||
|
||||
$this->assign('caijiConfig',$caijiConfig);
|
||||
$this->assign('phpExeFile',$phpExeFile);
|
||||
|
@ -111,15 +152,41 @@ class Setting extends BaseController {
|
|||
$mconfig=model('Config');
|
||||
if(request()->isPost()){
|
||||
$config=array();
|
||||
|
||||
$config['download_img']=input('download_img/d',0);
|
||||
$config['data_image']=input('data_image/d',0);
|
||||
$config['interval_img']=input('interval_img/d',0);
|
||||
|
||||
$config['img_timeout']=input('img_timeout/d',0);
|
||||
$config['more_suffix']=input('more_suffix','');
|
||||
$config['retry']=input('retry/d',0);
|
||||
$config['wait']=input('wait/d',0);
|
||||
$config['img_path']=trim(input('img_path',''));
|
||||
$config['img_url']=input('img_url','','trim');
|
||||
$config['img_name']=input('img_name','');
|
||||
$config['img_timeout']=input('img_timeout/d',0);
|
||||
$config['img_interval']=input('img_interval/d',0);
|
||||
$config['img_max']=input('img_max/d',0);
|
||||
$config['name_custom_path']=input('name_custom_path','');
|
||||
$config['name_custom_name']=input('name_custom_name','');
|
||||
$config['charset']=input('charset','');
|
||||
$config['charset_custom']=input('charset_custom','');
|
||||
$config['img_max']=input('img_max/d',0);
|
||||
|
||||
$config['img_func']=input('img_func','');
|
||||
$config['img_func_param']=input('img_func_param','');
|
||||
|
||||
|
||||
if(!empty($config['more_suffix'])){
|
||||
if(preg_match_all('/\b[a-zA-Z]\w+\b/i', $config['more_suffix'],$msuffix)){
|
||||
|
||||
$msuffix=$msuffix[0];
|
||||
$msuffix=implode(',', $msuffix);
|
||||
$config['more_suffix']=strtolower($msuffix);
|
||||
}else{
|
||||
$config['more_suffix']='';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!empty($config['img_path'])){
|
||||
|
||||
$checkImgPath=$mconfig->check_img_path($config['img_path']);
|
||||
|
@ -127,6 +194,7 @@ class Setting extends BaseController {
|
|||
$this->error($checkImgPath['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($config['img_url'])){
|
||||
|
||||
$checkImgUrl=$mconfig->check_img_url($config['img_url']);
|
||||
|
@ -135,6 +203,7 @@ class Setting extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
$checkNamePath=$mconfig->check_img_name_path($config['name_custom_path']);
|
||||
if($config['img_name']=='custom'){
|
||||
|
||||
|
@ -164,18 +233,44 @@ class Setting extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
if($config['charset']=='custom'&&empty($config['charset_custom'])){
|
||||
$this->error('请输入系统编码自定义内容');
|
||||
}
|
||||
|
||||
$mconfig->setConfig('download_img',$config);
|
||||
|
||||
$this->success(lang('op_success'),'Setting/download_img');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='图片本地化设置';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/download_img'),'title'=>'图片本地化')));
|
||||
set_g_sc('p_title','图片本地化设置');
|
||||
set_g_sc('p_name','图片本地化设置');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/download_img'),'title'=>'图片本地化'))));
|
||||
$imgConfig=$mconfig->getConfig('download_img','data');
|
||||
if(empty($imgConfig)){
|
||||
|
||||
$caijiConfig=$mconfig->getConfig('caiji','data');
|
||||
$imgConfig=$mconfig->get_img_config_from_caiji($caijiConfig);
|
||||
}
|
||||
|
||||
if(!is_array($imgConfig)){
|
||||
$imgConfig=array();
|
||||
}
|
||||
|
||||
if(empty($imgConfig)){
|
||||
|
||||
|
||||
$imgConfig['img_timeout']=0;
|
||||
$imgConfig['img_max']=0;
|
||||
$imgConfig['interval_img']=0;
|
||||
$imgConfig['wait']=0;
|
||||
$imgConfig['retry']=0;
|
||||
}else{
|
||||
|
||||
if($imgConfig['img_interval']>0){
|
||||
|
||||
$imgConfig['interval_img']=$imgConfig['img_interval']*1000;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assign('imgConfig',$imgConfig);
|
||||
return $this->fetch('download_img');
|
||||
}
|
||||
|
@ -218,6 +313,7 @@ class Setting extends BaseController {
|
|||
$type_list=array_map('trim', $type_list);
|
||||
|
||||
|
||||
$nowTime=time();
|
||||
for($k=count($ip_list);$k>=0;$k--){
|
||||
$v=$ip_list[$k];
|
||||
if(empty($v)){
|
||||
|
@ -233,7 +329,7 @@ class Setting extends BaseController {
|
|||
'failed'=>0,
|
||||
'num'=>0,
|
||||
'time'=>0,
|
||||
'addtime'=>NOW_TIME,
|
||||
'addtime'=>$nowTime,
|
||||
);
|
||||
if($mproxy->where(array('ip'=>$newData['ip']))->count()>0){
|
||||
|
||||
|
@ -248,8 +344,8 @@ class Setting extends BaseController {
|
|||
}
|
||||
|
||||
|
||||
$config['api']=input('api/a','','trim');
|
||||
$config['apis']=input('apis/a','','trim');
|
||||
$config['api']=input('api/a',array(),'trim');
|
||||
$config['apis']=input('apis/a',array(),'trim');
|
||||
$config['apis']=is_array($config['apis'])?$config['apis']:array();
|
||||
foreach ($config['apis'] as $k=>$v){
|
||||
if(empty($v['api_url'])||!preg_match('/^\w+\:\/\//',$v['api_url'])){
|
||||
|
@ -262,8 +358,9 @@ class Setting extends BaseController {
|
|||
$mconfig->setConfig('proxy',$config);
|
||||
$this->success(lang('op_success'),'Setting/Proxy');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='代理设置';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/Proxy'),'title'=>'代理')));
|
||||
set_g_sc('p_title','代理设置');
|
||||
set_g_sc('p_name','代理设置');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/Proxy'),'title'=>'代理'))));
|
||||
$proxyConfig=$mconfig->getConfig('proxy','data');
|
||||
|
||||
$proxyConfig['ip_count']=$mproxy->count();
|
||||
|
@ -280,10 +377,13 @@ class Setting extends BaseController {
|
|||
$config=array();
|
||||
$config['open']=input('open/d',0);
|
||||
$config['api']=input('api','','strtolower');
|
||||
$config['pass_html']=input('pass_html/d',0);
|
||||
$config['interval']=input('interval/d',0);
|
||||
$config['retry']=input('retry/d',0);
|
||||
$config['wait']=input('wait/d',0);
|
||||
|
||||
foreach ($apiTypes as $v){
|
||||
$config[$v]=input($v.'/a',null,'trim');
|
||||
$config[$v]=input($v.'/a',array(),'trim');
|
||||
}
|
||||
if(!empty($config['api'])){
|
||||
|
||||
|
@ -300,9 +400,13 @@ class Setting extends BaseController {
|
|||
$mconfig->setConfig('translate',$config);
|
||||
$this->success(lang('op_success'),'Setting/translate');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='翻译设置';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/translate'),'title'=>'翻译')));
|
||||
set_g_sc('p_title','翻译设置');
|
||||
set_g_sc('p_name','翻译设置');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/translate'),'title'=>'翻译'))));
|
||||
$transConfig=$mconfig->getConfig('translate','data');
|
||||
if(!is_array($transConfig)){
|
||||
$transConfig=array();
|
||||
}
|
||||
$apiLangs=array();
|
||||
foreach ($apiTypes as $api){
|
||||
$transConfig[$api]=is_array($transConfig[$api])?$transConfig[$api]:array();
|
||||
|
@ -318,6 +422,45 @@ class Setting extends BaseController {
|
|||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
/*云端设置*/
|
||||
public function storeAction(){
|
||||
$mconfig=model('Config');
|
||||
if(request()->isPost()){
|
||||
$sameAsPwd=input('same_as_pwd');
|
||||
|
||||
$config=array();
|
||||
$config['authkey']=input('authkey','','trim');
|
||||
$config['authkey_store']=input('authkey_store','','trim');
|
||||
|
||||
$mprov=model('Provider');
|
||||
$check=$mprov->checkAuthkey($config['authkey'],$sameAsPwd);
|
||||
if(!$check['success']){
|
||||
$this->error($check['msg'],'',$check['data']);
|
||||
}
|
||||
$check=$mprov->checkAuthkey($config['authkey_store'],$sameAsPwd);
|
||||
if(!$check['success']){
|
||||
$this->error($check['msg'],'',$check['data']);
|
||||
}
|
||||
|
||||
$mconfig->setConfig('store',$config);
|
||||
$this->success(lang('op_success'),'Setting/store');
|
||||
}else{
|
||||
set_g_sc('p_title',lang('setting_store'));
|
||||
set_g_sc('p_name',lang('setting_store'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/store'),'title'=>lang('setting_store')))));
|
||||
$storeConfig=$mconfig->getConfig('store','data');
|
||||
if(empty($storeConfig)){
|
||||
$storeConfig=array();
|
||||
}
|
||||
|
||||
$provCount=model('Provider')->count();
|
||||
$provCount=intval($provCount);
|
||||
|
||||
$this->assign('storeConfig',$storeConfig);
|
||||
$this->assign('provCount',$provCount);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
/*邮箱设置*/
|
||||
public function emailAction(){
|
||||
$is_test=input('is_test/d',0);
|
||||
|
@ -344,43 +487,36 @@ class Setting extends BaseController {
|
|||
$this->success(lang('op_success'),'Setting/email');
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']=lang('setting_email');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/email'),'title'=>lang('setting_email'))));
|
||||
set_g_sc('p_title',lang('setting_email'));
|
||||
set_g_sc('p_name',lang('setting_email'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/email'),'title'=>lang('setting_email')))));
|
||||
$emailConfig=$mconfig->getConfig('email','data');
|
||||
if(empty($emailConfig)){
|
||||
$emailConfig=array();
|
||||
}
|
||||
$this->assign('emailConfig',$emailConfig);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
/*页面渲染设置*/
|
||||
public function page_renderAction(){
|
||||
$is_test=input('is_test/d',0);
|
||||
$mconfig=model('Config');
|
||||
if(request()->isPost()){
|
||||
$config=array();
|
||||
$config['tool']=strtolower(input('tool'));
|
||||
$config['chrome']=input('chrome/a');
|
||||
$config['chrome']=input('chrome/a',array());
|
||||
$config['timeout']=input('timeout/d');
|
||||
if(!in_array($config['tool'],array('chrome'))){
|
||||
$config['tool']='';
|
||||
}
|
||||
if(empty($config['tool'])){
|
||||
|
||||
|
||||
|
||||
if(!empty($config['tool'])){
|
||||
$this->_check_userpwd();
|
||||
}
|
||||
|
||||
if($config['tool']=='chrome'){
|
||||
if(version_compare(PHP_VERSION,'5.5','<')){
|
||||
|
||||
$this->error('该功能仅支持php5.5及以上版本');
|
||||
}
|
||||
if($config['chrome']['port']==80){
|
||||
$this->error('不能设置为80端口','');
|
||||
}
|
||||
}
|
||||
$mconfig->setConfig('page_render',$config);
|
||||
if($config['tool']=='chrome'){
|
||||
set_time_limit(10);
|
||||
$chromeSoket=new \util\ChromeSocket($config['chrome']['host'],$config['chrome']['port'],$config['timeout'],$config['chrome']['filename']);
|
||||
$chromeSoket=new \util\ChromeSocket($config['chrome']['host'],$config['chrome']['port'],$config['timeout'],$config['chrome']['filename'],$config['chrome']);
|
||||
try {
|
||||
$chromeSoket->openHost();
|
||||
}catch (\Exception $ex){
|
||||
|
@ -389,15 +525,16 @@ class Setting extends BaseController {
|
|||
}
|
||||
$this->success(lang('op_success'),'Setting/page_render');
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='页面渲染设置 <small><a href="https://www.skycaiji.com/manual/doc/page_render" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/page_render'),'title'=>'页面渲染')));
|
||||
set_g_sc('p_title','页面渲染设置');
|
||||
set_g_sc('p_name','页面渲染设置 <small><a href="https://www.skycaiji.com/manual/doc/page_render" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/page_render'),'title'=>'页面渲染'))));
|
||||
$config=$mconfig->getConfig('page_render','data');
|
||||
$this->assign('config',$config);
|
||||
|
||||
if($config['tool']=='chrome'){
|
||||
if($mconfig->page_render_is_chrome(true,$config['tool'])){
|
||||
|
||||
$cConfig=$config['chrome'];
|
||||
$chromeSoket=new \util\ChromeSocket($cConfig['host'],$cConfig['port'],$config['timeout'],$cConfig['filename']);
|
||||
$chromeSoket=new \util\ChromeSocket($cConfig['host'],$cConfig['port'],$config['timeout'],$cConfig['filename'],$cConfig);
|
||||
$toolIsOpen=$chromeSoket->hostIsOpen();
|
||||
$this->assign('toolIsOpen',$toolIsOpen);
|
||||
}
|
||||
|
@ -406,9 +543,84 @@ class Setting extends BaseController {
|
|||
}
|
||||
/*清理缓存目录*/
|
||||
public function cleanAction(){
|
||||
set_time_limit(1000);
|
||||
$path=realpath(config('root_path').'/runtime');
|
||||
clear_dir($path);
|
||||
$this->success();
|
||||
if(request()->isPost()){
|
||||
set_time_limit(1000);
|
||||
$path=realpath(config('root_path').'/runtime');
|
||||
\util\Funcs::clear_dir($path);
|
||||
$this->success();
|
||||
}else{
|
||||
$this->error();
|
||||
}
|
||||
}
|
||||
|
||||
private function _check_userpwd(){
|
||||
if(!input('?_userpwd_')){
|
||||
$this->error('','',array('_userpwd_'=>true));
|
||||
}
|
||||
$userpwd=input('_userpwd_','');
|
||||
if(empty($userpwd)){
|
||||
$this->error('请输入密码','',array('_userpwd_'=>true));
|
||||
}
|
||||
$user=g_sc('user');
|
||||
if(empty($user)){
|
||||
$this->error('请先登录');
|
||||
}
|
||||
if(\skycaiji\admin\model\User::pwd_encrypt($userpwd,$user['salt'])!=$user['password']){
|
||||
|
||||
$this->error('密码错误','',array('_userpwd_'=>true));
|
||||
}
|
||||
}
|
||||
/*测试php*/
|
||||
public function test_phpAction(){
|
||||
if(request()->isPost()){
|
||||
$this->_check_userpwd();
|
||||
|
||||
if(!function_exists('proc_open')){
|
||||
$this->error('需开启proc_open函数');
|
||||
}else{
|
||||
$phpFile=input('php','','trim');
|
||||
|
||||
$phpvInfo=model('Config')->exec_php_version($phpFile);
|
||||
if($phpvInfo===false){
|
||||
$this->error('未检测到PHP可执行文件,请手动输入');
|
||||
}else{
|
||||
if($phpvInfo['success']){
|
||||
$this->success($phpvInfo['msg']?$phpvInfo['msg']:'测试成功');
|
||||
}else{
|
||||
$this->error($phpvInfo['msg']?$phpvInfo['msg']:'测试失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->error('测试失败');
|
||||
}
|
||||
/*测试chrome*/
|
||||
public function test_chromeAction(){
|
||||
if(request()->isPost()){
|
||||
$this->_check_userpwd();
|
||||
$chrome=input('chrome/a',array());
|
||||
|
||||
$return=\util\ChromeSocket::execHeadless($chrome['filename'], $chrome['port'], $chrome, 'all', true);
|
||||
if(!empty($return['error'])){
|
||||
|
||||
$this->error($return['error']);
|
||||
}else{
|
||||
|
||||
$info=is_array($return['info'])?$return['info']:array();
|
||||
if(is_array($info['status'])&&$info['status']['running']){
|
||||
|
||||
if($info['error']){
|
||||
$this->error($info['error']);
|
||||
}elseif($info['output']){
|
||||
$this->success('测试成功:'.$info['output']);
|
||||
}else{
|
||||
$this->success('测试成功');
|
||||
}
|
||||
}elseif($info['error']){
|
||||
$this->error($info['error']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->error('测试失败');
|
||||
}
|
||||
}
|
|
@ -10,249 +10,235 @@
|
|||
*/
|
||||
|
||||
namespace skycaiji\admin\controller;
|
||||
use think\Controller;
|
||||
|
||||
class Store extends BaseController {
|
||||
|
||||
public function downloadAction(){
|
||||
$mprov=model('Provider');
|
||||
$resultData=$mprov->storeAuthResult();
|
||||
if(!$resultData['success']){
|
||||
|
||||
$this->error($resultData['msg'],'');
|
||||
}
|
||||
$resultData=$resultData['data'];
|
||||
$provId=$resultData['provider_id'];
|
||||
|
||||
$storeAddon=input('store_addon','','trim');
|
||||
$storeAddon=json_decode(base64_decode($storeAddon),true);
|
||||
if(!is_array($storeAddon)||empty($storeAddon)){
|
||||
$this->error('下载参数错误','');
|
||||
}
|
||||
$storeAddon=array_map('strip_tags', $storeAddon);
|
||||
list($addonCat,$addonId,$addonVer,$addonName)=$storeAddon;
|
||||
$addonCat=strtolower($addonCat);
|
||||
|
||||
$cats=array('rule'=>'采集规则','plugin'=>'插件','app'=>'应用程序');
|
||||
$catName=$cats[$addonCat];
|
||||
|
||||
$existAddon=false;
|
||||
$updateAddon=false;
|
||||
if(in_array($addonCat, array('rule','plugin'))){
|
||||
if('rule'==$addonCat){
|
||||
$addonData=model('Rule')->where(array('store_id'=>$addonId,'provider_id'=>$provId))->find();
|
||||
}elseif('plugin'==$addonCat){
|
||||
$addonData=model('ReleaseApp')->where('app',$addonId)->find();
|
||||
if(empty($addonData)){
|
||||
model('FuncApp')->where('app',$addonId)->find();
|
||||
}
|
||||
}
|
||||
if(!empty($addonData)){
|
||||
$existAddon=true;
|
||||
if($addonVer&&version_compare($addonVer, $addonData['uptime'],'>')){
|
||||
$updateAddon=true;
|
||||
}
|
||||
}
|
||||
}elseif('app'==$addonCat){
|
||||
|
||||
$mapp=model('App');
|
||||
$existAddon=file_exists($mapp->app_class_file($addonId))?true:false;
|
||||
if($existAddon){
|
||||
$appVersion=$mapp->app_class($addonId,false,'version');
|
||||
if($addonVer&&version_compare($addonVer, $appVersion,'>')){
|
||||
$updateAddon=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tips=$updateAddon?'更新':'下载';
|
||||
|
||||
set_g_sc('p_title',$tips.$catName);
|
||||
set_g_sc('p_name',$tips.$catName);
|
||||
set_g_sc('p_nav',breadcrumb(array($tips.$catName)));
|
||||
|
||||
$downloadData = array(
|
||||
'provider_id' => $provId,
|
||||
'addon_cat' => $addonCat,
|
||||
'addon_id' => $addonId,
|
||||
'addon_name' => $addonName,
|
||||
'exist_addon' => $existAddon,
|
||||
'update_addon' => $updateAddon,
|
||||
'cat_name' => $catName
|
||||
);
|
||||
$this->assign('downloadData',$downloadData);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
public function installAction(){
|
||||
$this->check_usertoken();
|
||||
|
||||
$provId=input('provider_id/d',0);
|
||||
$addonCat=input('addon_cat','','strtolower');
|
||||
$addonId=input('addon_id','','trim');
|
||||
$provData=null;
|
||||
$mprov=model('Provider');
|
||||
if($provId>0){
|
||||
|
||||
$provData=$mprov->getById($provId);
|
||||
$check=$mprov->checkData($provData);
|
||||
if(!$check['success']){
|
||||
$this->error($check['msg']);
|
||||
}
|
||||
}
|
||||
$provId=empty($provData)?0:$provData['id'];
|
||||
$authkey=$mprov->getAuthkey($provData);
|
||||
$storeUrl=$mprov->getStoreUrl($provData);
|
||||
|
||||
$timestamp=time();
|
||||
|
||||
$clientinfo=clientinfo();
|
||||
$authsign=$mprov->createAuthsign($authkey,$clientinfo['url'],$storeUrl,$timestamp);
|
||||
|
||||
$uriParams=array(
|
||||
'authsign'=>$authsign,
|
||||
'client_url'=>$clientinfo['url'],
|
||||
'timestamp'=>$timestamp,
|
||||
'addon'=>$addonCat.':'.$addonId,
|
||||
);
|
||||
|
||||
if($addonCat=='app'){
|
||||
|
||||
$blockNo=input('block_no/d',0);
|
||||
$uriParams['block_no']=$blockNo;
|
||||
}
|
||||
|
||||
$storeData=curl_store($provData?$provData['url']:'','/client/addon/download?'.http_build_query($uriParams));
|
||||
$storeData=json_decode($storeData,true);
|
||||
$storeData=is_array($storeData)?$storeData:array();
|
||||
$storeData['data']=is_array($storeData['data'])?$storeData['data']:array();
|
||||
|
||||
if(!$storeData['code']){
|
||||
|
||||
$this->error('下载失败'.($storeData['msg']?(':'.$storeData['msg']):''));
|
||||
}
|
||||
|
||||
$result=array();
|
||||
$successUrl='';
|
||||
$successData=array();
|
||||
|
||||
if($addonCat=='rule'){
|
||||
|
||||
$rule=$storeData['data']['rule'];
|
||||
$rule=json_decode(base64_decode($rule),true);
|
||||
$result=$this->_installRule($rule,$provId);
|
||||
$successUrl='Mystore/rule';
|
||||
}elseif($addonCat=='plugin'){
|
||||
|
||||
$plugin=$storeData['data']['plugin'];
|
||||
$plugin=json_decode(base64_decode($plugin),true);
|
||||
$result=$this->_installPlugin($plugin,$provId);
|
||||
$successUrl='Mystore/'.$plugin['type'].'App';
|
||||
}elseif($addonCat=='app'){
|
||||
|
||||
$app=$storeData['data']['app'];
|
||||
$app=json_decode(base64_decode($app),true);
|
||||
$result=$this->_installApp($app,$provId);
|
||||
$successUrl='Mystore/app';
|
||||
$successData=$result;
|
||||
}
|
||||
if($result['success']){
|
||||
$this->success('下载完成',$successUrl,$successData);
|
||||
}else{
|
||||
$this->error('安装失败'.($result['msg']?(':'.$result['msg']):''));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function _installRule($rule,$provId=0){
|
||||
$result=array('success'=>false,'msg'=>'');
|
||||
|
||||
$rule=is_array($rule)?$rule:array();
|
||||
$rule=array_map('strip_tags', $rule);
|
||||
$store_id=intval($rule['store_id']);
|
||||
if($store_id<=0){
|
||||
$result['msg']='规则id为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($rule['name'])){
|
||||
$result['msg']='规则名称为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($rule['type'])){
|
||||
$result['msg']='规则类型为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($rule['module'])){
|
||||
$result['msg']='规则模块为空';
|
||||
return $result;
|
||||
}
|
||||
$rule['config']=base64_decode($rule['config']);
|
||||
if(empty($rule['config'])){
|
||||
$result['msg']='规则为空';
|
||||
return $result;
|
||||
}
|
||||
$newRule=array('type'=>$rule['type'],'module'=>$rule['module'],'store_id'=>$store_id,'name'=>$rule['name'],'uptime'=>($rule['uptime']>0?$rule['uptime']:time()),'config'=>$rule['config']);
|
||||
|
||||
$mrule=model('Rule');
|
||||
|
||||
if(!empty($rule['store_url'])){
|
||||
$newRule['provider_id']=model('Provider')->getIdByUrl($rule['store_url']);
|
||||
}else{
|
||||
$newRule['provider_id']=intval($provId);
|
||||
}
|
||||
|
||||
$ruleData=$mrule->where(array('store_id'=>$newRule['store_id'],'provider_id'=>$newRule['provider_id']))->find();
|
||||
if(empty($ruleData)){
|
||||
|
||||
$newRule['addtime']=time();
|
||||
$mrule->isUpdate(false)->allowField(true)->save($newRule);
|
||||
}else{
|
||||
|
||||
$mrule->strict(false)->where(array('id'=>$ruleData['id']))->update($newRule);
|
||||
}
|
||||
$result['success']=true;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isLoginAction(){
|
||||
if(empty($GLOBALS['_sc']['user'])){
|
||||
$this->dispatchJump(false,lang('user_error_is_not_admin'),url('Admin/Index/index',null,null,true));
|
||||
}else{
|
||||
$token=$this->_getToken();
|
||||
if(empty($token)){
|
||||
$token=md5(request()->server('HTTP_ORIGIN').date('Y-m-d H:i:s',time()).rand(1,1000000));
|
||||
session('store_token',array('token'=>$token,time=>time()));
|
||||
}
|
||||
|
||||
$this->dispatchJump(true,$token);
|
||||
}
|
||||
}
|
||||
/*安装规则*/
|
||||
public function installRuleAction(){
|
||||
$this->_checkRequest();
|
||||
|
||||
$mrule=model('Rule');
|
||||
$rule=json_decode(base64_decode(input('post.rule')),true);
|
||||
|
||||
$store_id=intval($rule['store_id']);
|
||||
if(empty($store_id)){
|
||||
$this->dispatchJump(false,'规则id为空');
|
||||
}
|
||||
if(empty($rule['name'])){
|
||||
$this->dispatchJump(false,'名称为空');
|
||||
}
|
||||
if(empty($rule['type'])){
|
||||
$this->dispatchJump(false,'类型错误');
|
||||
}
|
||||
if(empty($rule['module'])){
|
||||
$this->dispatchJump(false,'模块错误');
|
||||
}
|
||||
$rule['config']=base64_decode($rule['config']);
|
||||
if(empty($rule['config'])){
|
||||
$this->dispatchJump(false,'规则为空');
|
||||
}
|
||||
if($store_id>0){
|
||||
$newRule=array('type'=>$rule['type'],'module'=>$rule['module'],'store_id'=>$store_id,'name'=>$rule['name'],'uptime'=>($rule['uptime']>0?$rule['uptime']:time()),'config'=>$rule['config']);
|
||||
|
||||
$newRule['provider_id']=$this->_getStoreProvid($rule['store_url']);
|
||||
$ruleData=$mrule->where(array('store_id'=>$newRule['store_id'],'provider_id'=>$newRule['provider_id']))->find();
|
||||
if(empty($ruleData)){
|
||||
|
||||
$newRule['addtime']=NOW_TIME;
|
||||
$mrule->isUpdate(false)->allowField(true)->save($newRule);
|
||||
$ruleId=$mrule->id;
|
||||
}else{
|
||||
|
||||
$mrule->strict(false)->where(array('id'=>$ruleData['id']))->update($newRule);
|
||||
$ruleId=$ruleData['id'];
|
||||
}
|
||||
$this->dispatchJump(true,$ruleId);
|
||||
}else{
|
||||
$this->dispatchJump(false,'id错误');
|
||||
}
|
||||
}
|
||||
/*安装插件*/
|
||||
public function installPluginAction(){
|
||||
$this->_checkRequest();
|
||||
|
||||
$plugin=json_decode(base64_decode(input('post.plugin')),true);
|
||||
$result=$this->_installPlugin($plugin);
|
||||
|
||||
$this->dispatchJump($result['success'],$result['msg']);
|
||||
}
|
||||
/*安装应用程序*/
|
||||
public function installAppAction(){
|
||||
$this->_checkRequest();
|
||||
|
||||
$app=json_decode(base64_decode(input('post.app')),true);
|
||||
if(empty($app['app'])){
|
||||
$this->dispatchJump(false,'app标识错误');
|
||||
}
|
||||
if(!preg_match('/^[\w\-]+$/',$app['app'])){
|
||||
$this->dispatchJump(false,'app标识不规范');
|
||||
}
|
||||
if(empty($app['data'])){
|
||||
$this->dispatchJump(false,'数据错误');
|
||||
}
|
||||
$app['data']=base64_decode($app['data']);
|
||||
|
||||
$filePath=RUNTIME_PATH.'/cache_app_zip/'.$app['app'].'/';
|
||||
|
||||
$complete=false;
|
||||
if($app['block']>0){
|
||||
|
||||
$app['no']=intval($app['no']);
|
||||
write_dir_file($filePath.$app['no'],$app['data']);
|
||||
|
||||
$blockComplete=true;
|
||||
for($i=1;$i<=$app['block'];$i++){
|
||||
if(!file_exists($filePath.$i)){
|
||||
|
||||
$blockComplete=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($blockComplete){
|
||||
|
||||
$data=null;
|
||||
for($i=1;$i<=$app['block'];$i++){
|
||||
$data.=file_get_contents($filePath.$i);
|
||||
}
|
||||
write_dir_file($filePath.$app['app'].'.zip',$data);
|
||||
$complete=true;
|
||||
unset($data);
|
||||
}
|
||||
}else{
|
||||
|
||||
write_dir_file($filePath.$app['app'].'.zip',$app['data']);
|
||||
$complete=true;
|
||||
}
|
||||
if($complete){
|
||||
|
||||
$error='';
|
||||
try {
|
||||
$zipClass=new \ZipArchive();
|
||||
if($zipClass->open($filePath.$app['app'].'.zip')===TRUE){
|
||||
$zipClass->extractTo(config('apps_path').'/'.$app['app']);
|
||||
$zipClass->close();
|
||||
}else{
|
||||
$error='解压失败';
|
||||
}
|
||||
}catch(\Exception $ex){
|
||||
$error='您的服务器不支持ZipArchive解压';
|
||||
}
|
||||
|
||||
if($error){
|
||||
$this->dispatchJump(false,$error);
|
||||
}else{
|
||||
clear_dir($filePath);
|
||||
$this->dispatchJump(true);
|
||||
}
|
||||
}else{
|
||||
$this->dispatchJump(true);
|
||||
}
|
||||
}
|
||||
/*统一检测更新*/
|
||||
public function updateAction(){
|
||||
$updateList=array('status'=>1,'data'=>array());
|
||||
if(request()->isAjax()){
|
||||
$storeIds=input('store_ids');
|
||||
$storeIds=explode(',', $storeIds);
|
||||
|
||||
$storeApps=input('store_apps');
|
||||
$storeApps=explode(',', $storeApps);
|
||||
|
||||
$storeIdList=array();
|
||||
foreach ($storeIds as $id){
|
||||
if(preg_match('/^(\w+)_(\w+)$/',$id,$id)){
|
||||
$storeIdList[$id[1]][$id[2]]=$id[2];
|
||||
}
|
||||
}
|
||||
|
||||
$storeAppList=array();
|
||||
foreach ($storeApps as $app){
|
||||
if(preg_match('/^(\w+)_(\w+)$/',$app,$app)){
|
||||
$storeAppList[$app[1]][$app[2]]=$app[2];
|
||||
}
|
||||
}
|
||||
|
||||
$provId=$this->_getStoreProvid(input('store_url'));
|
||||
|
||||
|
||||
if(!empty($storeIdList)){
|
||||
foreach ($storeIdList as $type=>$ids){
|
||||
$list=array();
|
||||
$cond=array('store_id'=>array('in',$ids),'provider_id'=>$provId,'type'=>$type);
|
||||
$list=model('Rule')->field('`id`,`store_id`,`uptime`')->where($cond)->column('uptime','store_id');
|
||||
$list=is_array($list)?$list:array();
|
||||
$updateList['data'][$type]=$list;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($storeAppList)){
|
||||
foreach ($storeAppList as $type=>$apps){
|
||||
if(empty($type)){
|
||||
continue;
|
||||
}
|
||||
$list=array();
|
||||
$cond=array('app'=>array('in',$apps),'provider_id'=>$provId);
|
||||
if($type=='release'||$type=='cms'){
|
||||
$list=model('ReleaseApp')->where($cond)->column('uptime','app');
|
||||
}elseif($type=='func'){
|
||||
$list=model('FuncApp')->where($cond)->column('uptime','app');
|
||||
}elseif($type=='app'){
|
||||
foreach ($apps as $app){
|
||||
|
||||
$appClass=model('App')->app_class($app,false);
|
||||
$list[$app]=$appClass->config['version'];
|
||||
}
|
||||
}
|
||||
$list=is_array($list)?$list:array();
|
||||
$updateList['data'][$type]=$list;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsonp($updateList);
|
||||
}
|
||||
/*站点验证*/
|
||||
public function siteCertificationAction(){
|
||||
$this->_checkRequest();
|
||||
|
||||
$op=input('op');
|
||||
if($op=='set_key'){
|
||||
|
||||
$key=input('post.key');
|
||||
if(empty($key)){
|
||||
$this->dispatchJump(false,'密钥错误');
|
||||
}
|
||||
cache('site_certification',array('key'=>$key,'time'=>NOW_TIME));
|
||||
$this->dispatchJump(true);
|
||||
}else{
|
||||
$this->dispatchJump(false,'错误操作!');
|
||||
}
|
||||
}
|
||||
|
||||
public function _installPlugin($plugin){
|
||||
public function _installPlugin($plugin,$provId=0){
|
||||
$result=array('success'=>false,'msg'=>'');
|
||||
|
||||
|
||||
$plugin=is_array($plugin)?$plugin:array();
|
||||
$plugin=array_map('strip_tags', $plugin);
|
||||
$plugin['code']=base64_decode($plugin['code']);
|
||||
if(empty($plugin['app'])){
|
||||
$result['msg']='标识错误';
|
||||
$result['msg']='插件标识为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($plugin['name'])){
|
||||
$result['msg']='名称错误';
|
||||
$result['msg']='插件名称为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($plugin['type'])){
|
||||
$result['msg']='类型错误';
|
||||
$result['msg']='插件类型为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($plugin['module'])){
|
||||
$result['msg']='模块错误';
|
||||
$result['msg']='插件模块为空';
|
||||
return $result;
|
||||
}
|
||||
if(empty($plugin['code'])){
|
||||
$result['msg']='插件文件错误';
|
||||
$result['msg']='插件代码为空';
|
||||
return $result;
|
||||
}
|
||||
if(!empty($plugin['tpl'])){
|
||||
|
@ -263,8 +249,13 @@ class Store extends BaseController {
|
|||
$newData=array('app'=>$plugin['app'],'name'=>$plugin['name'],'desc'=>$plugin['desc'],'uptime'=>$plugin['uptime']);
|
||||
|
||||
|
||||
$newData['provider_id']=$this->_getStoreProvid($plugin['store_url']);
|
||||
if(!empty($plugin['store_url'])){
|
||||
$newData['provider_id']=model('Provider')->getIdByUrl($plugin['store_url']);
|
||||
}else{
|
||||
$newData['provider_id']=intval($provId);
|
||||
}
|
||||
|
||||
|
||||
if($plugin['type']=='release'){
|
||||
|
||||
$success=model('ReleaseApp')->addCms($newData,$plugin['code'],$plugin['tpl']);
|
||||
|
@ -277,120 +268,32 @@ class Store extends BaseController {
|
|||
$result['success']=$success?true:false;
|
||||
$result['msg']=$result['success']?'成功':'无效的插件';
|
||||
}else{
|
||||
$result['msg']='类型错误';
|
||||
$result['msg']='插件类型错误';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
/*获取平台域名Id*/
|
||||
protected function _getStoreProvid($storeUrl=null){
|
||||
if(empty($storeUrl)){
|
||||
$referer=request()->server('HTTP_REFERER');
|
||||
if(!empty($referer)){
|
||||
$storeUrl=$referer;
|
||||
}
|
||||
}
|
||||
$provId=model('Provider')->getIdByUrl($storeUrl);
|
||||
return $provId;
|
||||
}
|
||||
/*验证请求源*/
|
||||
protected function _checkRequest(){
|
||||
|
||||
|
||||
$token=request()->server('HTTP_X_STORE_TOKEN');
|
||||
$sessionToken=$this->_getToken();
|
||||
if(empty($token)||empty($sessionToken)||$token!=$sessionToken){
|
||||
$this->dispatchJump(false,'token验证失败,请刷新页面或清除缓存');
|
||||
}
|
||||
|
||||
$this->_checkCors(false);
|
||||
}
|
||||
|
||||
protected function _getToken(){
|
||||
$storeToken=session('store_token');
|
||||
$token=null;
|
||||
if(empty($storeToken)||!is_array($storeToken)||empty($storeToken['token'])){
|
||||
$token='';
|
||||
}else{
|
||||
$token=$storeToken['token'];
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
|
||||
public function _checkCors($openCorsHeader=true){
|
||||
$action=request()->action();
|
||||
if($action=='update'){
|
||||
|
||||
return;
|
||||
private function _installApp($app,$provId=0){
|
||||
$result=array('success'=>false,'msg'=>'','blocks'=>0,'next_block_no'=>0);
|
||||
|
||||
$app=is_array($app)?$app:array();
|
||||
$app=array_map('strip_tags', $app);
|
||||
|
||||
if(empty($app['app'])){
|
||||
$result['msg']='应用标识为空';
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
$httpOrigin=strtolower(request()->server('HTTP_ORIGIN'));
|
||||
if(empty($httpOrigin)){
|
||||
$httpOrigin='';
|
||||
}else{
|
||||
if(preg_match('/^\w+\:\/\//', $httpOrigin)){
|
||||
$httpOrigin=rtrim($httpOrigin,'/');
|
||||
}else{
|
||||
|
||||
$httpOrigin='';
|
||||
}
|
||||
if(!preg_match('/^[\w\-]+$/',$app['app'])){
|
||||
$result['msg']='应用标识不规范';
|
||||
return $result;
|
||||
}
|
||||
|
||||
$isAllowOrigin=false;
|
||||
|
||||
$provData=null;
|
||||
|
||||
if(!empty($httpOrigin)){
|
||||
if(in_array($httpOrigin,config('allow_origins'))){
|
||||
|
||||
$isAllowOrigin=true;
|
||||
}else{
|
||||
|
||||
$provData=model('Provider')->where(array('domain'=>$httpOrigin))->find();
|
||||
if(!empty($provData)&&$provData['enable']==1){
|
||||
|
||||
$isAllowOrigin=true;
|
||||
}
|
||||
}
|
||||
if($isAllowOrigin&&$openCorsHeader){
|
||||
|
||||
|
||||
header('Access-Control-Allow-Origin:'.$httpOrigin);
|
||||
|
||||
header('Access-Control-Allow-Credentials:true');
|
||||
|
||||
header('Access-Control-Allow-Methods:POST,GET');
|
||||
|
||||
header('Access-Control-Allow-Headers:X-Requested-With,X-Store-Token,Content-Type');
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$httpWith=request()->server('HTTP_X_REQUESTED_WITH');
|
||||
if(empty($httpWith)||strtolower($httpWith)!='xmlhttprequest'){
|
||||
|
||||
$this->dispatchJump(false,'不是ajax请求');
|
||||
}
|
||||
|
||||
if(empty($httpOrigin)){
|
||||
|
||||
$this->dispatchJump(false,'未知来源');
|
||||
}else{
|
||||
|
||||
if(!$isAllowOrigin){
|
||||
|
||||
if(empty($provData)){
|
||||
|
||||
$this->dispatchJump(false,'未知的第三方来源:'.$httpOrigin);
|
||||
}else{
|
||||
|
||||
$this->dispatchJump(false,'未受信任的第三方来源:'.$httpOrigin);
|
||||
}
|
||||
}
|
||||
if(empty($app['md5'])){
|
||||
$result['msg']='应用md5码为空';
|
||||
return $result;
|
||||
}
|
||||
$filePath=RUNTIME_PATH.'zip_app/'.$app['app'];
|
||||
$result=\util\Funcs::install_downloaded_zip($app, $filePath, config('apps_path').'/'.$app['app']);
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -121,8 +121,9 @@ class Task extends BaseController {
|
|||
$this->assign('pagenav',$pagenav);
|
||||
}
|
||||
$showChange=$show=='list'?'folder':'list';
|
||||
$GLOBALS['_sc']['p_name']=lang('task_list').' <small><a href="'.url('Task/list?show='.$showChange).'">'.lang('task_change_'.$showChange).'</a></small>';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list'))));
|
||||
set_g_sc('p_title',lang('task_list'));
|
||||
set_g_sc('p_name',lang('task_list').' <small><a href="'.url('Task/list?show='.$showChange).'" title="切换'.lang('task_change_'.$showChange).'">'.lang('task_change_'.$showChange).'</a></small>');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')))));
|
||||
return $this->fetch('list_'.$show);
|
||||
}
|
||||
/*任务列表,打开文件夹*/
|
||||
|
@ -163,9 +164,10 @@ class Task extends BaseController {
|
|||
if(input('?config.img_url')){
|
||||
$newData['config']['img_url']=input('config.img_url','','trim');
|
||||
}
|
||||
$newData['sort']=min(intval($newData['sort']),999999);
|
||||
$newData['config']=$this->_save_config($newData['config']);
|
||||
$newData['config']=serialize($newData['config']);
|
||||
$newData['addtime']=NOW_TIME;
|
||||
$newData['addtime']=time();
|
||||
|
||||
$importColl=null;
|
||||
$importRele=null;
|
||||
|
@ -202,7 +204,7 @@ class Task extends BaseController {
|
|||
|
||||
$importRele=$importRele->toArray();
|
||||
$importRele['task_id']=$taskData['id'];
|
||||
$importRele['addtime']=NOW_TIME;
|
||||
$importRele['addtime']=time();
|
||||
unset($importRele['id']);
|
||||
model('Release')->isUpdate(false)->allowField(true)->save($importRele);
|
||||
}
|
||||
|
@ -221,9 +223,12 @@ class Task extends BaseController {
|
|||
$mtaskgroup=model('Taskgroup');
|
||||
$tgSelect=$mtaskgroup->getLevelSelect();
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('task_add');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),array('url'=>url('Task/add'),'title'=>lang('task_add'))));
|
||||
set_g_sc('p_title',lang('task_add'));
|
||||
set_g_sc('p_name',lang('task_add'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),array('url'=>url('Task/add'),'title'=>lang('task_add')))));
|
||||
|
||||
|
||||
$this->assign('gConfig',$this->_global_caiji_config());
|
||||
$this->assign('tgSelect',$tgSelect);
|
||||
|
||||
if(request()->isAjax()){
|
||||
|
@ -249,7 +254,6 @@ class Task extends BaseController {
|
|||
|
||||
if(request()->isPost()){
|
||||
$newData=input('param.');
|
||||
|
||||
$validate=Loader::validate('Task');
|
||||
if(!$validate->scene('edit')->check($newData)){
|
||||
|
||||
|
@ -258,6 +262,7 @@ class Task extends BaseController {
|
|||
if(input('?config.img_url')){
|
||||
$newData['config']['img_url']=input('config.img_url','','trim');
|
||||
}
|
||||
$newData['sort']=min(intval($newData['sort']),999999);
|
||||
$newData['config']=$this->_save_config($newData['config']);
|
||||
$newData['config']=serialize($newData['config']);
|
||||
if($taskData['name']!=$newData['name']){
|
||||
|
@ -281,14 +286,16 @@ class Task extends BaseController {
|
|||
}
|
||||
}else{
|
||||
$taskData=$taskData->getData();
|
||||
$taskData=is_array($taskData)?$taskData:array();
|
||||
$taskData['config']=unserialize($taskData['config']);
|
||||
$taskData['config']=is_array($taskData['config'])?$taskData['config']:array();
|
||||
|
||||
$mtaskgroup=model('Taskgroup');
|
||||
$tgSelect=$mtaskgroup->getLevelSelect();
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('task_edit').':'.$taskData['name'];
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>$taskData['name'])));
|
||||
set_g_sc('p_title','任务:'.$taskData['name']);
|
||||
set_g_sc('p_name',lang('task_edit').':'.$taskData['name']);
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>$taskData['name']))));
|
||||
|
||||
$fieldList=array();
|
||||
$collData=model('Collector')->where(array('task_id'=>$taskData['id']))->find();
|
||||
|
@ -303,6 +310,7 @@ class Task extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
$this->assign('gConfig',$this->_global_caiji_config());
|
||||
$this->assign('tgSelect',$tgSelect);
|
||||
$this->assign('taskData',$taskData);
|
||||
$this->assign('fieldList',$fieldList);
|
||||
|
@ -313,27 +321,93 @@ class Task extends BaseController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function _global_caiji_config(){
|
||||
$imgFuncParam=g_sc_c('download_img','img_func_param');
|
||||
if($imgFuncParam){
|
||||
$imgFuncParam=str_replace("\r", '\r', $imgFuncParam);
|
||||
$imgFuncParam=str_replace("\n", '\n', $imgFuncParam);
|
||||
$imgFuncParam=htmlspecialchars($imgFuncParam,ENT_QUOTES);
|
||||
}else{
|
||||
$imgFuncParam='';
|
||||
}
|
||||
|
||||
$gConfig=array(
|
||||
'num'=>intval(g_sc_c('caiji','num')),
|
||||
'interval'=>intval(g_sc('c_caiji_interval')),
|
||||
'interval_html'=>intval(g_sc_c('caiji','interval_html')),
|
||||
'real_time'=>g_sc_c('caiji','real_time')>0?'是':'否',
|
||||
'proxy'=>g_sc_c('proxy','open')>0?'是':'否',
|
||||
'download_img'=>g_sc_c('download_img','download_img')>0,
|
||||
'img_path'=>g_sc_c('download_img','img_path')?g_sc_c('download_img','img_path'):(config('root_path').DS.'data'.DS.'images'),
|
||||
'img_url'=>g_sc_c('download_img','img_url')?g_sc_c('download_img','img_url'):(config('root_website').'/data/images'),
|
||||
'img_name'=>g_sc_c('download_img','img_name'),
|
||||
'name_custom_path'=>g_sc_c('download_img','name_custom_path')?g_sc_c('download_img','name_custom_path'):'无',
|
||||
'name_custom_name'=>lang('down_img_name_custom_name_'.g_sc_c('download_img','name_custom_name')),
|
||||
'interval_img'=>intval(g_sc_c('download_img','interval_img')),
|
||||
'img_func'=>g_sc_c('download_img','img_func'),
|
||||
'img_func_param'=>$imgFuncParam
|
||||
);
|
||||
return $gConfig;
|
||||
}
|
||||
|
||||
/*保持更多设置*/
|
||||
public function _save_config($config=array()){
|
||||
$config=is_array($config)?$config:array();
|
||||
$config['num']=intval($config['num']);
|
||||
$config['interval']=intval($config['interval']);
|
||||
$config['interval_html']=intval($config['interval_html']);
|
||||
$config['img_path']=trim($config['img_path']);
|
||||
$config['img_url']=trim($config['img_url']);
|
||||
|
||||
$config['interval_img']=intval($config['interval_img']);
|
||||
|
||||
$mconfig=model('Config');
|
||||
|
||||
if(!empty($config['img_path'])){
|
||||
|
||||
$checkImgPath=model('Config')->check_img_path($config['img_path']);
|
||||
$checkImgPath=$mconfig->check_img_path($config['img_path']);
|
||||
if(!$checkImgPath['success']){
|
||||
$this->error($checkImgPath['msg']);
|
||||
}
|
||||
}
|
||||
if(!empty($config['img_url'])){
|
||||
|
||||
$checkImgUrl=model('Config')->check_img_url($config['img_url']);
|
||||
$checkImgUrl=$mconfig->check_img_url($config['img_url']);
|
||||
if(!$checkImgUrl['success']){
|
||||
$this->error($checkImgUrl['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
$checkNamePath=$mconfig->check_img_name_path($config['name_custom_path']);
|
||||
if($config['img_name']=='custom'){
|
||||
|
||||
if(empty($config['name_custom_path'])&&is_empty(g_sc_c('download_img','name_custom_path'))){
|
||||
|
||||
$this->error('请输入图片名称自定义路径');
|
||||
}
|
||||
if(!$checkNamePath['success']){
|
||||
$this->error($checkNamePath['msg']);
|
||||
}
|
||||
}else{
|
||||
|
||||
if(!$checkNamePath['success']){
|
||||
$config['name_custom_path']='';
|
||||
}
|
||||
}
|
||||
|
||||
$checkNameName=$mconfig->check_img_name_name($config['name_custom_name']);
|
||||
if($config['img_name']=='custom'){
|
||||
|
||||
if(!empty($config['name_custom_name'])&&!$checkNameName['success']){
|
||||
$this->error($checkNameName['msg']);
|
||||
}
|
||||
}else{
|
||||
|
||||
if(!$checkNameName['success']){
|
||||
$config['name_custom_name']='';
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
/*导入规则*/
|
||||
|
@ -381,7 +455,7 @@ class Task extends BaseController {
|
|||
|
||||
|
||||
$collData=$mcoll->where(array('task_id'=>$taskData['id'],'module'=>$module))->find();
|
||||
$newColl=array('name'=>$name,'module'=>$module,'task_id'=>$taskData['id'],'config'=>$config,'uptime'=>NOW_TIME);
|
||||
$newColl=array('name'=>$name,'module'=>$module,'task_id'=>$taskData['id'],'config'=>$config,'uptime'=>time());
|
||||
if(empty($collData)){
|
||||
$mcoll->add_new($newColl);
|
||||
}else{
|
||||
|
@ -421,10 +495,11 @@ class Task extends BaseController {
|
|||
$this->success(lang('op_success'));
|
||||
}elseif($op=='saveall'){
|
||||
|
||||
$newsort=input('newsort/a');
|
||||
$newsort=input('newsort/a',array());
|
||||
if(is_array($newsort)&&count($newsort)>0){
|
||||
foreach ($newsort as $key=>$val){
|
||||
$mtask->strict(false)->where('id',intval($key))->update(array('sort'=>intval($val)));
|
||||
foreach ($newsort as $key=>$val){
|
||||
$val=min(intval($val),999999);
|
||||
$mtask->strict(false)->where('id',intval($key))->update(array('sort'=>$val));
|
||||
}
|
||||
}
|
||||
$this->success(lang('op_success'),'Task/list?show='.input('show'));
|
||||
|
@ -440,114 +515,58 @@ class Task extends BaseController {
|
|||
/*执行任务采集*/
|
||||
public function collectAction(){
|
||||
$taskId=input('id/d',0);
|
||||
|
||||
$this->_backstage_cli_collect('task --task_id '.$taskId);
|
||||
if(input('?backstage')){
|
||||
|
||||
if(!IS_CLI){
|
||||
ignore_user_abort(true);
|
||||
|
||||
if($GLOBALS['_sc']['c']['caiji']['server']=='cli'){
|
||||
|
||||
cli_command_exec('collect task --task_id '.$taskId);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
ignore_user_abort(true);
|
||||
define('CLOSE_ECHO_MSG',true);
|
||||
$this->_backstage_task($taskId);
|
||||
}else{
|
||||
ignore_user_abort(false);
|
||||
|
||||
model('Task')->backstage_task($taskId);
|
||||
}
|
||||
|
||||
$this->_collect($taskId);
|
||||
|
||||
$this->_echo_msg_end();
|
||||
}
|
||||
/*批量执行任务采集*/
|
||||
public function collectBatchAction(){
|
||||
$taskIds=input('ids');
|
||||
if(empty($taskIds)){
|
||||
$this->echo_msg('没有选中任务');
|
||||
exit();
|
||||
$this->echo_msg_exit('没有选中任务');
|
||||
}
|
||||
$taskIds=explode(',', $taskIds);
|
||||
$taskIds=array_map('intval', $taskIds);
|
||||
|
||||
if(input('?backstage')){
|
||||
|
||||
if(!IS_CLI){
|
||||
ignore_user_abort(true);
|
||||
|
||||
if($GLOBALS['_sc']['c']['caiji']['server']=='cli'){
|
||||
|
||||
cli_command_exec('collect batch --task_ids '.implode(',',$taskIds));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
ignore_user_abort(true);
|
||||
define('CLOSE_ECHO_MSG',true);
|
||||
}else{
|
||||
ignore_user_abort(false);
|
||||
}
|
||||
$this->_backstage_cli_collect('batch --task_ids '.implode(',',$taskIds));
|
||||
|
||||
if($GLOBALS['_sc']['c']['caiji']['timeout']>0){
|
||||
set_time_limit(60*$GLOBALS['_sc']['c']['caiji']['timeout']);
|
||||
if(g_sc_c('caiji','timeout')>0){
|
||||
set_time_limit(60*g_sc_c('caiji','timeout'));
|
||||
}else{
|
||||
set_time_limit(0);
|
||||
}
|
||||
|
||||
$taskList=model('Task')->where('id','in',$taskIds)->column('*','id');
|
||||
$taskList=model('Task')->where('id','in',$taskIds)->column('name','id');
|
||||
if(empty($taskList)){
|
||||
$this->echo_msg('没有任务');
|
||||
exit();
|
||||
$this->echo_msg_exit('没有任务');
|
||||
}
|
||||
|
||||
$sortTasks=array();
|
||||
$sortIds=array();
|
||||
foreach ($taskIds as $v){
|
||||
$sortTasks[$v]=$taskList[$v];
|
||||
if(isset($taskList[$v])){
|
||||
$sortIds[$v]=$v;
|
||||
}
|
||||
}
|
||||
|
||||
$taskList=$sortTasks;
|
||||
unset($sortTasks);
|
||||
|
||||
$this->_collect_batch($taskList);
|
||||
$this->_collect_batch($sortIds);
|
||||
|
||||
$this->echo_msg('所有任务采集完毕!','green');
|
||||
}
|
||||
/*将任务标记为后台运行*/
|
||||
public function _backstage_task($taskId){
|
||||
$GLOBALS['_sc']['backstage_task_runtime']=time();
|
||||
|
||||
if(model('Task')->where('id',$taskId)->count()>0){
|
||||
|
||||
$mcache=CacheModel::getInstance('backstage_task');
|
||||
$mcache->db()->strict(false)->insert(array(
|
||||
'cname'=>$taskId,
|
||||
'dateline'=>$GLOBALS['_sc']['backstage_task_runtime'],
|
||||
'ctype'=>0,
|
||||
'data'=>''
|
||||
),true);
|
||||
|
||||
if(!isset($GLOBALS['_sc']['backstage_task_ids'])){
|
||||
$GLOBALS['_sc']['backstage_task_ids']=array();
|
||||
}
|
||||
$GLOBALS['_sc']['backstage_task_ids'][$taskId]=$taskId;
|
||||
|
||||
static $registered=false;
|
||||
if(!$registered){
|
||||
register_shutdown_function(function(){
|
||||
|
||||
if(!empty($GLOBALS['_sc']['backstage_task_ids'])&&is_array($GLOBALS['_sc']['backstage_task_ids'])){
|
||||
$mcache=\skycaiji\admin\model\CacheModel::getInstance('backstage_task');
|
||||
$mcache->db()->strict(false)->where('cname','in',$GLOBALS['_sc']['backstage_task_ids'])->update(array('ctype'=>1,'data'=>time()));
|
||||
}
|
||||
});
|
||||
$registered=true;
|
||||
}
|
||||
}
|
||||
$this->_echo_msg_end();
|
||||
}
|
||||
/*单个任务采集*/
|
||||
public function _collect($taskId){
|
||||
static $setted_timeout=null;
|
||||
if(!isset($setted_timeout)){
|
||||
if($GLOBALS['_sc']['c']['caiji']['timeout']>0){
|
||||
set_time_limit(60*$GLOBALS['_sc']['c']['caiji']['timeout']);
|
||||
if(g_sc_c('caiji','timeout')>0){
|
||||
set_time_limit(60*g_sc_c('caiji','timeout'));
|
||||
}else{
|
||||
set_time_limit(0);
|
||||
}
|
||||
|
@ -557,18 +576,15 @@ class Task extends BaseController {
|
|||
$mtask=model('Task');
|
||||
$taskData=$mtask->getById($taskId);
|
||||
if(empty($taskData)){
|
||||
$this->echo_msg(lang('task_error_empty_task'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('task_error_empty_task'));
|
||||
}
|
||||
$taskData=$taskData->toArray();
|
||||
if(empty($taskData['module'])){
|
||||
|
||||
$this->echo_msg(lang('task_error_null_module'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('task_error_null_module'));
|
||||
}
|
||||
if(!in_array($taskData['module'],config('allow_coll_modules'))){
|
||||
$this->echo_msg(lang('coll_error_invalid_module'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('coll_error_invalid_module'));
|
||||
}
|
||||
$taskData['config']=unserialize($taskData['config']);
|
||||
model('Task')->loadConfig($taskData);
|
||||
|
@ -576,19 +592,17 @@ class Task extends BaseController {
|
|||
$mcoll=model('Collector');
|
||||
$collData=$mcoll->where(array('task_id'=>$taskData['id'],'module'=>$taskData['module']))->find();
|
||||
if(empty($collData)){
|
||||
$this->echo_msg(lang('coll_error_empty_coll'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('coll_error_empty_coll'));
|
||||
}
|
||||
$collData=$collData->toArray();
|
||||
|
||||
$mrele=model('Release');
|
||||
$releData=$mrele->where(array('task_id'=>$taskData['id']))->find();
|
||||
if(empty($releData)){
|
||||
$this->echo_msg(lang('rele_error_empty_rele'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('rele_error_empty_rele'));
|
||||
}
|
||||
$releData=$releData->toArray();
|
||||
$mtask->strict(false)->where('id',$taskData['id'])->update(array('caijitime'=>NOW_TIME));
|
||||
$mtask->strict(false)->where('id',$taskData['id'])->update(array('caijitime'=>time()));
|
||||
$acoll=controller('admin/C'.strtolower($collData['module']),'event');
|
||||
$acoll->init($collData);
|
||||
$arele=controller('admin/R'.strtolower($releData['module']),'event');
|
||||
|
@ -597,22 +611,19 @@ class Task extends BaseController {
|
|||
|
||||
if('api'==$releData['module']){
|
||||
|
||||
$GLOBALS['_sc']['c']['caiji']['real_time']=0;
|
||||
|
||||
set_g_sc(['c','caiji','real_time'],0);
|
||||
|
||||
$cacheApiData=$arele->get_cache_fields();
|
||||
if($cacheApiData!==false){
|
||||
|
||||
|
||||
json($cacheApiData)->send();
|
||||
exit();
|
||||
$arele->json_exit($cacheApiData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$all_field_list=array();
|
||||
|
||||
$caijiNum=intval($GLOBALS['_sc']['c']['caiji']['num']);
|
||||
$caijiNum=intval(g_sc_c('caiji','num'));
|
||||
$taskNum=intval($taskData['config']['num']);
|
||||
|
||||
if($taskNum<=0||($caijiNum>0&&$taskNum>$caijiNum)){
|
||||
|
@ -655,26 +666,29 @@ class Task extends BaseController {
|
|||
$this->echo_msg('没有采集到数据','orange');
|
||||
}else{
|
||||
$this->echo_msg('采集到'.count((array)$all_field_list).'条数据','green');
|
||||
if(empty($GLOBALS['_sc']['c']['caiji']['real_time'])){
|
||||
if(is_empty(g_sc_c('caiji','real_time'))){
|
||||
|
||||
$addedNum=$arele->export($all_field_list);
|
||||
$addedNum=$arele->doExport($all_field_list);
|
||||
$this->echo_msg('成功发布'.$addedNum.'条数据','green');
|
||||
}
|
||||
}
|
||||
}
|
||||
/*批量任务采集*/
|
||||
public function _collect_batch($taskList=array()){
|
||||
public function _collect_batch($taskIds=array()){
|
||||
$mtask=model('Task');
|
||||
$mcoll=model('Collector');
|
||||
$mrele=model('Release');
|
||||
$caijiNum=intval($GLOBALS['_sc']['c']['caiji']['num']);
|
||||
$caijiNum=intval(g_sc_c('caiji','num'));
|
||||
$caijiLimit=false;
|
||||
if($caijiNum>0){
|
||||
$caijiLimit=true;
|
||||
$this->echo_msg('总共需采集'.$caijiNum.'条数据','black');
|
||||
}
|
||||
foreach ($taskList as $taskData){
|
||||
$mtask->strict(false)->where('id',$taskData['id'])->update(array('caijitime'=>time()));
|
||||
foreach ($taskIds as $taskId){
|
||||
$taskData=$mtask->getById($taskId);
|
||||
if(empty($taskData)){
|
||||
continue;
|
||||
}
|
||||
$collData=$mcoll->where(array('task_id'=>$taskData['id'],'module'=>$taskData['module']))->find();
|
||||
$releData=$mrele->where(array('task_id'=>$taskData['id']))->find();
|
||||
if(empty($collData)||empty($releData)){
|
||||
|
@ -686,18 +700,28 @@ class Task extends BaseController {
|
|||
$releData=$releData->toArray();
|
||||
if($releData['module']=='api'){
|
||||
|
||||
$this->echo_msg('任务:'.$taskData['name'].',发布方式为API接口,跳过执行','orange');
|
||||
$this->echo_msg('任务:'.$taskData['name'].' 发布方式为生成api,跳过执行','orange');
|
||||
continue;
|
||||
}
|
||||
if(input('?backstage')){
|
||||
|
||||
$this->_backstage_task($taskData['id']);
|
||||
}
|
||||
|
||||
$taskData['config']=unserialize($taskData['config']);
|
||||
|
||||
$mtask->loadConfig($taskData);
|
||||
|
||||
if(g_sc_c('caiji','interval')>0){
|
||||
$waitTime=(60*g_sc_c('caiji','interval'))-abs(time()-intval($taskData['caijitime']));
|
||||
if($waitTime>0){
|
||||
$this->echo_msg('任务:'.$taskData['name'].' 再次采集需等待'.\skycaiji\admin\model\Config::wait_time_tips($waitTime).' <a href="'.url('Admin/Task/edit?id='.$taskData['id']).'" target="_blank">设置运行间隔</a>','orange');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$mtask->strict(false)->where('id',$taskData['id'])->update(array('caijitime'=>time()));
|
||||
|
||||
if(input('?backstage')){
|
||||
|
||||
$mtask->backstage_task($taskData['id']);
|
||||
}
|
||||
|
||||
$acoll='\\skycaiji\\admin\\event\\C'.strtolower($collData['module']);
|
||||
$acoll=new $acoll();
|
||||
$acoll->init($collData);
|
||||
|
@ -744,9 +768,9 @@ class Task extends BaseController {
|
|||
}else{
|
||||
$this->echo_msg('任务:'.$taskData['name'].' 采集到'.count((array)$all_field_list).'条数据','green');
|
||||
|
||||
if(empty($GLOBALS['_sc']['c']['caiji']['real_time'])){
|
||||
if(is_empty(g_sc_c('caiji','real_time'))){
|
||||
|
||||
$addedNum=$arele->export($all_field_list);
|
||||
$addedNum=$arele->doExport($all_field_list);
|
||||
$this->echo_msg('成功发布'.$addedNum.'条数据','green');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,8 +74,9 @@ class Taskgroup extends BaseController {
|
|||
$parentTgList=$mtaskgroup->where(array('parent_id'=>0))->order('sort desc')->column('name','id');
|
||||
$this->assign('parentTgList',$parentTgList);
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('taskgroup_list');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list'))));
|
||||
set_g_sc('p_title',lang('taskgroup_list'));
|
||||
set_g_sc('p_name',lang('taskgroup_list'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')))));
|
||||
return $this->fetch();
|
||||
}
|
||||
/**
|
||||
|
@ -90,6 +91,7 @@ class Taskgroup extends BaseController {
|
|||
|
||||
$this->error($validate->getError());
|
||||
}
|
||||
$newData['sort']=min(intval($newData['sort']),999999);
|
||||
|
||||
$mtaskgroup->isUpdate(false)->allowField(true)->save($newData);
|
||||
$tgid=$mtaskgroup->id;
|
||||
|
@ -102,8 +104,9 @@ class Taskgroup extends BaseController {
|
|||
$parentTgList=$mtaskgroup->where(array('parent_id'=>0))->order('sort desc')->column('name','id');
|
||||
$this->assign('parentTgList',$parentTgList);
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('taskgroup_add');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),array('url'=>url('Taskgroup/add'),'title'=>lang('taskgroup_add'))));
|
||||
set_g_sc('p_title',lang('taskgroup_add'));
|
||||
set_g_sc('p_name',lang('taskgroup_add'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),array('url'=>url('Taskgroup/add'),'title'=>lang('taskgroup_add')))));
|
||||
|
||||
if(request()->isAjax()){
|
||||
return view('add_ajax');
|
||||
|
@ -130,6 +133,7 @@ class Taskgroup extends BaseController {
|
|||
|
||||
$this->error($validate->getError());
|
||||
}
|
||||
$newData['sort']=min(intval($newData['sort']),999999);
|
||||
if($tgData['name']!=$newData['name']){
|
||||
|
||||
if($mtaskgroup->where(array('name'=>$newData['name']))->count()>0){
|
||||
|
@ -160,8 +164,9 @@ class Taskgroup extends BaseController {
|
|||
$this->assign('parentTgList',$parentTgList);
|
||||
$this->assign('tgData',$tgData);
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('taskgroup_edit').':'.$tgData['name'];
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),array('url'=>url('Taskgroup/edit?id='.$tgData['id']),'title'=>$tgData['name'])));
|
||||
set_g_sc('p_title','分组:'.$tgData['name']);
|
||||
set_g_sc('p_name',lang('taskgroup_edit').':'.$tgData['name']);
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),array('url'=>url('Taskgroup/edit?id='.$tgData['id']),'title'=>$tgData['name']))));
|
||||
|
||||
if(request()->isAjax()){
|
||||
return view('add_ajax');
|
||||
|
@ -230,7 +235,7 @@ class Taskgroup extends BaseController {
|
|||
}
|
||||
}elseif($op=='deleteall'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$ids=input('ids/a',array());
|
||||
if(is_array($ids)&&count($ids)>0){
|
||||
$list=$mtaskgroup->where(array('id'=>array('in',$ids)))->column('*');
|
||||
$deleteIds=array();
|
||||
|
@ -251,14 +256,15 @@ class Taskgroup extends BaseController {
|
|||
$this->success(lang($hasSub?'tg_deleteall_has_sub':'op_success'));
|
||||
}elseif($op=='saveall'){
|
||||
|
||||
$ids=input('ids/a');
|
||||
$newsort=input('newsort/a');
|
||||
$ids=input('ids/a',array());
|
||||
$newsort=input('newsort/a',array());
|
||||
if(is_array($ids)&&count($ids)>0){
|
||||
$ids=array_map('intval', $ids);
|
||||
|
||||
$updateSql=' UPDATE '.$mtaskgroup->getQuery()->getTable().' SET `sort` = CASE `id` ';
|
||||
foreach ($ids as $tgid){
|
||||
$updateSql.= sprintf(" WHEN %d THEN '%s' ", $tgid, intval($newsort[$tgid]));
|
||||
$newsort[$tgid]=min(intval($newsort[$tgid]),999999);
|
||||
$updateSql.= sprintf(" WHEN %d THEN '%s' ", $tgid, $newsort[$tgid]);
|
||||
}
|
||||
$updateSql.='END WHERE `id` IN ('. implode(',',$ids).')';
|
||||
try{
|
||||
|
|
|
@ -14,12 +14,15 @@ use skycaiji\admin\model\DbCommon;
|
|||
class Tool extends BaseController {
|
||||
/*文件管理*/
|
||||
public function fileManagerAction(){
|
||||
$GLOBALS['_sc']['p_name']='文件管理';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/fileManager'),'title'=>'文件管理')));
|
||||
set_g_sc('p_title','文件管理');
|
||||
set_g_sc('p_name','文件管理');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Tool/fileManager'),'title'=>'文件管理'))));
|
||||
return $this->fetch('fileManager');
|
||||
}
|
||||
/*elfinder文件管理器*/
|
||||
public function elfinderAction(){
|
||||
$this->check_usertoken();
|
||||
|
||||
$op=input('op');
|
||||
if(empty($op)){
|
||||
|
||||
|
@ -44,14 +47,21 @@ class Tool extends BaseController {
|
|||
'uploadDeny' => array('all'),
|
||||
'uploadAllow' => array('image/x-ms-bmp', 'image/gif', 'image/jpeg', 'image/png', 'image/x-icon', 'text/plain'),
|
||||
'uploadOrder' => array('deny', 'allow'),
|
||||
'attributes' => array (
|
||||
'attributes' => array (
|
||||
array (
|
||||
'pattern' => '/\.php$/i',
|
||||
'read' => false,
|
||||
'write' => false,
|
||||
'hidden' => true,
|
||||
'locked' => false
|
||||
)
|
||||
'pattern' => '/\.(php|html|lock)$/i',
|
||||
'read' => false,
|
||||
'write' => false,
|
||||
'hidden' => true,
|
||||
'locked' => false
|
||||
),
|
||||
array (
|
||||
'pattern' => '/^\/{0,1}$/i',
|
||||
'read' => true,
|
||||
'write' => false,
|
||||
'hidden' => false,
|
||||
'locked' => false
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -86,21 +96,36 @@ class Tool extends BaseController {
|
|||
}
|
||||
}
|
||||
}
|
||||
$GLOBALS['_sc']['p_name']='错误日志';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/logs'),'title'=>'错误日志')));
|
||||
set_g_sc('p_title','错误日志');
|
||||
set_g_sc('p_name','错误日志');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Tool/logs'),'title'=>'错误日志'))));
|
||||
$this->assign('logList',$logList);
|
||||
return $this->fetch();
|
||||
}
|
||||
/*读取日志*/
|
||||
public function logAction(){
|
||||
config('dispatch_error_tmpl','common:error');
|
||||
config('dispatch_success_tmpl','common:success');
|
||||
|
||||
$file=realpath(input('file'));
|
||||
$logPath=realpath(config('root_path').'/runtime/log');
|
||||
if(stripos($file,$logPath)===false){
|
||||
$this->error('不是日志文件');
|
||||
$this->error('不是日志文件','');
|
||||
}
|
||||
$log=file_get_contents($file);
|
||||
exit('<pre>'.$log.'</pre>');
|
||||
|
||||
if(request()->isPost()){
|
||||
if(input('upload')){
|
||||
|
||||
curl_skycaiji('/client/upload/log',null,array(),array('log'=>$log,'v'=>SKYCAIJI_VERSION));
|
||||
$this->success('上报成功,感谢支持!','');
|
||||
}
|
||||
}else{
|
||||
|
||||
return $this->display('<pre>'.$log.'</pre>');
|
||||
}
|
||||
}
|
||||
|
||||
/*文件校验*/
|
||||
public function checkfileAction(){
|
||||
set_time_limit(0);
|
||||
|
@ -156,8 +181,9 @@ class Tool extends BaseController {
|
|||
$this->error('',null,array('files'=>$error_files));
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='校验文件';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/checkfile'),'title'=>'校验文件')));
|
||||
set_g_sc('p_title','校验文件');
|
||||
set_g_sc('p_name','校验文件');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Tool/checkfile'),'title'=>'校验文件'))));
|
||||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +233,7 @@ class Tool extends BaseController {
|
|||
$this->error('没有获取到表');
|
||||
}
|
||||
|
||||
if(!version_compare($check_db['version'],$GLOBALS['_sc']['c']['version'],'=')){
|
||||
if(!version_compare($check_db['version'],g_sc_c('version'),'=')){
|
||||
|
||||
$this->error('校验文件版本与数据库版本不一致');
|
||||
}
|
||||
|
@ -417,30 +443,38 @@ class Tool extends BaseController {
|
|||
}
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='校验数据库';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/checkdb'),'title'=>'校验数据库')));
|
||||
set_g_sc('p_title','校验数据库');
|
||||
set_g_sc('p_name','校验数据库');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Tool/checkdb'),'title'=>'校验数据库'))));
|
||||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
public function json_treeAction(){
|
||||
if(request()->isPost()){
|
||||
$url=input('url','','trim');
|
||||
$html=input('html','','trim');
|
||||
if(request()->isPost()){
|
||||
$data=input('data','','trim');
|
||||
$json='';
|
||||
$eCpattern=controller('admin/Cpattern','event');
|
||||
if(!empty($url)){
|
||||
if(preg_match('/^\w+\:\/\//', $data)){
|
||||
|
||||
$html=get_html($url);
|
||||
$data=get_html($data);
|
||||
}
|
||||
if(!empty($html)){
|
||||
$json=convert_html2json($html,true);
|
||||
if(!empty($data)){
|
||||
$json=\util\Funcs::convert_html2json($data,true);
|
||||
}
|
||||
|
||||
$this->success('','',array('json'=>$json));
|
||||
}else{
|
||||
$GLOBALS['_sc']['p_name']='JSON解析';
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/json_tree'),'title'=>'JSON解析')));
|
||||
return $this->fetch('json_tree');
|
||||
return $this->_json_tree_view();
|
||||
}
|
||||
}
|
||||
public function json_tree_dataAction(){
|
||||
$data=input('data','','trim');
|
||||
$this->assign('data',$data);
|
||||
return $this->_json_tree_view();
|
||||
}
|
||||
private function _json_tree_view(){
|
||||
set_g_sc('p_title','JSON解析');
|
||||
set_g_sc('p_name','JSON解析');
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('Tool/json_tree'),'title'=>'JSON解析'))));
|
||||
return $this->fetch('json_tree');
|
||||
}
|
||||
}
|
|
@ -17,30 +17,9 @@ class Upgrade extends BaseController{
|
|||
public function __construct(){
|
||||
parent::__construct();
|
||||
set_time_limit(3600);
|
||||
$this->oldFilePath=config('root_path').'/data/program/backup/skycaiji'.$GLOBALS['_sc']['c']['version'];
|
||||
$this->newFilePath=config('root_path').'/data/program/upgrade/skycaiji'.$GLOBALS['_sc']['c']['version'];
|
||||
$this->oldFilePath=config('root_path').'/data/program/backup/skycaiji'.g_sc_c('version');
|
||||
$this->newFilePath=config('root_path').'/data/program/upgrade/skycaiji'.g_sc_c('version');
|
||||
}
|
||||
/*检测更新*/
|
||||
public function newVersionAction(){
|
||||
$version=get_html('https://www.skycaiji.com/upgrade/program/version?v='.SKYCAIJI_VERSION,null,null,'utf-8');
|
||||
$version=json_decode($version,true);
|
||||
$version=is_array($version)?$version:array();
|
||||
$new_version=trim($version['new_version']);
|
||||
$cur_version=$GLOBALS['_sc']['c']['version'];
|
||||
|
||||
|
||||
if(version_compare($new_version,$cur_version,'>')){
|
||||
|
||||
$version['is_new_version']=true;
|
||||
}
|
||||
|
||||
$cacheIx=cache('backstage_admin_index');
|
||||
if(empty($cacheIx)||$cacheIx['ver']!=$version['admin_index_ver']){
|
||||
$version['is_new_admin_index']=true;
|
||||
}
|
||||
|
||||
$this->success('',null,$version);
|
||||
}
|
||||
/*
|
||||
* 下载的文件完整性检测
|
||||
* 注意:执行该方法时,旧代码已经编译了,替换文件后还是执行的旧文件代码
|
||||
|
@ -96,12 +75,11 @@ class Upgrade extends BaseController{
|
|||
$this->success();
|
||||
}
|
||||
}
|
||||
$fileUrl='https://www.skycaiji.com/upgrade/program/getFile?filename='.rawurlencode(base64_encode($fileName));
|
||||
|
||||
$curl=\util\Curl::get($fileUrl,null,array('timeout'=>100));
|
||||
if($curl->isOk){
|
||||
$curlInfo=curl_skycaiji('/client/upgrade/file?filename='.rawurlencode(base64_encode($fileName)),null,array('timeout'=>100),null,true);
|
||||
if($curlInfo['ok']){
|
||||
|
||||
$newFile=$curl->body;
|
||||
$newFile=$curlInfo['html'];
|
||||
$oldFile=file_get_contents(config('root_path').$fileName);
|
||||
if(!empty($oldFile)){
|
||||
|
||||
|
@ -142,7 +120,7 @@ class Upgrade extends BaseController{
|
|||
unset($md5Files);
|
||||
|
||||
|
||||
$newFileList=get_html('https://www.skycaiji.com/upgrade/program/files',null,array('timeout'=>100),'utf-8');
|
||||
$newFileList=curl_skycaiji('/client/upgrade/files',null,array('timeout'=>100));
|
||||
$newFileList=json_decode($newFileList,true);
|
||||
|
||||
$downFileList=array();
|
||||
|
|
|
@ -24,8 +24,9 @@ class User extends BaseController {
|
|||
$this->assign('pagenav',$pagenav);
|
||||
$userList=$userList->all();
|
||||
|
||||
$GLOBALS['_sc']['p_name']=lang('user_list');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list'))));
|
||||
set_g_sc('p_title',lang('user_list'));
|
||||
set_g_sc('p_name',lang('user_list'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')))));
|
||||
|
||||
$groupList=model('Usergroup')->column('*','id');
|
||||
$this->assign('userList',$userList);
|
||||
|
@ -37,11 +38,7 @@ class User extends BaseController {
|
|||
$muser=model('User');
|
||||
$musergroup=model('Usergroup');
|
||||
if(request()->isPost()){
|
||||
if(!check_usertoken()){
|
||||
$this->error(lang('usertoken_error'),'Admin/User/add');
|
||||
}
|
||||
|
||||
if($GLOBALS['_sc']['c']['site']['verifycode']){
|
||||
if(g_sc_c('site','verifycode')){
|
||||
|
||||
$verifycode=trim(input('verifycode'));
|
||||
$check=check_verify($verifycode);
|
||||
|
@ -65,9 +62,9 @@ class User extends BaseController {
|
|||
$newData['password']=\skycaiji\admin\model\User::pwd_encrypt($newData['password'],$newData['salt']);
|
||||
$newGroup=$musergroup->getById($newData['groupid']);
|
||||
if($musergroup->user_level_limit($newGroup['level'])){
|
||||
$this->error('您不能添加“'.$GLOBALS['_sc']['user']['group']['name'].'”用户组');
|
||||
$this->error('您不能添加“'.g_sc('user','group','name').'”用户组');
|
||||
}
|
||||
$newData['regtime']=NOW_TIME;
|
||||
$newData['regtime']=time();
|
||||
$muser->isUpdate(false)->allowField(true)->save($newData);
|
||||
if($muser->uid>0){
|
||||
$this->success(lang('op_success'),'User/list');
|
||||
|
@ -75,9 +72,10 @@ class User extends BaseController {
|
|||
$this->error(lang('op_failed'));
|
||||
}
|
||||
}else{
|
||||
$subGroupList=$musergroup->get_sub_level($GLOBALS['_sc']['user']['groupid']);
|
||||
$GLOBALS['_sc']['p_name']=lang('user_add');
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),array('url'=>url('User/add'),'title'=>lang('user_add'))));
|
||||
$subGroupList=$musergroup->get_sub_level(g_sc('user','groupid'));
|
||||
set_g_sc('p_title',lang('user_add'));
|
||||
set_g_sc('p_name',lang('user_add'));
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),array('url'=>url('User/add'),'title'=>lang('user_add')))));
|
||||
$this->assign('subGroupList',$subGroupList);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
@ -95,16 +93,13 @@ class User extends BaseController {
|
|||
}
|
||||
$userData['group']=$musergroup->getById($userData['groupid']);
|
||||
|
||||
$isOwner=($GLOBALS['_sc']['user']['uid']==$userData['uid'])?true:false;
|
||||
$isOwner=(g_sc('user','uid')==$userData['uid'])?true:false;
|
||||
if(!$isOwner&&$musergroup->user_level_limit($userData['group']['level'])){
|
||||
|
||||
$this->error('您不能编辑“'.$userData['group']['name'].'”组的用户');
|
||||
}
|
||||
if(request()->isPost()){
|
||||
if(!check_usertoken()){
|
||||
$this->error(lang('usertoken_error'),'Admin/User/edit?uid='.$userData['uid']);
|
||||
}
|
||||
if($GLOBALS['_sc']['c']['site']['verifycode']){
|
||||
if(g_sc_c('site','verifycode')){
|
||||
|
||||
$verifycode=trim(input('verifycode'));
|
||||
$check=check_verify($verifycode);
|
||||
|
@ -135,7 +130,7 @@ class User extends BaseController {
|
|||
}
|
||||
$newGroup=$musergroup->getById($newData['groupid']);
|
||||
if($musergroup->user_level_limit($newGroup['level'])){
|
||||
$this->error('您不能改为“'.$GLOBALS['_sc']['user']['group']['name'].'”用户组');
|
||||
$this->error('您不能改为“'.g_sc('user','group','name').'”用户组');
|
||||
}
|
||||
if($isOwner||empty($newData['groupid'])){
|
||||
|
||||
|
@ -143,15 +138,22 @@ class User extends BaseController {
|
|||
}
|
||||
|
||||
$muser->strict(false)->where(array('uid'=>$uid))->update($newData);
|
||||
$this->success(lang('op_success'),'User/list');
|
||||
|
||||
if($isOwner){
|
||||
|
||||
$userData=$muser->getByUid($uid);
|
||||
$muser->setLoginSession($userData);
|
||||
}
|
||||
|
||||
$this->success(lang('op_success'),'User/list');
|
||||
}else{
|
||||
$this->assign('userData',$userData);
|
||||
$subGroupList=$musergroup->get_sub_level($GLOBALS['_sc']['user']['groupid']);
|
||||
$subGroupList=$musergroup->get_sub_level(g_sc('user','groupid'));
|
||||
$this->assign('subGroupList',$subGroupList);
|
||||
$this->assign('isOwner',$isOwner);
|
||||
$GLOBALS['_sc']['p_name']=lang('user_edit').':'.$userData['username'];
|
||||
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),array('url'=>url('User/edit?uid='.$userData['uid']),'title'=>$userData['username'])));
|
||||
set_g_sc('p_title','用户:'.$userData['username']);
|
||||
set_g_sc('p_name',lang('user_edit').':'.$userData['username']);
|
||||
set_g_sc('p_nav',breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),array('url'=>url('User/edit?uid='.$userData['uid']),'title'=>$userData['username']))));
|
||||
return $this->fetch();
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +168,7 @@ class User extends BaseController {
|
|||
if(empty($userData)){
|
||||
$this->error(lang('user_error_empty_user'));
|
||||
}
|
||||
if($userData['uid']==$GLOBALS['_sc']['user']['uid']){
|
||||
if($userData['uid']==g_sc('user','uid')){
|
||||
|
||||
$this->error('不能删除自己');
|
||||
}
|
||||
|
|
|
@ -24,20 +24,20 @@ abstract class Collector extends \skycaiji\admin\controller\BaseController {
|
|||
}
|
||||
}
|
||||
/*采集器的输出内容需要重写,只有正在采集时才输出内容*/
|
||||
public function echo_msg($str,$color='red',$echo=true,$end_str=''){
|
||||
if(is_collecting()){
|
||||
public function echo_msg($str,$color='red',$echo=true,$end_str='',$div_style=''){
|
||||
if(is_collecting()){
|
||||
static $pause_session=null;
|
||||
if(!isset($pause_session)){
|
||||
|
||||
if(session_status()!==2){
|
||||
if(session_status()!==PHP_SESSION_ACTIVE){
|
||||
session_start();
|
||||
}
|
||||
\think\Session::pause();
|
||||
session_write_close();
|
||||
|
||||
$pause_session=true;
|
||||
}
|
||||
|
||||
parent::echo_msg($str,$color,$echo,$end_str);
|
||||
parent::echo_msg($str,$color,$echo,$end_str,$div_style);
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -67,99 +67,20 @@ abstract class Collector extends \skycaiji\admin\controller\BaseController {
|
|||
public function set_html_interval(){
|
||||
if(is_collecting()){
|
||||
|
||||
if($GLOBALS['_sc']['c']['caiji']['html_interval']>0){
|
||||
|
||||
sleep($GLOBALS['_sc']['c']['caiji']['html_interval']);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
$millisecond=g_sc_c('caiji','interval_html');
|
||||
if(empty($millisecond)&&g_sc_c('caiji','html_interval')>0){
|
||||
|
||||
$millisecond=g_sc_c('caiji','html_interval')*1000;
|
||||
}
|
||||
if($millisecond>0){
|
||||
usleep($millisecond*1000);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*获取内容*/
|
||||
public function get_content($html){
|
||||
try {
|
||||
$cread=new \util\Readability($html,'utf-8');
|
||||
$data=$cread->getContent();
|
||||
}catch (\Exception $ex){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return trim($data['content']);
|
||||
}
|
||||
/*获取标题*/
|
||||
public function get_title($html){
|
||||
|
||||
if(preg_match_all('/<h1\b[^<>]*?>(?P<content>[\s\S]+?)<\/h1>/i', $html,$title)){
|
||||
if (count($title['content'])>1){
|
||||
|
||||
$title=null;
|
||||
}else{
|
||||
$title=strip_tags(reset($title['content']));
|
||||
if (preg_match('/^((\ \;)|\s)*$/i', $title)){
|
||||
$title=null;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$title=null;
|
||||
}
|
||||
if (empty($title)){
|
||||
$pattern = array (
|
||||
'<(h[12])\b[^<>]*?(id|class)=[\'\"]{0,1}[^\'\"<>]*(title|article)[^<>]*>(?P<content>[\s\S]+?)<\/\1>',
|
||||
'<title>(?P<content>[\s\S]+?)([\-\_\|][\s\S]+?)*<\/title>'
|
||||
);
|
||||
$title=$this->return_preg_match($pattern, $html);
|
||||
}
|
||||
return trim(strip_tags($title));
|
||||
}
|
||||
public function get_keywords($html){
|
||||
$patterns=array(
|
||||
'<meta[^<>]*?name=[\'\"]keywords[\'\"][^<>]*?content=[\'\"](?P<content>[\s\S]*?)[\'\"]',
|
||||
'<meta[^<>]*?content=[\'\"](?P<content>[\s\S]*?)[\'\"][^<>]*?name=[\'\"]keywords[\'\"]'
|
||||
);
|
||||
$data=$this->return_preg_match($patterns, $html);
|
||||
return trim(strip_tags($data));
|
||||
}
|
||||
public function get_description($html){
|
||||
$patterns=array(
|
||||
'<meta[^<>]*?name=[\'\"]description[\'\"][^<>]*?content=[\'\"](?P<content>[\s\S]*?)[\'\"]',
|
||||
'<meta[^<>]*?content=[\'\"](?P<content>[\s\S]*?)[\'\"][^<>]*?name=[\'\"]description[\'\"]'
|
||||
);
|
||||
$data=$this->return_preg_match($patterns, $html);
|
||||
return trim(strip_tags($data));
|
||||
}
|
||||
/**
|
||||
* 匹配规则的值
|
||||
* @param 规则 $pattern
|
||||
* @param 来源内容 $content
|
||||
* @param 返回值得键名 $reg_key
|
||||
*/
|
||||
public function return_preg_match($pattern,$content,$reg_key='content'){
|
||||
if(is_array($pattern)){
|
||||
|
||||
foreach ($pattern as $patt){
|
||||
if(preg_match('/'.$patt.'/i', $content,$cont)){
|
||||
$cont=$cont[$reg_key];
|
||||
break;
|
||||
}else{
|
||||
$cont=false;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(preg_match('/'.$pattern.'/i', $content,$cont)){
|
||||
$cont=$cont[$reg_key];
|
||||
}else{
|
||||
$cont=false;
|
||||
}
|
||||
}
|
||||
return empty($cont)?'':$cont;
|
||||
}
|
||||
/**
|
||||
* 匹配根目录
|
||||
* @param string $url 完整的网址
|
||||
|
@ -217,8 +138,8 @@ abstract class Collector extends \skycaiji\admin\controller\BaseController {
|
|||
public function create_complete_url($url,$base_url,$domain_url){
|
||||
static $base_domain=array();
|
||||
|
||||
if(preg_match('/^\w+\:\/\//', $url)){
|
||||
|
||||
if(preg_match('/^\w+\:/', $url)){
|
||||
|
||||
return $url;
|
||||
}elseif(strpos($url,'//')===0){
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@ class Rapi extends Release{
|
|||
* @param unknown $config
|
||||
*/
|
||||
public function setConfig($config){
|
||||
$api=input('api/a');
|
||||
$api=input('api/a',array());
|
||||
$api['url']=trim($api['url'],'\/\\');
|
||||
$api['cache_time']=intval($api['cache_time']);
|
||||
$api['hide_fields']=is_array($api['hide_fields'])?$api['hide_fields']:array();
|
||||
|
@ -45,13 +45,15 @@ class Rapi extends Release{
|
|||
$mcacheCont->db()->where('cname','in',$contUrls)->delete();
|
||||
}
|
||||
|
||||
|
||||
$this->hide_coll_fields($this->config['api']['hide_fields'],$collFieldsList);
|
||||
|
||||
foreach ($collFieldsList as $collFieldsKey=>$collFields){
|
||||
$this->hide_coll_fields($this->config['api']['hide_fields'],$collFields);
|
||||
$collFieldsList[$collFieldsKey]=$collFields;
|
||||
}
|
||||
|
||||
$this->set_cache_fields($collFieldsList);
|
||||
|
||||
json($collFieldsList)->send();
|
||||
exit();
|
||||
$this->json_exit($collFieldsList);
|
||||
}
|
||||
|
||||
/*设置缓存数据*/
|
||||
|
@ -81,5 +83,19 @@ class Rapi extends Release{
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*输出json数据*/
|
||||
public function json_exit($collFieldsList){
|
||||
if(defined('API_TASK_RESPONSE_JSON')){
|
||||
json($collFieldsList)->send();
|
||||
}else{
|
||||
$html='<form id="win_form_json" method="post" target="_blank" action="'.url('Tool/json_tree_data').'">'.html_usertoken()
|
||||
.'<p>生成API返回的数据 <a href="javascript:;" onclick="document.getElementById(\'win_form_json\').submit();">解析</a></p>'
|
||||
.'<textarea name="data" style="width:100%;margin:5px 0;" rows="20">'.htmlspecialchars(json_encode($collFieldsList)).'</textarea></form>';
|
||||
$this->echo_msg($html,'black');
|
||||
$this->_echo_msg_end();
|
||||
}
|
||||
exit();
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -19,8 +19,8 @@ class Rcms extends Release{
|
|||
* @param unknown $config
|
||||
*/
|
||||
public function setConfig($config){
|
||||
$config['cms']=input('cms/a');
|
||||
$config['cms_app']=input('cms_app/a');
|
||||
$config['cms']=input('cms/a',array());
|
||||
$config['cms_app']=input('cms_app/a',array());
|
||||
if(empty($config['cms']['path'])){
|
||||
$this->error('cms路径不能为空');
|
||||
}
|
||||
|
@ -54,11 +54,9 @@ class Rcms extends Release{
|
|||
|
||||
if(model('ReleaseApp')->oldFileExists($this->config['cms']['app'],'Cms')){
|
||||
|
||||
$this->echo_msg(lang('release_upgrade'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('release_upgrade'));
|
||||
}else{
|
||||
$this->echo_msg('没有cms发布插件:'.$this->config['cms']['app']);
|
||||
exit();
|
||||
$this->echo_msg_exit('没有cms发布插件:'.$this->config['cms']['app']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class Rdb extends Release{
|
|||
* @param unknown $config
|
||||
*/
|
||||
public function setConfig($config){
|
||||
$db=input('db/a','','trim');
|
||||
$db=input('db/a',array(),'trim');
|
||||
foreach ($db as $k=>$v){
|
||||
if(empty($v)&&'pwd'!=$k){
|
||||
|
||||
|
@ -26,7 +26,7 @@ class Rdb extends Release{
|
|||
}
|
||||
}
|
||||
$config['db']=$db;
|
||||
$config['db_table']=input('db_table/a','','trim');
|
||||
$config['db_table']=input('db_table/a',array(),'trim');
|
||||
|
||||
if(is_array($config['db_table'])&&is_array($config['db_table']['field'])){
|
||||
foreach($config['db_table']['field'] as $tbName=>$tbFields){
|
||||
|
@ -48,6 +48,8 @@ class Rdb extends Release{
|
|||
public function export($collFieldsList,$options=null){
|
||||
|
||||
$db_config=$this->get_db_config($this->config['db']);
|
||||
$db_config['fields_strict']=false;
|
||||
|
||||
$db_key=md5(serialize($db_config));
|
||||
if(empty($this->db_conn_list[$db_key])){
|
||||
|
||||
|
@ -180,8 +182,8 @@ class Rdb extends Release{
|
|||
|
||||
$mdb->commit();
|
||||
reset($autoidList);
|
||||
list($firstTable,$firstId) = each($autoidList);
|
||||
$firstId=intval($firstId);
|
||||
$firstTable=key($autoidList);
|
||||
$firstId=intval($autoidList[$firstTable]);
|
||||
if($firstId>0){
|
||||
$addedNum++;
|
||||
$returnData['id']=$firstId;
|
||||
|
|
|
@ -18,7 +18,7 @@ class Rdiy extends Release{
|
|||
* @param unknown $config
|
||||
*/
|
||||
public function setConfig($config){
|
||||
$diy=input('diy/a','','trim');
|
||||
$diy=input('diy/a',array(),'trim');
|
||||
if(!in_array($diy['type'],array('app','code'))){
|
||||
$this->error('类型错误');
|
||||
}
|
||||
|
@ -65,17 +65,14 @@ class Rdiy extends Release{
|
|||
$releDiy=$this->rele_diy_list[$releDiy];
|
||||
}elseif(model('ReleaseApp')->oldFileExists($appName,'diy')){
|
||||
|
||||
$this->echo_msg(lang('release_upgrade'));
|
||||
exit();
|
||||
$this->echo_msg_exit(lang('release_upgrade'));
|
||||
}
|
||||
}
|
||||
if(empty($releDiy)){
|
||||
$this->echo_msg('没有自定义插件:'.$appName);
|
||||
exit();
|
||||
$this->echo_msg_exit('没有自定义插件:'.$appName);
|
||||
}
|
||||
}catch (\Exception $ex){
|
||||
$this->echo_msg($ex->getMessage());
|
||||
exit();
|
||||
$this->echo_msg_exit($ex->getMessage());
|
||||
}
|
||||
|
||||
$addedNum=0;
|
||||
|
|
|
@ -27,6 +27,16 @@ abstract class Release extends ReleaseBase{
|
|||
$this->error(lang('task_error_empty_task'));
|
||||
}
|
||||
}
|
||||
public function doExport($collFieldsList,$options=null){
|
||||
$addedNum=0;
|
||||
try{
|
||||
$addedNum=$this->export($collFieldsList,$options);
|
||||
}catch (\Exception $ex){
|
||||
|
||||
$this->echo_msg($ex->getMessage());
|
||||
}
|
||||
return $addedNum;
|
||||
}
|
||||
/**
|
||||
* 优化设置页面post过来的config
|
||||
* @param unknown $config 页面配置
|
||||
|
|
|
@ -74,7 +74,7 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
return '';
|
||||
}
|
||||
$val=$collFieldVal['value'];
|
||||
if(!empty($GLOBALS['_sc']['c']['download_img']['download_img'])){
|
||||
if(!is_empty(g_sc_c('download_img','download_img'))){
|
||||
|
||||
if(!empty($collFieldVal['img'])){
|
||||
|
||||
|
@ -96,9 +96,14 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
$curI++;
|
||||
if($curI<$total){
|
||||
|
||||
if(!empty($GLOBALS['_sc']['c']['download_img']['img_interval'])){
|
||||
sleep($GLOBALS['_sc']['c']['download_img']['img_interval']);
|
||||
}
|
||||
$millisecond=g_sc_c('download_img','interval_img');
|
||||
if(empty($millisecond)&&g_sc_c('download_img','img_interval')>0){
|
||||
|
||||
$millisecond=g_sc_c('download_img','img_interval')*1000;
|
||||
}
|
||||
if($millisecond>0){
|
||||
usleep($millisecond*1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,11 +112,12 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
}
|
||||
/*下载图片*/
|
||||
public function download_img($url){
|
||||
static $retryCur=0;
|
||||
static $imgPaths=array();
|
||||
static $imgUrls=array();
|
||||
|
||||
$img_path=$GLOBALS['_sc']['c']['download_img']['img_path'];
|
||||
$img_url=$GLOBALS['_sc']['c']['download_img']['img_url'];
|
||||
$img_path=g_sc_c('download_img','img_path');
|
||||
$img_url=g_sc_c('download_img','img_url');
|
||||
|
||||
if(!isset($imgPaths[$img_path])){
|
||||
if(empty($img_path)){
|
||||
|
@ -138,32 +144,76 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
if(empty($url)){
|
||||
return '';
|
||||
}
|
||||
if(!preg_match('/^\w+\:\/\//',$url)){
|
||||
|
||||
$isDataImage=stripos($url, 'data:image/')===0?true:false;
|
||||
|
||||
if(!preg_match('/^\w+\:\/\//',$url)&&!$isDataImage){
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
if(!empty($GLOBALS['_sc']['c']['caiji']['robots'])){
|
||||
|
||||
if(!model('Collector')->abide_by_robots($url)){
|
||||
$this->echo_msg('robots拒绝访问的网址:'.$url);
|
||||
return $url;
|
||||
}
|
||||
if($isDataImage&&is_empty(g_sc_c('download_img','data_image'))){
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
if(!$isDataImage){
|
||||
|
||||
if(!is_empty(g_sc_c('caiji','robots'))){
|
||||
|
||||
if(!model('Collector')->abide_by_robots($url)){
|
||||
$this->echo_msg('robots拒绝访问的网址:'.$url);
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static $imgList=array();
|
||||
static $imgSuffixes=null;
|
||||
if(!isset($imgSuffixes)){
|
||||
$imgSuffixes=array('jpg','jpeg','gif','png','bmp');
|
||||
$moreSuffix=g_sc_c('download_img','more_suffix');
|
||||
if(!empty($moreSuffix)){
|
||||
$moreSuffix=explode(',', $moreSuffix);
|
||||
if(is_array($moreSuffix)){
|
||||
$imgSuffixes=array_merge($imgSuffixes,$moreSuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
$key=md5($url);
|
||||
if(!isset($imgList[$key])){
|
||||
|
||||
if(preg_match('/\.(jpg|jpeg|gif|png|bmp)\b/i',$url,$prop)){
|
||||
$prop=strtolower($prop[1]);
|
||||
}else{
|
||||
$prop='jpg';
|
||||
$prop='';
|
||||
$dataImageCode='';
|
||||
if($isDataImage){
|
||||
|
||||
if(preg_match('/^data\:image\/(.+?)\;base64\,(.*)$/i',$url,$prop)){
|
||||
$dataImageCode=base64_decode(trim($prop[2]));
|
||||
$prop=strtolower($prop[1]);
|
||||
}else{
|
||||
$prop='';
|
||||
}
|
||||
}else{
|
||||
|
||||
if(preg_match('/\.([a-zA-Z][\w\-]+)([\?\#]|$)/',$url,$prop)){
|
||||
$prop=strtolower($prop[1]);
|
||||
}else{
|
||||
$prop='';
|
||||
}
|
||||
}
|
||||
if(!in_array($prop, $imgSuffixes)){
|
||||
|
||||
$prop='';
|
||||
}
|
||||
if(empty($prop)){
|
||||
$prop='jpg';
|
||||
}
|
||||
|
||||
$filename='';
|
||||
$imgurl='';
|
||||
$isExists=false;
|
||||
$imgname=$GLOBALS['_sc']['c']['download_img']['img_name'];
|
||||
$imgname=g_sc_c('download_img','img_name');
|
||||
|
||||
if('url'==$imgname){
|
||||
|
||||
|
@ -172,6 +222,7 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
|
||||
$imgname=substr($key,0,2).'/'.substr($key,-2,2).'/'.$key.'.'.$prop;
|
||||
$filename=$img_path.$imgname;
|
||||
$filename=$this->_convert_img_charset($filename);
|
||||
$isExists=file_exists($filename);
|
||||
|
||||
if(!$isExists){
|
||||
|
@ -179,77 +230,167 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
|
||||
$imgname=substr($key,0,2).'/'.substr($key,2).'.'.$prop;
|
||||
$filename=$img_path.$imgname;
|
||||
$filename=$this->_convert_img_charset($filename);
|
||||
$isExists=file_exists($filename);
|
||||
}
|
||||
}elseif('custom'==$imgname){
|
||||
|
||||
$customPath=$GLOBALS['_sc']['c']['download_img']['name_custom_path'];
|
||||
if(isset($GLOBALS['_sc']['c']['download_img']['_name_custom_path'])){
|
||||
$customPath=$GLOBALS['_sc']['c']['download_img']['_name_custom_path'];
|
||||
$customPath=g_sc_c('download_img','name_custom_path');
|
||||
if(!is_null(g_sc_c('download_img','_name_custom_path'))){
|
||||
$customPath=g_sc_c('download_img','_name_custom_path');
|
||||
}
|
||||
$customName=$GLOBALS['_sc']['c']['download_img']['name_custom_name'];
|
||||
if(isset($GLOBALS['_sc']['c']['download_img']['_name_custom_name'])){
|
||||
$customName=$GLOBALS['_sc']['c']['download_img']['_name_custom_name'];
|
||||
$customName=g_sc_c('download_img','name_custom_name');
|
||||
if(!is_null(g_sc_c('download_img','_name_custom_name'))){
|
||||
$customName=g_sc_c('download_img','_name_custom_name');
|
||||
}
|
||||
$customPath=model('Config')->convert_img_name_path($customPath,$url);
|
||||
$customName=model('Config')->convert_img_name_name($customName,$url);
|
||||
$imgname=$customPath.'/'.$customName.'.'.$prop;
|
||||
$filename=$img_path.$imgname;
|
||||
$filename=$img_path.$imgname;
|
||||
$filename=$this->_convert_img_charset($filename);
|
||||
$isExists=file_exists($filename);
|
||||
}else{
|
||||
|
||||
$imgname=date('Y-m-d',NOW_TIME).'/'.$key.'.'.$prop;
|
||||
$imgname=date('Y-m-d',time()).'/'.$key.'.'.$prop;
|
||||
$filename=$img_path.$imgname;
|
||||
$filename=$this->_convert_img_charset($filename);
|
||||
$isExists=file_exists($filename);
|
||||
}
|
||||
$imgurl=$img_url.$imgname;
|
||||
|
||||
if(!$isExists){
|
||||
|
||||
$mproxy=model('Proxyip');
|
||||
try {
|
||||
$options=array();
|
||||
$headers=array();
|
||||
|
||||
if(!empty($GLOBALS['_sc']['task_request_headers'])&&!empty($GLOBALS['_sc']['task_request_headers']['request_headers']['download_img'])){
|
||||
|
||||
$headers=$GLOBALS['_sc']['task_request_headers']['headers'];
|
||||
if(!empty($headers['useragent'])){
|
||||
|
||||
$options['useragent']=$headers['useragent'];
|
||||
}
|
||||
unset($headers['useragent']);
|
||||
}
|
||||
|
||||
if(!empty($GLOBALS['_sc']['c']['download_img']['img_timeout'])){
|
||||
|
||||
$options['timeout']=$GLOBALS['_sc']['c']['download_img']['img_timeout'];
|
||||
}
|
||||
if(!empty($GLOBALS['_sc']['c']['proxy']['open'])){
|
||||
|
||||
$proxyIp=$mproxy->get_usable_ip();
|
||||
$proxyIp=$mproxy->to_proxy_ip($proxyIp);
|
||||
if(!empty($proxyIp)){
|
||||
|
||||
$options['proxy']=$proxyIp;
|
||||
}
|
||||
}
|
||||
if(!empty($GLOBALS['_sc']['c']['download_img']['img_max'])){
|
||||
|
||||
$options['max_bytes']=intval($GLOBALS['_sc']['c']['download_img']['img_max'])*1024*1024;
|
||||
}
|
||||
|
||||
$imgCode=get_html($url,$headers,$options,'utf-8');
|
||||
if(!empty($imgCode)){
|
||||
|
||||
if(write_dir_file($filename,$imgCode)){
|
||||
$imgList[$key]=$imgurl;
|
||||
}
|
||||
}
|
||||
|
||||
}catch (\Exception $ex){
|
||||
|
||||
}
|
||||
if($isDataImage){
|
||||
|
||||
if(!empty($dataImageCode)){
|
||||
if(write_dir_file($filename,$dataImageCode)){
|
||||
$imgList[$key]=$imgurl;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
$mproxy=model('Proxyip');
|
||||
$proxyDbIp=null;
|
||||
try {
|
||||
$options=array();
|
||||
$headers=array();
|
||||
|
||||
if(!is_empty(g_sc('task_img_headers'))){
|
||||
|
||||
$headers=g_sc('task_img_headers');
|
||||
}
|
||||
|
||||
if(!is_empty(g_sc_c('download_img','img_timeout'))){
|
||||
|
||||
$options['timeout']=g_sc_c('download_img','img_timeout');
|
||||
}
|
||||
if(!is_empty(g_sc_c('proxy','open'))){
|
||||
|
||||
$proxyDbIp=$mproxy->get_usable_ip();
|
||||
$proxyIp=$mproxy->to_proxy_ip($proxyDbIp);
|
||||
if(!empty($proxyIp)){
|
||||
|
||||
$options['proxy']=$proxyIp;
|
||||
}
|
||||
}
|
||||
if(!is_empty(g_sc_c('download_img','img_max'))){
|
||||
|
||||
$options['max_bytes']=intval(g_sc_c('download_img','img_max'))*1024*1024;
|
||||
}
|
||||
|
||||
$imgCodeInfo=get_html($url,$headers,$options,'utf-8',null,true);
|
||||
if(!empty($imgCodeInfo['ok'])){
|
||||
|
||||
$retryCur=0;
|
||||
if(!empty($imgCodeInfo['html'])){
|
||||
|
||||
if(preg_match('/\bcontent-type\s*\:\s*image\s*\/(\w+)/i', $imgCodeInfo['header'],$mImgProp)){
|
||||
|
||||
$mImgProp=strtolower($mImgProp[1]);
|
||||
if($prop!=$mImgProp){
|
||||
|
||||
if(in_array($mImgProp,$imgSuffixes)){
|
||||
|
||||
static $sameImgProp=array('jpg','jpeg');
|
||||
if(!in_array($prop,$sameImgProp)||!in_array($mImgProp,$sameImgProp)){
|
||||
|
||||
$imgname.='.'.$mImgProp;
|
||||
$imgurl.='.'.$mImgProp;
|
||||
$filename.='.'.$mImgProp;
|
||||
|
||||
if(file_exists($filename)){
|
||||
|
||||
$isExists=true;
|
||||
$imgList[$key]=$imgurl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!$isExists){
|
||||
if(write_dir_file($filename,$imgCodeInfo['html'])){
|
||||
$imgList[$key]=$imgurl;
|
||||
|
||||
$funcName=g_sc_c('download_img','img_func');
|
||||
if(!empty($funcName)){
|
||||
|
||||
$paramVals=array(
|
||||
'[图片:文件名]'=>$filename,
|
||||
'[图片:路径]'=>$img_path,
|
||||
'[图片:名称]'=>$imgname,
|
||||
'[图片:链接]'=>$imgurl,
|
||||
'[图片:网址]'=>$url
|
||||
);
|
||||
$return=model('FuncApp')->execute_func('downloadImg',$funcName,$filename,g_sc_c('download_img','img_func_param'),$paramVals);
|
||||
if($return['success']){
|
||||
|
||||
if($return['data']&&preg_match('/^\w+\:\/\//',$return['data'])){
|
||||
|
||||
$imgList[$key]=$return['data'];
|
||||
}
|
||||
}elseif($return['msg']){
|
||||
|
||||
$this->echo_msg($return['msg']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
if($retryCur<=0){
|
||||
$this->echo_msg('<div class="clear"><span class="left">图片下载失败:</span><a href="'.$url.'" target="_blank" class="lurl">'.$url.'</a></div>','red');
|
||||
}
|
||||
|
||||
|
||||
if(!empty($proxyDbIp)){
|
||||
$mproxy->set_ip_failed($proxyDbIp);
|
||||
}
|
||||
|
||||
$failedWait=intval(g_sc_c('download_img','wait'));
|
||||
if($failedWait>0){
|
||||
|
||||
sleep($failedWait);
|
||||
}
|
||||
|
||||
$retryMax=intval(g_sc_c('download_img','retry'));
|
||||
if($retryMax>0){
|
||||
|
||||
if($retryCur<$retryMax){
|
||||
|
||||
$retryCur++;
|
||||
$this->echo_msg(($retryCur>1?',':'重试:').'第'.$retryCur.'次','black',true,'','display:inline;');
|
||||
return $this->download_img($url);
|
||||
}else{
|
||||
$retryCur=0;
|
||||
$this->echo_msg('图片无效','red',true,'','display:inline;margin-left:10px;');
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (\Exception $ex){
|
||||
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
$imgList[$key]=$imgurl;
|
||||
|
@ -257,6 +398,27 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
}
|
||||
return empty($imgList[$key])?$url:$imgList[$key];
|
||||
}
|
||||
|
||||
private function _convert_img_charset($filename){
|
||||
static $charset=null;
|
||||
if(!isset($charset)){
|
||||
$charset=g_sc_c('download_img','charset');
|
||||
$charset=empty($charset)?'':strtolower($charset);
|
||||
if($charset=='custom'){
|
||||
|
||||
$charset=g_sc_c('download_img','charset_custom');
|
||||
$charset=empty($charset)?'':strtolower($charset);
|
||||
}
|
||||
if($charset=='utf-8'){
|
||||
|
||||
$charset='';
|
||||
}
|
||||
}
|
||||
if(!empty($charset)&&!empty($filename)){
|
||||
$filename=iconv('utf-8',$charset.'//IGNORE',$filename);
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
/*获取采集器字段*/
|
||||
public function get_coll_fields($taskId,$taskModule){
|
||||
static $fieldsList=array();
|
||||
|
@ -280,12 +442,11 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
}
|
||||
/*隐藏采集字段(删除字段)*/
|
||||
public function hide_coll_fields($hideFields,&$collFields){
|
||||
if(!empty($hideFields)&&!empty($collFields)&&is_array($hideFields)){
|
||||
foreach ($collFields as $k=>$v){
|
||||
foreach ($hideFields as $hideField){
|
||||
unset($collFields[$k]['fields'][$hideField]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($hideFields)&&is_array($hideFields)&&is_array($collFields)&&is_array($collFields['fields'])){
|
||||
foreach ($hideFields as $hideField){
|
||||
unset($collFields['fields'][$hideField]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,18 +460,26 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
}
|
||||
return $val;
|
||||
}
|
||||
/*任意编码转换成utf8*/
|
||||
public function auto_convert2utf8($arr){
|
||||
$arr=array_array_map('auto_convert2utf8',$arr);
|
||||
return $arr;
|
||||
/**
|
||||
* 任意编码转换成utf8
|
||||
* @param mixed $val 字符串或数组
|
||||
*/
|
||||
public function auto_convert2utf8($val){
|
||||
if(is_array($val)){
|
||||
$val=\util\Funcs::array_array_map('auto_convert2utf8',$val);
|
||||
}else{
|
||||
$val=auto_convert2utf8($val);
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
/*写入文件*/
|
||||
public function write_file($filename,$data){
|
||||
return write_dir_file($filename,$data);
|
||||
}
|
||||
|
||||
/*初始化下载图片*/
|
||||
public function init_download_img($taskData,$collFields){
|
||||
if(!empty($GLOBALS['_sc']['c']['download_img']['download_img'])&&$GLOBALS['_sc']['c']['download_img']['img_name']=='custom'){
|
||||
if(!is_empty(g_sc_c('download_img','download_img'))&&g_sc_c('download_img','img_name')=='custom'){
|
||||
|
||||
if(empty($taskData)){
|
||||
$taskData=array();
|
||||
|
@ -319,7 +488,7 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
$collFields=array();
|
||||
}
|
||||
|
||||
$name_custom_path=$GLOBALS['_sc']['c']['download_img']['name_custom_path'];
|
||||
$name_custom_path=g_sc_c('download_img','name_custom_path');
|
||||
$check=model('Config')->check_img_name_path($name_custom_path);
|
||||
if($check['success']){
|
||||
$name_custom_path=$this->_convert_img_params($name_custom_path, $taskData, $collFields);
|
||||
|
@ -327,10 +496,10 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
$name_custom_path='temp';
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['c']['download_img']['_name_custom_path']=$name_custom_path;
|
||||
set_g_sc(['c','download_img','_name_custom_path'],$name_custom_path);
|
||||
|
||||
|
||||
$name_custom_name=$GLOBALS['_sc']['c']['download_img']['name_custom_name'];
|
||||
$name_custom_name=g_sc_c('download_img','name_custom_name');
|
||||
$check=model('Config')->check_img_name_name($name_custom_name);
|
||||
if($check['success']){
|
||||
$name_custom_name=$this->_convert_img_params($name_custom_name, $taskData, $collFields);
|
||||
|
@ -338,11 +507,11 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
|
|||
$name_custom_name='';
|
||||
}
|
||||
|
||||
$GLOBALS['_sc']['c']['download_img']['_name_custom_name']=$name_custom_name;
|
||||
set_g_sc(['c','download_img','_name_custom_name'],$name_custom_name);
|
||||
}else{
|
||||
|
||||
unset($GLOBALS['_sc']['c']['download_img']['_name_custom_path']);
|
||||
unset($GLOBALS['_sc']['c']['download_img']['_name_custom_name']);
|
||||
set_g_sc(['c','download_img','_name_custom_path'],null);
|
||||
set_g_sc(['c','download_img','_name_custom_name'],null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,14 @@
|
|||
*/
|
||||
|
||||
namespace skycaiji\admin\event;
|
||||
|
||||
class Rfile extends Release {
|
||||
/**
|
||||
* 设置页面post过来的config
|
||||
* @param unknown $config
|
||||
*/
|
||||
public function setConfig($config){
|
||||
$file=input('file/a');
|
||||
$file=input('file/a',array());
|
||||
$file['path']=trim($file['path'],'\/\\');
|
||||
$file['hide_fields']=is_array($file['hide_fields'])?$file['hide_fields']:array();
|
||||
if(empty($file['path'])){
|
||||
|
@ -34,21 +35,22 @@ class Rfile extends Release {
|
|||
/*导出数据*/
|
||||
public function export($collFieldsList,$options=null){
|
||||
if(!in_array($this->config['file']['type'],array('xlsx','xls','txt'))){
|
||||
$this->echo_msg('不支持的文件格式:'.$this->config['file']['type']);
|
||||
$this->echo_msg_exit('不支持的文件格式:'.$this->config['file']['type']);
|
||||
}
|
||||
$this->hide_coll_fields($this->config['file']['hide_fields'],$collFieldsList);
|
||||
|
||||
$hideFields=$this->config['file']['hide_fields'];
|
||||
|
||||
$filepath=config('root_path').'/data/'.$this->config['file']['path'].'/'.$this->release['task_id'];
|
||||
$filename=date('Y-m-d',NOW_TIME).'.'.$this->config['file']['type'];
|
||||
$filename=date('Y-m-d',time()).'.'.$this->config['file']['type'];
|
||||
$filename=$filepath.'/'.$filename;
|
||||
|
||||
$addedNum=0;
|
||||
$excelType=array('xlsx'=>'Excel2007','xls'=>'Excel5');
|
||||
if(!empty($excelType[$this->config['file']['type']])){
|
||||
|
||||
$excelType=$excelType[$this->config['file']['type']];
|
||||
if(empty($excelType)){
|
||||
$this->echo_msg('错误的文件格式');
|
||||
exit();
|
||||
$this->echo_msg_exit('错误的文件格式');
|
||||
}
|
||||
|
||||
if(!file_exists($filename)){
|
||||
|
@ -61,6 +63,7 @@ class Rfile extends Release {
|
|||
$newPhpExcel->setActiveSheetIndex(0);
|
||||
|
||||
$firstFields=reset($collFieldsList);
|
||||
$this->hide_coll_fields($hideFields, $firstFields);
|
||||
$firstFields=array_keys($firstFields['fields']);
|
||||
foreach ($firstFields as $k=>$v){
|
||||
$newPhpExcel->getActiveSheet()->setCellValue(chr(65+$k).'1',$v);
|
||||
|
@ -71,28 +74,30 @@ class Rfile extends Release {
|
|||
unset($newPhpExcel);
|
||||
}
|
||||
$filename=realpath($filename);
|
||||
$objReader = \PHPExcel_IOFactory::createReader($excelType);
|
||||
$phpExcel = $objReader->load($filename);
|
||||
$phpExcel->setActiveSheetIndex(0);
|
||||
$rowNum=$phpExcel->getSheet(0)->getHighestRow();
|
||||
$rowNum=intval($rowNum);
|
||||
|
||||
$addedNum=0;
|
||||
foreach ($collFieldsList as $collFieldsKey=>$collFields){
|
||||
|
||||
$this->init_download_img($this->task,$collFields['fields']);
|
||||
$addedNum++;
|
||||
$curRow=$rowNum+$addedNum;
|
||||
$collFields['fields']=is_array($collFields['fields'])?array_values($collFields['fields']):array();
|
||||
foreach ($collFields['fields'] as $k=>$v){
|
||||
$phpExcel->getActiveSheet()->setCellValue(chr(65+$k).$curRow,$this->get_field_val($v));
|
||||
}
|
||||
$this->record_collected($collFields['url'], array('id'=>1,'target'=>$filename,'desc'=>'行:'.$curRow), $this->release,$collFields['title']);
|
||||
|
||||
unset($collFieldsList[$collFieldsKey]['fields']);
|
||||
if($filename){
|
||||
$objReader = \PHPExcel_IOFactory::createReader($excelType);
|
||||
$phpExcel = $objReader->load($filename);
|
||||
$phpExcel->setActiveSheetIndex(0);
|
||||
$rowNum=$phpExcel->getSheet(0)->getHighestRow();
|
||||
$rowNum=intval($rowNum);
|
||||
|
||||
foreach ($collFieldsList as $collFieldsKey=>$collFields){
|
||||
|
||||
$this->init_download_img($this->task,$collFields['fields']);
|
||||
$this->hide_coll_fields($hideFields, $collFields);
|
||||
$addedNum++;
|
||||
$curRow=$rowNum+$addedNum;
|
||||
$collFields['fields']=is_array($collFields['fields'])?array_values($collFields['fields']):array();
|
||||
foreach ($collFields['fields'] as $k=>$v){
|
||||
$phpExcel->getActiveSheet()->setCellValue(chr(65+$k).$curRow,$this->get_field_val($v));
|
||||
}
|
||||
$this->record_collected($collFields['url'], array('id'=>1,'target'=>$filename,'desc'=>'行:'.$curRow), $this->release,$collFields['title']);
|
||||
|
||||
unset($collFieldsList[$collFieldsKey]['fields']);
|
||||
}
|
||||
$objWriter = \PHPExcel_IOFactory::createWriter($phpExcel,$excelType);
|
||||
$objWriter->save($filename);
|
||||
}
|
||||
$objWriter = \PHPExcel_IOFactory::createWriter($phpExcel,$excelType);
|
||||
$objWriter->save($filename);
|
||||
}elseif('txt'==$this->config['file']['type']){
|
||||
|
||||
$txtLine=0;
|
||||
|
@ -109,30 +114,34 @@ class Rfile extends Release {
|
|||
fclose($fpTxt);
|
||||
}else{
|
||||
|
||||
write_dir_file( $filename, null);
|
||||
write_dir_file( $filename, '');
|
||||
}
|
||||
|
||||
|
||||
foreach ($collFieldsList as $collFieldsKey=>$collFields){
|
||||
|
||||
$addedNum++;
|
||||
$fieldVals=array();
|
||||
foreach ($collFields['fields'] as $k=>$v){
|
||||
$fieldVal=str_replace(array("\r","\n"), array('\r','\n'), $this->get_field_val($v));
|
||||
if(empty($this->config['file']['txt_implode'])){
|
||||
|
||||
$fieldVal=str_replace("\t", ' ', $fieldVal);
|
||||
}
|
||||
$fieldVals[]=$fieldVal;
|
||||
}
|
||||
$fieldVals=implode($this->config['file']['txt_implode']?$this->config['file']['txt_implode']:"\t", $fieldVals);
|
||||
if(write_dir_file($filename,$fieldVals."\r\n",FILE_APPEND)){
|
||||
|
||||
$txtLine++;
|
||||
$this->record_collected($collFields['url'], array('id'=>1,'target'=>$filename,'desc'=>'行:'.$txtLine), $this->release,$collFields['title']);
|
||||
}
|
||||
|
||||
unset($collFieldsList[$collFieldsKey]['fields']);
|
||||
$filename=realpath($filename);
|
||||
if($filename){
|
||||
|
||||
foreach ($collFieldsList as $collFieldsKey=>$collFields){
|
||||
|
||||
$this->init_download_img($this->task,$collFields['fields']);
|
||||
$this->hide_coll_fields($hideFields, $collFields);
|
||||
$addedNum++;
|
||||
$fieldVals=array();
|
||||
foreach ($collFields['fields'] as $k=>$v){
|
||||
$fieldVal=str_replace(array("\r","\n"), array('\r','\n'), $this->get_field_val($v));
|
||||
if(empty($this->config['file']['txt_implode'])){
|
||||
|
||||
$fieldVal=str_replace("\t", ' ', $fieldVal);
|
||||
}
|
||||
$fieldVals[]=$fieldVal;
|
||||
}
|
||||
$fieldVals=implode($this->config['file']['txt_implode']?$this->config['file']['txt_implode']:"\t", $fieldVals);
|
||||
if(write_dir_file($filename,$fieldVals."\r\n",FILE_APPEND)){
|
||||
|
||||
$txtLine++;
|
||||
$this->record_collected($collFields['url'], array('id'=>1,'target'=>$filename,'desc'=>'行:'.$txtLine), $this->release,$collFields['title']);
|
||||
}
|
||||
|
||||
unset($collFieldsList[$collFieldsKey]['fields']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class Rtoapi extends Release{
|
|||
* @param unknown $config
|
||||
*/
|
||||
public function setConfig($config){
|
||||
$toapi=input('toapi/a','','trim');
|
||||
$toapi=input('toapi/a',array(),'trim');
|
||||
if(empty($toapi['url'])){
|
||||
$this->error('请输入接口地址');
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ class Rtoapi extends Release{
|
|||
$toapi['param_val']=is_array($toapi['param_val'])?$toapi['param_val']:array();
|
||||
$toapi['param_addon']=is_array($toapi['param_addon'])?$toapi['param_addon']:array();
|
||||
if(is_array($toapi['param_name'])){
|
||||
$toapi['param_name']=array_array_map('trim', $toapi['param_name']);
|
||||
$toapi['param_name']=\util\Funcs::array_array_map('trim', $toapi['param_name']);
|
||||
foreach ($toapi['param_name'] as $k=>$v){
|
||||
if(empty($v)){
|
||||
|
||||
|
|
|
@ -13,25 +13,23 @@ return array(
|
|||
'admincp'=>'后台',
|
||||
|
||||
'sign_wildcard'=>'(*)',
|
||||
'sign_match'=>'[内容{:num}]',
|
||||
'sign_match'=>'[内容{:id}]',
|
||||
'tips_sign_wildcard'=>'通配符可匹配任意字符',
|
||||
'tips_sign_match'=>'匹配任意字符并保存为标签以供调用,等同于捕获组:(?<content编号>.*?)',
|
||||
'tips_sign_match_only'=>'匹配任意字符并保存为标签以供调用,等同于捕获组:(?<content>.*?)',
|
||||
'tips_sign_group'=>'捕获组:(?<content编号>[\s\S]*?),匹配正则并保存为[内容]标签以供调用',
|
||||
'tips_sign_group_only'=>'捕获组:(?<content>[\s\S]*?),匹配正则并保存为[内容]标签以供调用',
|
||||
'tips_sign_match'=>'匹配任意字符并保存为标签以供调用,等同于捕获组:(?<nr标识>.*?)',
|
||||
'tips_sign_match_only'=>'匹配任意字符并保存为标签以供调用,等同于捕获组:(?<nr>.*?)',
|
||||
'tips_sign_group'=>'捕获组:(?<nr标识>[\s\S]*?),匹配正则并保存为[内容]标签以供调用',
|
||||
'tips_sign_group_only'=>'捕获组:(?<nr>[\s\S]*?),匹配正则并保存为[内容]标签以供调用',
|
||||
|
||||
'tips_regular'=>'可使用正则表达式',
|
||||
|
||||
'setting'=>'设置',
|
||||
'setting_site'=>'站点设置',
|
||||
'setting_site'=>'站点设置',
|
||||
'set_site_verifycode'=>'开启图片验证码',
|
||||
|
||||
|
||||
|
||||
'setting_caiji'=>'采集设置',
|
||||
'set_caiji_auto'=>'开启自动采集',
|
||||
'set_caiji_run'=>'自动采集运行方式',
|
||||
'set_caiji_interval'=>'每次采集间隔时间',
|
||||
'set_caiji_interval'=>'采集运行间隔',
|
||||
'set_caiji_num'=>'每次采集数量',
|
||||
'set_caiji_timeout'=>'最大执行时间',
|
||||
|
||||
|
@ -45,8 +43,24 @@ return array(
|
|||
'set_email_type'=>'SMTP端口类型',
|
||||
'set_email_test_subject'=>'测试发送邮件',
|
||||
'set_email_test_body'=>'恭喜,发送邮件成功!',
|
||||
|
||||
|
||||
|
||||
|
||||
'setting_store'=>'云端设置',
|
||||
'store_authkey_error'=>'通信密钥只能由字母和数字组成且长度在6-100位之间',
|
||||
|
||||
|
||||
'down_img_m_'=>'本地存储',
|
||||
'down_img_m_loc'=>'本地存储',
|
||||
'down_img_m_func'=>'使用函数',
|
||||
|
||||
'down_img_name_'=>'按时间生成(方便日期归类)',
|
||||
'down_img_name_time'=>'按时间生成(方便日期归类)',
|
||||
'down_img_name_url'=>'按网址生成(防止重复下载)',
|
||||
'down_img_name_custom'=>'自定义',
|
||||
|
||||
'down_img_name_custom_name_'=>'图片网址MD5码',
|
||||
|
||||
|
||||
'config_error_none_email'=>'没有邮箱服务器配置,请在后台设置!',
|
||||
|
||||
|
||||
|
@ -57,14 +71,14 @@ return array(
|
|||
'user_username'=>'用户名',
|
||||
'user_password'=>'密码',
|
||||
'user_repassword'=>'确认密码',
|
||||
'user_newpwd_tips'=>'如果您想修改密码,请在此输入新密码,否则留空',
|
||||
'user_newpwd_tips'=>'如需修改密码,请在此输入新密码,否则留空',
|
||||
'user_email'=>'邮箱',
|
||||
'user_email_tips'=>'用于找回账号密码',
|
||||
'user_groupid'=>'用户组',
|
||||
|
||||
|
||||
'user_error_has_username'=>'用户名已经存在!',
|
||||
'user_error_edit_not_allow'=>'只有创始人才能编辑他人的账号!',
|
||||
'user_error_delete_not_allow'=>'只有创始人才能删除账号!',
|
||||
'user_error_email'=>'邮箱格式错误!',
|
||||
'user_error_groupid'=>'不是允许的用户组!',
|
||||
'user_error_del_founder'=>'不能删除创始人账号!',
|
||||
|
||||
|
@ -76,14 +90,14 @@ return array(
|
|||
'user_login_in'=>'登录中...',
|
||||
'user_auto_login'=>'正在自动登录...',
|
||||
|
||||
'usertoken_error'=>'用户token错误,请刷新界面重新获取或清除浏览器缓存!',
|
||||
'usertoken_error'=>'用户token错误,请刷新页面或重新登录!',
|
||||
|
||||
'task'=>'任务',
|
||||
'task_add'=>'添加任务',
|
||||
'task_edit'=>'编辑任务',
|
||||
'task_list'=>'任务列表',
|
||||
'task_change_list'=>'切换列表模式',
|
||||
'task_change_folder'=>'切换分组模式',
|
||||
'task_change_list'=>'列表模式',
|
||||
'task_change_folder'=>'分组模式',
|
||||
|
||||
'task_name'=>'任务名称',
|
||||
'task_tg'=>'任务分组',
|
||||
|
@ -101,12 +115,11 @@ return array(
|
|||
'task_root'=>'根目录',
|
||||
'task_loading'=>'正在载入数据',
|
||||
'task_none_data'=>'无数据',
|
||||
'task_caiji_ing'=>'正在采集',
|
||||
'task_set_task'=>'任务设置',
|
||||
'task_set_collector'=>'采集器设置',
|
||||
'task_set_release'=>'发布设置',
|
||||
|
||||
|
||||
|
||||
|
||||
'task_error_null_id'=>'请输入任务id',
|
||||
'task_error_empty_task'=>'不存在任务',
|
||||
'task_error_null_tgid'=>'请输入分组id',
|
||||
|
@ -158,9 +171,10 @@ return array(
|
|||
'field_module_extract'=>'字段提取',
|
||||
'field_module_sign'=>'[内容]标签',
|
||||
|
||||
'process_module_html'=>'html标签过滤',
|
||||
'process_module_html'=>'html标签过滤',
|
||||
'process_module_insert'=>'插入内容',
|
||||
'process_module_replace'=>'内容替换',
|
||||
'process_module_filter'=>'关键词过滤',
|
||||
'process_module_filter'=>'关键词过滤',
|
||||
'process_module_if'=>'条件判断',
|
||||
'process_module_translate'=>'翻译',
|
||||
'process_module_tool'=>'工具箱',
|
||||
|
@ -219,6 +233,7 @@ return array(
|
|||
|
||||
'error_unknown_database'=>'未知的数据库',
|
||||
'error_null_input'=>'请输入{:str}',
|
||||
'error_open_basedir'=>'您的网站开启了目录访问限制(open_basedir),请检查是否因该问题导致目录无法读写!',
|
||||
|
||||
'collected'=>'已采集数据',
|
||||
'collected_list'=>'已采集数据列表',
|
||||
|
@ -260,7 +275,6 @@ return array(
|
|||
'yzm_error_please_input'=>'请输入激活码',
|
||||
'yzm_error_timeout'=>'激活码已过期!请重新发送',
|
||||
'yzm_error_yzm'=>'激活码错误',
|
||||
|
||||
|
||||
'admincp_style'=>'界面',
|
||||
'admincp_sidebar_mini'=>'菜单最小化',
|
||||
|
@ -314,15 +328,14 @@ return array(
|
|||
'separator'=>':',
|
||||
'redirecting'=>'跳转中...',
|
||||
'close'=>'关闭',
|
||||
'return_home'=>'{:time}秒钟后返回<a href="{:url}">页面</a>',
|
||||
|
||||
|
||||
|
||||
'tips_match'=>'示例:<div id="a">[内容1]</div>(*)<div id="b">[内容2]</div>',
|
||||
'tips_matchn'=>'示例:[内容1] [内容2]',
|
||||
'tips_match_only'=>'示例:<div id="content">[内容]</div>',
|
||||
'tips_match_url'=>'示例:<a href="http://demo.com/[内容1]/[内容2]">(*)</a>',
|
||||
'tips_matchn_url'=>'示例:http://www.demo.com/[内容1]-[内容2].html',
|
||||
'tips_match_only'=>'示例:<div id="content">[内容]</div>',
|
||||
'tips_match_area'=>'示例:<div id="a">[内容123]</div>(*)<div id="b">[内容abc]</div>',
|
||||
'tips_matchn_area'=>'示例:[内容123] [内容abc]',
|
||||
'tips_match_url'=>'示例:<a href="http://demo.com/[内容123]/[内容abc]">(*)</a>',
|
||||
'tips_matchn_url'=>'示例:http://www.demo.com/[内容123]-[内容abc].html',
|
||||
|
||||
'release_upgrade'=>'插件版本过低,请升级插件 <a href="https://www.skycaiji.com/manual/doc/release_upgrade" target="_blank">升级教程</a>',
|
||||
);
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class App extends BaseModel{
|
||||
class App extends \skycaiji\common\model\BaseModel{
|
||||
/*检测是否是应用并获取配置文件实例化*/
|
||||
public function app_class($app,$includeClass=true){
|
||||
public function app_class($app,$includeClass=true,$configKey=null){
|
||||
static $passPaths=array('.','..','common','admin','skycaiji','vendor');
|
||||
if($this->right_app($app)){
|
||||
|
||||
|
@ -49,7 +49,14 @@ class App extends BaseModel{
|
|||
}
|
||||
|
||||
if($appClass){
|
||||
$appClass->config=$this->clear_config($appClass->config);
|
||||
if(!property_exists($appClass,'config')){
|
||||
$appClass->config=array();
|
||||
}
|
||||
$appClass->config=$this->clear_config($appClass->config);
|
||||
if(!empty($configKey)){
|
||||
|
||||
return $appClass->config[$configKey];
|
||||
}
|
||||
return $appClass;
|
||||
}
|
||||
}
|
||||
|
@ -158,6 +165,32 @@ class App extends BaseModel{
|
|||
$filename=$this->config_filename($app);
|
||||
unlink($filename);
|
||||
}
|
||||
/*转换扩展*/
|
||||
public function convert_packs($packs,$app,$returnType=null,$navid=null){
|
||||
$packs=is_array($packs)?$packs:array();
|
||||
$appUrl=config('root_website').'/app/'.$app.'/';
|
||||
$returnPacks=array();
|
||||
foreach ($packs as $k=>$v){
|
||||
if($v['type']=='nav'){
|
||||
$v['nav_link']=str_replace(array('{app}','{apps}'), array($appUrl,config('root_website').'/app/'),$v['nav_link']);
|
||||
if(!preg_match('/^\w+\:\/\//', $v['nav_link'])){
|
||||
|
||||
$v['nav_link']=$appUrl.$v['nav_link'];
|
||||
}
|
||||
$v['name']=htmlspecialchars($v['name'],ENT_QUOTES);
|
||||
if(isset($navid)&&$navid==$k){
|
||||
|
||||
$v['is_current']=true;
|
||||
}
|
||||
$packs[$k]=$v;
|
||||
}
|
||||
if($returnType&&$returnType==$v['type']){
|
||||
$returnPacks[$k]=$packs[$k];
|
||||
}
|
||||
}
|
||||
return $returnType?$returnPacks:$packs;
|
||||
}
|
||||
|
||||
private function _array_map($callback, $arr1){
|
||||
if(is_array($arr1)){
|
||||
$arr=array();
|
||||
|
|
|
@ -56,9 +56,13 @@ class CacheModel{
|
|||
public function getCache($cname,$key=null){
|
||||
|
||||
$cache=$this->db()->where('cname',$cname)->find();
|
||||
switch($cache['ctype']){
|
||||
case 1:$cache['data']=intval($cache['data']);break;
|
||||
case 2:$cache['data']=unserialize($cache['data']);break;
|
||||
if(!empty($cache)){
|
||||
switch($cache['ctype']){
|
||||
case 1:$cache['data']=intval($cache['data']);break;
|
||||
case 2:$cache['data']=unserialize($cache['data']);break;
|
||||
}
|
||||
}else{
|
||||
$cache=array();
|
||||
}
|
||||
return $key?$cache[$key]:$cache;
|
||||
}
|
||||
|
@ -89,7 +93,7 @@ class CacheModel{
|
|||
*/
|
||||
public function expire($cname,$timeout=72000){
|
||||
$cache=$this->getCache($cname);
|
||||
if(empty($cache)||abs(NOW_TIME-$cache['dateline']>$timeout)){
|
||||
if(empty($cache)||abs(time()-$cache['dateline']>$timeout)){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
/*采集到的数据库*/
|
||||
class Collected extends BaseModel{
|
||||
class Collected extends \skycaiji\common\model\BaseModel{
|
||||
|
||||
public function __construct($data=[]){
|
||||
try {
|
||||
|
|
|
@ -11,18 +11,18 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class Collector extends BaseModel{
|
||||
class Collector extends \skycaiji\common\model\BaseModel{
|
||||
|
||||
public function add_new($data){
|
||||
$data['addtime']=NOW_TIME;
|
||||
$data['uptime']=NOW_TIME;
|
||||
$data['addtime']=time();
|
||||
$data['uptime']=time();
|
||||
$this->isUpdate(false)->allowField(true)->save($data);
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function edit_by_id($id,$data){
|
||||
unset($data['addtime']);
|
||||
$data['uptime']=NOW_TIME;
|
||||
$data['uptime']=time();
|
||||
|
||||
$this->strict(false)->where(array('id'=>$id))->update($data);
|
||||
}
|
||||
|
@ -130,6 +130,48 @@ class Collector extends BaseModel{
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function compatible_config($config){
|
||||
if(!is_array($config)){
|
||||
$config=array();
|
||||
}
|
||||
|
||||
if(!isset($config['area'])){
|
||||
|
||||
if(!empty($config['area_start'])||!empty($config['area_end'])) {
|
||||
|
||||
$config['area']=$config['area_start'] . (!empty($config['area_end']) ? '(?<nr>[\s\S]+?)' : '(?<nr>[\s\S]+)') . $config['area_end'];
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($config['url_web'])){
|
||||
|
||||
if(!empty($config['url_post'])&&isset($config['url_posts'])){
|
||||
|
||||
\util\Funcs::filter_key_val_list($config['url_posts']['names'], $config['url_posts']['vals']);
|
||||
|
||||
$config['url_web']=array('open'=>1,'form_method'=>'post','form_names'=>$config['url_posts']['names'],'form_vals'=>$config['url_posts']['vals']);
|
||||
|
||||
if(is_array($config['level_urls'])){
|
||||
foreach ($config['level_urls'] as $k=>$v){
|
||||
$v['url_web']=$config['url_web'];
|
||||
$config['level_urls'][$k]=$v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
public static function echo_msg_end_js(){
|
||||
return '<script type="text/javascript" data-echo-msg-is-end="1">window.parent.window.collectorEchoMsg("end");</script>';
|
||||
}
|
||||
|
||||
public static function echo_msg_log_filename($logid){
|
||||
$logid=md5($logid);
|
||||
$filename=RUNTIME_PATH.'echo_msg/'.substr($logid,0,2).'/'.substr($logid,2);
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -11,88 +11,46 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class Config extends BaseModel {
|
||||
protected $pk = 'cname';
|
||||
class Config extends \skycaiji\common\model\Config {
|
||||
|
||||
public function convertData($configItem){
|
||||
if(!empty($configItem)){
|
||||
switch($configItem['ctype']){
|
||||
case 1:$configItem['data']=intval($configItem['data']);break;
|
||||
case 2:$configItem['data']=unserialize($configItem['data']);break;
|
||||
}
|
||||
}
|
||||
return $configItem;
|
||||
}
|
||||
/**
|
||||
* 获取
|
||||
* @param string $cname 名称
|
||||
* @param string $key 数据键名
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfig($cname,$key=null){
|
||||
|
||||
$item=$this->where('cname',$cname)->find();
|
||||
if(!empty($item)){
|
||||
$item=$item->toArray();
|
||||
$item=$this->convertData($item);
|
||||
}
|
||||
return $key?$item[$key]:$item;
|
||||
}
|
||||
/**
|
||||
* 设置
|
||||
* @param string $cname 名称
|
||||
* @param string $value 数据
|
||||
*/
|
||||
public function setConfig($cname,$value){
|
||||
$data=array('cname'=>$cname,'ctype'=>0);
|
||||
if(is_array($value)){
|
||||
$data['ctype']=2;
|
||||
$data['data']=serialize($value);
|
||||
}elseif(is_integer($value)){
|
||||
$data['ctype']=1;
|
||||
$data['data']=intval($value);
|
||||
}else{
|
||||
$data['data']=$value;
|
||||
}
|
||||
$data['dateline']=time();
|
||||
$this->insert($data,true);
|
||||
|
||||
|
||||
$this->cacheConfigList();
|
||||
}
|
||||
/*缓存所有配置*/
|
||||
public function cacheConfigList(){
|
||||
$keyConfig='cache_config_all';
|
||||
$configDbList=$this->column('*');
|
||||
$configDbList=empty($configDbList)?array():$configDbList;
|
||||
$configList=array();
|
||||
foreach ($configDbList as $configItem){
|
||||
$configItem=$this->convertData($configItem);
|
||||
$configList[$configItem['cname']]=$configItem['data'];
|
||||
}
|
||||
cache($keyConfig,array('list'=>$configList));
|
||||
}
|
||||
public function getConfigList(){
|
||||
$keyConfig='cache_config_all';
|
||||
$cacheConfig=cache($keyConfig);
|
||||
if(!is_array($cacheConfig)){
|
||||
$cacheConfig=array();
|
||||
}
|
||||
$configList=$cacheConfig['list'];
|
||||
return is_array($configList)?$configList:array();
|
||||
}
|
||||
|
||||
/*设置版本号*/
|
||||
public function setVersion($version){
|
||||
$version=trim(strtoupper($version),'V');
|
||||
$this->setConfig('version', $version);
|
||||
|
||||
public function server_is_cli($isInput=false,$val=null){
|
||||
$value='';
|
||||
if(empty($isInput)){
|
||||
|
||||
$value=g_sc_c('caiji','server');
|
||||
}else{
|
||||
|
||||
$value=$val;
|
||||
}
|
||||
$value=$value=='cli'?true:false;
|
||||
return $value;
|
||||
}
|
||||
/*获取数据库的版本*/
|
||||
public function getVersion(){
|
||||
$dbVersion=$this->where("`cname`='version'")->find();
|
||||
if(!empty($dbVersion)){
|
||||
$dbVersion=$this->convertData($dbVersion);
|
||||
$dbVersion=$dbVersion['data'];
|
||||
}
|
||||
return $dbVersion;
|
||||
|
||||
|
||||
public function page_render_is_chrome($isInput=false,$val=null){
|
||||
$value='';
|
||||
if(empty($isInput)){
|
||||
|
||||
$value=g_sc_c('page_render','tool');
|
||||
}else{
|
||||
|
||||
$value=$val;
|
||||
}
|
||||
$value=$value=='chrome'?true:false;
|
||||
return $value;
|
||||
}
|
||||
|
||||
/*检查图片路径*/
|
||||
public function check_img_path($imgPath){
|
||||
$return=array('success'=>false,'msg'=>'');
|
||||
|
@ -102,7 +60,7 @@ class Config extends BaseModel {
|
|||
$return['msg']='图片目录必须为绝对路径!';
|
||||
}else{
|
||||
if(!is_dir($imgPath)){
|
||||
$return['msg']='图片目录不存在!';
|
||||
$return['msg']='图片目录不存在!'.(self::check_basedir_limited($imgPath)?lang('error_open_basedir'):'');
|
||||
}else{
|
||||
$imgPath=realpath($imgPath);
|
||||
$root_path=rtrim(realpath(config('root_path')),'\\\/');
|
||||
|
@ -134,7 +92,7 @@ class Config extends BaseModel {
|
|||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/*检查自定义图片名的路径设置*/
|
||||
public function check_img_name_path($path){
|
||||
static $check_list=array();
|
||||
$pathMd5=md5($path);
|
||||
|
@ -157,18 +115,19 @@ class Config extends BaseModel {
|
|||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/*转换自定义图片名的路径*/
|
||||
public function convert_img_name_path($path,$url){
|
||||
if(!empty($path)){
|
||||
$md5=md5($url);
|
||||
static $tags=array('[年]','[月]','[日]','[时]','[分]','[秒]','[前两位]','[后两位]');
|
||||
$nowTime=time();
|
||||
$tagsRe=array(
|
||||
date('Y',NOW_TIME),
|
||||
date('m',NOW_TIME),
|
||||
date('d',NOW_TIME),
|
||||
date('H',NOW_TIME),
|
||||
date('i',NOW_TIME),
|
||||
date('s',NOW_TIME),
|
||||
date('Y',$nowTime),
|
||||
date('m',$nowTime),
|
||||
date('d',$nowTime),
|
||||
date('H',$nowTime),
|
||||
date('i',$nowTime),
|
||||
date('s',$nowTime),
|
||||
substr($md5,0,2),
|
||||
substr($md5,-2,2),
|
||||
);
|
||||
|
@ -184,7 +143,7 @@ class Config extends BaseModel {
|
|||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/*检查自定义图片名的名称设置*/
|
||||
public function check_img_name_name($name){
|
||||
static $check_list=array();
|
||||
$nameMd5=md5($name);
|
||||
|
@ -204,29 +163,36 @@ class Config extends BaseModel {
|
|||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/*转换自定义图片名的名称*/
|
||||
public function convert_img_name_name($name,$url){
|
||||
$md5=md5($url);
|
||||
if(!empty($name)){
|
||||
$urlname='';
|
||||
if(preg_match('/([^\/]+?)\./', $url,$urlname)){
|
||||
if(preg_match('/([^\/]+?)(\.[a-zA-Z][\w\-]+){0,1}([\?\#]|$)/', $url,$urlname)){
|
||||
|
||||
$urlname=$urlname[1];
|
||||
if(mb_strlen($urlname,'utf-8')>100){
|
||||
|
||||
$urlname=mb_substr($urlname,0,100,'utf-8');
|
||||
}
|
||||
}else{
|
||||
$urlname='';
|
||||
}
|
||||
|
||||
if(empty($urlname)){
|
||||
|
||||
$urlname=$md5;
|
||||
}
|
||||
|
||||
static $tags=array('[年]','[月]','[日]','[时]','[分]','[秒]','[前两位]','[后两位]','[图片网址MD5码]','[图片原名]');
|
||||
$nowTime=time();
|
||||
$tagsRe=array(
|
||||
date('Y',NOW_TIME),
|
||||
date('m',NOW_TIME),
|
||||
date('d',NOW_TIME),
|
||||
date('H',NOW_TIME),
|
||||
date('i',NOW_TIME),
|
||||
date('s',NOW_TIME),
|
||||
date('Y',$nowTime),
|
||||
date('m',$nowTime),
|
||||
date('d',$nowTime),
|
||||
date('H',$nowTime),
|
||||
date('i',$nowTime),
|
||||
date('s',$nowTime),
|
||||
substr($md5,0,2),
|
||||
substr($md5,-2,2),
|
||||
$md5,
|
||||
|
@ -242,7 +208,8 @@ class Config extends BaseModel {
|
|||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
/*从采集设置中提取出图片本地化设置*/
|
||||
public function get_img_config_from_caiji($caijiConfig){
|
||||
$config=array();
|
||||
if(!empty($caijiConfig)){
|
||||
|
@ -256,8 +223,9 @@ class Config extends BaseModel {
|
|||
}
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function detect_php_exe(){
|
||||
|
||||
/*检测出php可执行文件路径*/
|
||||
public static function detect_php_exe(){
|
||||
static $php_filename=null;
|
||||
|
||||
if(!isset($php_filename)){
|
||||
|
@ -290,11 +258,125 @@ class Config extends BaseModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$php_filename='php';
|
||||
}
|
||||
if(empty($php_filename)){
|
||||
$php_filename='php';
|
||||
}
|
||||
}
|
||||
return $php_filename;
|
||||
}
|
||||
|
||||
public function exec_php_version($phpFile){
|
||||
$return=false;
|
||||
if(empty($phpFile)){
|
||||
|
||||
$phpFile=self::detect_php_exe();
|
||||
}
|
||||
if(!empty($phpFile)){
|
||||
$return=array('success'=>false,'msg'=>'');
|
||||
$phpFile=self::cli_safe_filename($phpFile);
|
||||
$phpFile.=' -v';
|
||||
$info=proc_open_exec($phpFile,'all',3,true);
|
||||
$info=is_array($info)?$info:array();
|
||||
$info['output']=trim($info['output']);
|
||||
$info['error']=trim($info['error']);
|
||||
|
||||
if(is_array($info['status'])&&$info['status']['running']){
|
||||
|
||||
if($info['error']){
|
||||
$return['msg']=$info['error'];
|
||||
}elseif($info['output']){
|
||||
$return['success']=true;
|
||||
$return['msg']=('测试成功,PHP信息:'.$info['output']);
|
||||
}else{
|
||||
$return['success']=true;
|
||||
}
|
||||
}elseif($info['error']){
|
||||
$return['msg']=$info['error'];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function cli_safe_filename($filename){
|
||||
if(!empty($filename)){
|
||||
if(IS_WIN){
|
||||
|
||||
$filename='"'.$filename.'"';
|
||||
}else{
|
||||
|
||||
if(preg_match('/(?<!\\\)\s/', $filename)){
|
||||
$filename=preg_replace('/(?<!\\\)(\s)/', "\\\\$1", $filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/*open_basedir目录保护,检查目录是否受限*/
|
||||
public static function check_basedir_limited($path){
|
||||
$openBasedir=ini_get('open_basedir');
|
||||
if(empty($openBasedir)){
|
||||
return false;
|
||||
}
|
||||
if(empty($path)){
|
||||
return false;
|
||||
}
|
||||
if(file_exists($path)){
|
||||
|
||||
return false;
|
||||
}
|
||||
$path=str_replace('\\', '/', $path);
|
||||
$path=rtrim($path,'/').'/';
|
||||
|
||||
$openBasedir=explode(IS_WIN?';':':', $openBasedir);
|
||||
if(is_array($openBasedir)){
|
||||
foreach ($openBasedir as $dir){
|
||||
if(empty($dir)){
|
||||
continue;
|
||||
}
|
||||
$dir=str_replace('\\', '/', $dir);
|
||||
$dir=rtrim($dir,'/').'/';
|
||||
if(stripos($path, $dir)===0){
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static function check_collect_wait(){
|
||||
$return=false;
|
||||
$lastCollectTime=cache('last_collect_time');
|
||||
if(g_sc('c_caiji_interval')>0){
|
||||
|
||||
$waitTime=(60*g_sc('c_caiji_interval'))-abs(time()-$lastCollectTime);
|
||||
if($waitTime>0){
|
||||
$return=array(
|
||||
'msg'=>'再次采集需等待'.self::wait_time_tips($waitTime),
|
||||
'wait'=>$waitTime
|
||||
);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function wait_time_tips($seconds){
|
||||
$seconds=intval($seconds);
|
||||
if($seconds>0){
|
||||
if($seconds<60){
|
||||
$seconds.='秒';
|
||||
}else{
|
||||
$seconds=$seconds/60;
|
||||
$seconds=substr(sprintf("%.3f", $seconds), 0, -2);
|
||||
$seconds.='分钟';
|
||||
}
|
||||
}else{
|
||||
$seconds='';
|
||||
}
|
||||
return $seconds;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -32,7 +32,7 @@ class DbCommon{
|
|||
'break_reconnect'=>true,
|
||||
'params'=>array(),
|
||||
);
|
||||
if(!empty($GLOBALS['_sc']['c']['site']['dblong'])){
|
||||
if(!is_empty(g_sc_c('site','dblong'))){
|
||||
|
||||
$this->config['params'][\PDO::ATTR_PERSISTENT]=true;
|
||||
}
|
||||
|
|
|
@ -10,19 +10,27 @@
|
|||
*/
|
||||
|
||||
namespace skycaiji\admin\model;
|
||||
class FuncApp extends BaseModel{
|
||||
class FuncApp extends \skycaiji\common\model\BaseModel{
|
||||
protected $tableName='func_app';
|
||||
|
||||
public $funcPath;
|
||||
public $funcModules=array(
|
||||
'process'=>array (
|
||||
'name'=>'数据处理',
|
||||
'loc'=>'数据处理»使用函数'
|
||||
'loc'=>'任务»采集器设置»数据处理»使用函数',
|
||||
'config'=>'allow_process_func',
|
||||
'extend'=>'EXTEND_PROCESS_FUNC',
|
||||
),
|
||||
'processIf'=>array(
|
||||
'name'=>'条件判断',
|
||||
'loc'=>'数据处理»条件判断»使用函数'
|
||||
)
|
||||
'loc'=>'任务»采集器设置»数据处理»条件判断»使用函数',
|
||||
'config'=>'allow_process_if',
|
||||
'extend'=>'EXTEND_PROCESS_IF',
|
||||
),
|
||||
'downloadImg'=>array(
|
||||
'name'=>'下载图片',
|
||||
'loc'=>'设置»采集设置»图片本地化»使用函数',
|
||||
)
|
||||
);
|
||||
public function __construct($data = []){
|
||||
parent::__construct($data);
|
||||
|
@ -34,7 +42,8 @@ class FuncApp extends BaseModel{
|
|||
$data['module']=$this->format_module($data['module']);
|
||||
$data['name']=strip_tags($data['name']);
|
||||
$data['addtime']=time();
|
||||
$data['enable']=0;
|
||||
$data['enable']=intval($data['enable']);
|
||||
$data['enable']=$data['enable']>0?1:0;
|
||||
$data['uptime']=$data['uptime']>0?$data['uptime']:time();
|
||||
return $this->strict(false)->insert($data,false,true);
|
||||
}
|
||||
|
@ -68,7 +77,7 @@ class FuncApp extends BaseModel{
|
|||
$funcTpl=str_replace(array('{$module}','{$classname}','{$name}','{$methods}'), array($module,$app,$appData['name'],$appData['methods']), $funcTpl);
|
||||
|
||||
if(write_dir_file($funcFile,$funcTpl)){
|
||||
return $this->insertApp(array('module'=>$module,'app'=>$app,'name'=>$name));
|
||||
return $this->insertApp(array('module'=>$module,'app'=>$app,'name'=>$name,'enable'=>1));
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
@ -90,7 +99,7 @@ class FuncApp extends BaseModel{
|
|||
return false;
|
||||
}
|
||||
|
||||
$codeFmt=strip_phpcode_comment($code);
|
||||
$codeFmt=\util\Funcs::strip_phpcode_comment($code);
|
||||
|
||||
if(!preg_match('/^\s*namespace\s+plugin\\\func\b/im',$codeFmt)){
|
||||
|
||||
|
@ -127,9 +136,9 @@ class FuncApp extends BaseModel{
|
|||
return $this->funcPath."{$module}/{$app}.php";
|
||||
}
|
||||
/*获取插件文件类的属性*/
|
||||
public function get_app_class($module,$app){
|
||||
public function get_app_class($module,$app,$options=array()){
|
||||
$module=$this->format_module($module);
|
||||
$filename=$this->funcPath."{$module}/{$app}.php";
|
||||
$filename=$this->filename($module,$app);
|
||||
if(file_exists($filename)){
|
||||
$class=$this->app_classname($module, $app);
|
||||
if(class_exists($class)){
|
||||
|
@ -149,18 +158,74 @@ class FuncApp extends BaseModel{
|
|||
$reMethods=$reClass->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
$methods=array();
|
||||
if(!empty($reMethods)){
|
||||
$phpCode=array();
|
||||
if(!empty($options['method_code'])||!empty($options['method_params'])){
|
||||
$phpCode=file($filename);
|
||||
}
|
||||
foreach ($reMethods as $reMethod){
|
||||
$methodData=array();
|
||||
|
||||
$methodName=$reMethod->name;
|
||||
if(empty($methodName)||strpos($methodName,'__')===0){
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$methodCmt=$reMethod->getDocComment();
|
||||
if(empty($options['doc_comment'])){
|
||||
|
||||
$methodCmt=preg_replace('/^[\/\*\s]+/m', '', $methodCmt);
|
||||
$methodCmt=trim($methodCmt);
|
||||
}
|
||||
|
||||
$comment=$reMethod->getDocComment();
|
||||
$comment=preg_replace('/^[\/\*\s]+/m', '', $comment);
|
||||
$comment=trim($comment);
|
||||
|
||||
$methods[$methodName]=array('comment'=>$comment);
|
||||
if(!empty($options['comment_cut'])){
|
||||
|
||||
$methodCmtCut='';
|
||||
if($methodCmt){
|
||||
$methodCmt=preg_replace('/^[\/\*\s]+/m', '', $methodCmt);
|
||||
$methodCmt=trim($methodCmt);
|
||||
|
||||
$methodCmtCut=$methodCmt;
|
||||
$methodCmtCut=htmlspecialchars($methodCmtCut,ENT_QUOTES);
|
||||
$methodCmtCut=preg_replace('/[\r\n]+/', ' ', $methodCmtCut);
|
||||
$methodCmtCut=trim($methodCmtCut);
|
||||
$maxLen=50;
|
||||
if(mb_strlen($methodCmtCut,'utf-8')>$maxLen){
|
||||
|
||||
$methodCmtCut=mb_substr($methodCmtCut,0,$maxLen,'utf-8').'...';
|
||||
}
|
||||
|
||||
$methodCmt=htmlspecialchars($methodCmt,ENT_QUOTES);
|
||||
$methodCmt=preg_replace('/[\r\n]+/', '\r\n', $methodCmt);
|
||||
$methodCmt=trim($methodCmt);
|
||||
}
|
||||
$methodData['comment_cut']=$methodCmtCut;
|
||||
}
|
||||
$methodData['comment']=$methodCmt;
|
||||
|
||||
if(!empty($options['method_code'])||!empty($options['method_params'])){
|
||||
|
||||
$methodStart=$reMethod->getStartLine();
|
||||
$methodEnd=$reMethod->getEndLine();
|
||||
$methodCode=array_slice($phpCode, $methodStart-1, $methodEnd-$methodStart+1);
|
||||
$methodCode=is_array($methodCode)?implode('',$methodCode):'';
|
||||
if(!empty($options['method_code'])){
|
||||
|
||||
$methodData['code']=$methodCode;
|
||||
}
|
||||
|
||||
if(!empty($options['method_params'])){
|
||||
$methodParams='';
|
||||
if(preg_match('/\bfunction\s+'.addslashes($methodName).'\s*\((.*?)\)\s*\{/i',$methodCode,$methodParams)){
|
||||
$methodParams=$methodParams[1];
|
||||
}else{
|
||||
$methodParams='';
|
||||
}
|
||||
$methodData['params']=trim(htmlspecialchars($methodParams,ENT_QUOTES));
|
||||
}
|
||||
}
|
||||
$methods[$methodName]=$methodData;
|
||||
}
|
||||
}
|
||||
return array (
|
||||
|
@ -170,7 +235,7 @@ class FuncApp extends BaseModel{
|
|||
'copyright' => $copyright,
|
||||
'identifier' => $identifier,
|
||||
'name' => $name,
|
||||
'methods' => $methods
|
||||
'methods' => $methods,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -241,6 +306,167 @@ class FuncApp extends BaseModel{
|
|||
return $appList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行插件函数
|
||||
* @param string $module 模块
|
||||
* @param string $funcNameFmt 函数/方法
|
||||
* @param string $defaultVal 默认传入值
|
||||
* @param string $paramsStr 输入的参数(有换行符)
|
||||
* @param array $paramValList 所有参数值(调用参数时使用)
|
||||
*/
|
||||
public function execute_func($module,$funcName,$defaultVal,$paramsStr,$paramValList=null){
|
||||
|
||||
static $func_class_list=array('process'=>array(),'processIf'=>array(),'downloadImg'=>array());
|
||||
static $func_param_num_list=array('process'=>array(),'processIf'=>array(),'downloadImg'=>array());
|
||||
$class_list=&$func_class_list[$module];
|
||||
$param_num_list=&$func_param_num_list[$module];
|
||||
|
||||
$options = $this->funcModules[$module];
|
||||
|
||||
$return=array('success'=>false,'msg'=>'','data'=>null);
|
||||
|
||||
if(!empty($funcName)){
|
||||
$funcNameFmt=strpos($funcName, ':')!==false?explode(':', $funcName):$funcName;
|
||||
if(!is_array($funcNameFmt)){
|
||||
|
||||
if(!function_exists($funcNameFmt)&&$funcNameFmt!='empty'){
|
||||
|
||||
$return['msg']=$options['loc'].'»无效的函数:'.$funcNameFmt;
|
||||
}elseif(!array_key_exists($funcNameFmt, config($options['config']))&&!array_key_exists($funcNameFmt, config($options['extend']))){
|
||||
|
||||
$return['msg']=$options['loc'].'»未配置函数:'.$funcNameFmt;
|
||||
}else{
|
||||
$return['success']=true;
|
||||
}
|
||||
}else{
|
||||
|
||||
$className=$funcNameFmt[0];
|
||||
$methodName=$funcNameFmt[1];
|
||||
if(!isset($class_list[$className])){
|
||||
|
||||
$enable=$this->field('enable')->where(array('app'=>$className,'module'=>$module))->value('enable');
|
||||
if($enable){
|
||||
|
||||
$class=$this->app_classname($module,$className);
|
||||
if(!class_exists($class)){
|
||||
|
||||
$class_list[$className]=1;
|
||||
}else{
|
||||
$class=new $class();
|
||||
$class_list[$className]=$class;
|
||||
}
|
||||
}else{
|
||||
$class_list[$className]=2;
|
||||
}
|
||||
}
|
||||
if(is_object($class_list[$className])){
|
||||
|
||||
if(!method_exists($class_list[$className], $methodName)){
|
||||
$return['msg']=$options['loc'].'»不存在方法:'.$className.'->'.$methodName;
|
||||
}else{
|
||||
$return['success']=true;
|
||||
}
|
||||
}else{
|
||||
$msg=$options['loc'].'»';
|
||||
if($class_list[$className]==1){
|
||||
$msg.='不存在插件:';
|
||||
}elseif($class_list[$className]==2){
|
||||
$msg.='已禁用插件:';
|
||||
}else{
|
||||
$msg.='无效的插件:';
|
||||
}
|
||||
$return['msg']=$msg.$className;
|
||||
}
|
||||
}
|
||||
|
||||
if($return['success']){
|
||||
static $func_param_list=array();
|
||||
$funcParam=null;
|
||||
if(empty($paramsStr)){
|
||||
|
||||
$funcParam=array($defaultVal);
|
||||
}else{
|
||||
$fparamMd5=md5($paramsStr);
|
||||
if(!isset($func_param_list[$fparamMd5])){
|
||||
if(preg_match_all('/[^\r\n]+/',$paramsStr,$mfuncParam)){
|
||||
$func_param_list[$fparamMd5]=$mfuncParam[0];
|
||||
}
|
||||
}
|
||||
$funcParam=$func_param_list[$fparamMd5];
|
||||
if($funcParam){
|
||||
foreach ($funcParam as $k=>$v){
|
||||
|
||||
$v=str_replace('###', $defaultVal, $v);
|
||||
|
||||
if($paramValList&&preg_match_all('/\[(?:\x{5b57}\x{6bb5}|\x{56fe}\x{7247})\:.+?\]/u',$v,$match_params)){
|
||||
$match_params=$match_params[0];
|
||||
for($i=0;$i<count($match_params);$i++){
|
||||
$v=str_replace($match_params[$i],$paramValList[$match_params[$i]],$v);
|
||||
}
|
||||
}
|
||||
$funcParam[$k]=$v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($funcParam)&&is_array($funcParam)){
|
||||
try {
|
||||
$callback=null;
|
||||
$paramNum=array();
|
||||
if(!is_array($funcNameFmt)){
|
||||
|
||||
if($funcNameFmt=='empty'){
|
||||
|
||||
$return['data']=empty($funcParam[0]);
|
||||
}else{
|
||||
$callback=$funcNameFmt;
|
||||
if(!isset($param_num_list[$funcNameFmt])){
|
||||
|
||||
$refFunc=new \ReflectionFunction($funcNameFmt);
|
||||
$param_num_list[$funcNameFmt]=array(
|
||||
'num'=>intval($refFunc->getNumberOfParameters()),
|
||||
'required'=>intval($refFunc->getNumberOfRequiredParameters()),
|
||||
);
|
||||
}
|
||||
$paramNum=$param_num_list[$funcNameFmt];
|
||||
}
|
||||
}else{
|
||||
|
||||
$callback=array($class_list[$funcNameFmt[0]],$funcNameFmt[1]);
|
||||
if(!isset($param_num_list[$funcName])){
|
||||
|
||||
$refMethod=(new \ReflectionClass($class_list[$funcNameFmt[0]]))->getMethod($funcNameFmt[1]);
|
||||
$param_num_list[$funcName]=array(
|
||||
'num'=>intval($refMethod->getNumberOfParameters()),
|
||||
'required'=>intval($refMethod->getNumberOfRequiredParameters()),
|
||||
);
|
||||
}
|
||||
$paramNum=$param_num_list[$funcName];
|
||||
}
|
||||
if($callback){
|
||||
$paramCount=count($funcParam);
|
||||
if($paramCount<$paramNum['required']){
|
||||
|
||||
$return['success']=false;
|
||||
$return['msg']=$options['loc'].'»'.$funcName.'»至少传入'.$paramNum['required'].'个参数';
|
||||
}elseif($paramCount>$paramNum['num']){
|
||||
|
||||
$funcParam=array_slice($funcParam,0,$paramNum['num']);
|
||||
}
|
||||
if($return['success']){
|
||||
$return['data']=call_user_func_array($callback, $funcParam);
|
||||
}
|
||||
}
|
||||
}catch (\Exception $ex){
|
||||
|
||||
$return['success']=false;
|
||||
$return['msg']=$options['loc'].'»'.$funcName.'»运行错误:'.$ex->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -11,32 +11,198 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
/*第三方服务商*/
|
||||
class Provider extends BaseModel{
|
||||
/*匹配域名*/
|
||||
public static function match_domain($url){
|
||||
$domain=null;
|
||||
class Provider extends \skycaiji\common\model\BaseModel{
|
||||
|
||||
public static function match_domain_http($url){
|
||||
$domain='';
|
||||
if(preg_match('/^\w+\:\/\/[\w\-]+(\.[\w\-]+)*(\:\d+){0,1}/', $url,$domain)){
|
||||
$domain=rtrim($domain[0],'/');
|
||||
$domain=strtolower($domain);
|
||||
$domain=strtolower($domain[0]);
|
||||
}else{
|
||||
$domain=null;
|
||||
$domain='';
|
||||
}
|
||||
return $domain;
|
||||
return $domain?$domain:'';
|
||||
}
|
||||
|
||||
public static function match_domain_name($url){
|
||||
$domain='';
|
||||
if(preg_match('/^\w+\:\/\/(?P<domain>[\w\-]+(\.[\w\-]+)*)(\:\d+){0,1}/', $url,$domain)){
|
||||
$domain=strtolower($domain['domain']);
|
||||
}else{
|
||||
$domain='';
|
||||
}
|
||||
return $domain?$domain:'';
|
||||
}
|
||||
|
||||
|
||||
public static function is_official_url($url){
|
||||
$domain=self::match_domain_http($url);
|
||||
if(!empty($domain)&&in_array($domain,config('allow_origins'))){
|
||||
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function create_store_url($url,$urlPath,$urlParams=null){
|
||||
if(empty($url)){
|
||||
|
||||
$url='https://www.skycaiji.com';
|
||||
}
|
||||
$urlParams=$urlParams?('?'.http_build_query($urlParams)):'';
|
||||
|
||||
$url=rtrim($url,'/').'/'.$urlPath.$urlParams;
|
||||
return $url;
|
||||
}
|
||||
|
||||
/*获取id*/
|
||||
public function getIdByUrl($url){
|
||||
$url=self::match_domain($url);
|
||||
if(is_official_url($url)){
|
||||
$domain=self::match_domain_http($url);
|
||||
if(self::is_official_url($domain)){
|
||||
|
||||
$url=null;
|
||||
$domain=null;
|
||||
}
|
||||
$id=0;
|
||||
if(!empty($url)){
|
||||
$id=model('Provider')->where('domain',$url)->value('id');
|
||||
if(!empty($domain)){
|
||||
$id=$this->where('domain',$domain)->value('id');
|
||||
$id=intval($id);
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
public function getAuthkey($provData){
|
||||
$authkey='';
|
||||
if(!empty($provData)){
|
||||
|
||||
$authkey=$provData['authkey'];
|
||||
}else{
|
||||
|
||||
$authkey=g_sc_c('store','authkey_store');
|
||||
}
|
||||
if(empty($authkey)){
|
||||
|
||||
$authkey=g_sc_c('store','authkey');
|
||||
}
|
||||
return $authkey?$authkey:'';
|
||||
}
|
||||
|
||||
public function getStoreUrl($provData){
|
||||
$url='';
|
||||
if(!empty($provData)){
|
||||
|
||||
$url=$provData['url'];
|
||||
}else{
|
||||
|
||||
$url=self::create_store_url(null,'store');
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function createAuthsign($authkey,$clientUrl,$storeUrl,$timestamp){
|
||||
$data=array(
|
||||
'authkey'=>$authkey?md5($authkey):'',
|
||||
'client_domain'=>self::match_domain_name($clientUrl),
|
||||
'store_domain'=>self::match_domain_name($storeUrl),
|
||||
'timestamp'=>$timestamp,
|
||||
);
|
||||
ksort($data);
|
||||
$data=md5(http_build_query($data));
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function checkData($provData){
|
||||
$result=array('success'=>false,'msg'=>'');
|
||||
if(empty($provData)){
|
||||
$result['msg']='未知的第三方平台';
|
||||
}elseif(empty($provData['enable'])){
|
||||
$result['msg']='未受信任的第三方平台:'.$provData['url'];
|
||||
}else{
|
||||
$result['success']=true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function checkAuthkey($authkey,$sameAsPwd=false){
|
||||
$result=array('success'=>false,'msg'=>'','data'=>array());
|
||||
$authkey=$authkey?$authkey:'';
|
||||
|
||||
if(!empty($authkey)&&!preg_match('/^[a-zA-Z0-9]{6,100}$/i', $authkey)){
|
||||
|
||||
$result['msg']=lang('store_authkey_error');
|
||||
}else{
|
||||
|
||||
$result['success']=true;
|
||||
if(!$sameAsPwd){
|
||||
|
||||
$userData=g_sc('user');
|
||||
if($userData['password']==\skycaiji\admin\model\User::pwd_encrypt($authkey,$userData['salt'])){
|
||||
$result['success']=false;
|
||||
$result['data']['same_as_pwd']='检测到通信密钥与登录密码一致,这容易导致密码泄露,确定设置为该值?';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function storeAuthResult(){
|
||||
$storeUrl=input('store_url','','trim');
|
||||
$authsign=input('authsign','','trim');
|
||||
$timestamp=input('timestamp/d',0);
|
||||
|
||||
$result=array('success'=>false,'msg'=>'','data'=>array());
|
||||
|
||||
if(empty($storeUrl)){
|
||||
|
||||
$storeUrl=request()->server('HTTP_REFERER');
|
||||
}
|
||||
$storeUrl=$storeUrl?$storeUrl:'';
|
||||
|
||||
$provData=null;
|
||||
$provId=$this->getIdByUrl($storeUrl);
|
||||
if($provId>0){
|
||||
|
||||
$provData=$this->getById($provId);
|
||||
$provData=empty($provData)?array():$provData->toArray();
|
||||
$check=$this->checkData($provData);
|
||||
if(!$check['success']){
|
||||
$result['msg']=$check['msg'];
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if(empty($provData)&&!self::is_official_url($storeUrl)){
|
||||
|
||||
$result['msg']='未知的第三方来源:'.$storeUrl;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$authkey=$this->getAuthkey($provData);
|
||||
|
||||
$clientinfo=clientinfo();
|
||||
$clientSign=$this->createAuthsign($authkey,$clientinfo['url'],$storeUrl,$timestamp);
|
||||
if($clientSign!=$authsign){
|
||||
|
||||
$msg='<div style="font-weight:normal;">验证失败,客户端的<a href="'.url('setting/store','',true,true).'" target="_blank" style="font-weight:bold;">通信密钥</a>与';
|
||||
$msg.='<a href="'.self::create_store_url($provData?$provData['url']:null,'client/go/authkey',array('clientinfo'=>g_sc('clientinfo'))).'" target="_blank" style="font-weight:bold;">';
|
||||
$msg.=($provData?'第三方':'云').'平台</a>中的不一致</div>';
|
||||
$result['msg']=$msg;
|
||||
return $result;
|
||||
}else{
|
||||
|
||||
$nowTime=time();
|
||||
if(abs($nowTime-$timestamp)>1000){
|
||||
$result['msg']=sprintf('连接超时,请校对时间<br>平台端请求:%s<br>客户端响应:%s',date('Y-m-d H:i:s',$timestamp),date('Y-m-d H:i:s',$nowTime));
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
$result['success']=true;
|
||||
$result['data']['provider_id']=$provId;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -11,12 +11,12 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class Proxyip extends BaseModel {
|
||||
class Proxyip extends \skycaiji\common\model\BaseModel {
|
||||
public $name='proxy_ip';
|
||||
public $setting;
|
||||
public function __construct($data=[]){
|
||||
parent::__construct($data);
|
||||
$this->setting=$GLOBALS['_sc']['c']['proxy'];
|
||||
$this->setting=g_sc_c('proxy');
|
||||
}
|
||||
/*数据库ip转换成get_html格式的ip*/
|
||||
public function to_proxy_ip($proxyDbIp){
|
||||
|
@ -45,21 +45,24 @@ class Proxyip extends BaseModel {
|
|||
if(!empty($this->setting['open'])){
|
||||
|
||||
$cond=array();
|
||||
$order=null;
|
||||
if(!empty($this->setting['use'])){
|
||||
|
||||
if($this->setting['use']=='num'){
|
||||
|
||||
$cond['num']=array('lt',$this->setting['use_num']);
|
||||
$order='no desc';
|
||||
}elseif($this->setting['use']=='time'){
|
||||
|
||||
$cond['time']=array(array('eq',0),array('gt',time()-$this->setting['use_time']*60), 'or') ;
|
||||
$cond['time']=array(array('eq',0),array('gt',time()-$this->setting['use_time']*60), 'or') ;
|
||||
$order='no desc';
|
||||
}
|
||||
}else{
|
||||
|
||||
$cond['num']=array('lt',1);
|
||||
}
|
||||
$cond['invalid']=0;
|
||||
$proxyipData=$this->where($cond)->find();
|
||||
$proxyipData=$this->where($cond)->order($order)->find();
|
||||
|
||||
if(empty($proxyipData)&&!empty($this->setting['api']['open'])){
|
||||
|
||||
|
@ -69,12 +72,12 @@ class Proxyip extends BaseModel {
|
|||
if($this->where('invalid',0)->count()<=0){
|
||||
|
||||
$this->add_api_ips($this->setting);
|
||||
$proxyipData=$this->where($cond)->find();
|
||||
$proxyipData=$this->where($cond)->order($order)->find();
|
||||
}
|
||||
}elseif($apiInsert=='end'){
|
||||
|
||||
$this->add_api_ips($this->setting);
|
||||
$proxyipData=$this->where($cond)->find();
|
||||
$proxyipData=$this->where($cond)->order($order)->find();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,9 +94,8 @@ class Proxyip extends BaseModel {
|
|||
|
||||
$this->strict(false)->where('1=1')->update(array('num'=>0));
|
||||
}
|
||||
$proxyipData=$this->where($cond)->find();
|
||||
$proxyipData=$this->where($cond)->order($order)->find();
|
||||
}
|
||||
|
||||
if(!empty($proxyipData)){
|
||||
|
||||
$upData=array();
|
||||
|
@ -121,18 +123,18 @@ class Proxyip extends BaseModel {
|
|||
}
|
||||
/*ip失败次数*/
|
||||
public function set_ip_failed($proxy_ip){
|
||||
if(empty($this->setting['failed'])||$this->setting['failed']<=0){
|
||||
|
||||
return;
|
||||
}
|
||||
if(empty($proxy_ip)){
|
||||
return;
|
||||
}
|
||||
$upData=array();
|
||||
$upData['failed']=$proxy_ip['failed']+1;
|
||||
if($upData['failed']>=$this->setting['failed']){
|
||||
|
||||
$upData['invalid']=1;
|
||||
$upData['failed']=intval($proxy_ip['failed'])+1;
|
||||
|
||||
if(!empty($this->setting['failed'])){
|
||||
|
||||
if($upData['failed']>=$this->setting['failed']){
|
||||
|
||||
$upData['invalid']=1;
|
||||
}
|
||||
}
|
||||
$this->strict(false)->where(array('ip'=>$proxy_ip['ip']))->update($upData);
|
||||
}
|
||||
|
@ -176,12 +178,12 @@ class Proxyip extends BaseModel {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*转换api匹配格式*/
|
||||
public function convert_format($format){
|
||||
static $list=array();
|
||||
$md5=md5($format);
|
||||
if(!isset($list[$md5])){
|
||||
$format=preg_replace('/\\\*([\'\/])/',"\\\\$1",$format);
|
||||
$format=controller('admin/Cpattern','event')->correct_reg_pattern($format);
|
||||
$format=str_replace(array('[ip]','[端口]','[用户名]','[密码]','(*)')
|
||||
,array('(?P<ip>(\d+\.){3}\d+)','(?P<port>\d+)','(?P<user>[^\s\\\'\"\<\>\,]*)','(?P<pwd>[^\s\\\'\"\<\>\,]*)','[\s\S]*?')
|
||||
,$format);
|
||||
|
@ -192,10 +194,11 @@ class Proxyip extends BaseModel {
|
|||
}
|
||||
return $format;
|
||||
}
|
||||
|
||||
/*转换成数据库形式*/
|
||||
public function ips_format2db($ipList,$default=array()){
|
||||
$ipList=is_array($ipList)?$ipList:array();
|
||||
$default=is_array($default)?$default:array();
|
||||
$nowTime=time();
|
||||
foreach ($ipList as $k=>$ip){
|
||||
if(empty($ip)||empty($ip['ip'])){
|
||||
unset($ipList[$k]);
|
||||
|
@ -208,7 +211,7 @@ class Proxyip extends BaseModel {
|
|||
}
|
||||
$ip['ip']=$ip['ip'].':'.$ip['port'];
|
||||
$ip['type']=$default['type'];
|
||||
$ip['addtime']=NOW_TIME;
|
||||
$ip['addtime']=$nowTime;
|
||||
unset($ip['port']);
|
||||
$ipList[$k]=$ip;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class Release extends BaseModel{
|
||||
class Release extends \skycaiji\common\model\BaseModel{
|
||||
public function getByTaskid($taskId){
|
||||
static $dataList=array();
|
||||
if(empty($taskId)){
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace skycaiji\admin\model;
|
||||
|
||||
use think\Loader;
|
||||
class ReleaseApp extends BaseModel{
|
||||
class ReleaseApp extends \skycaiji\common\model\BaseModel{
|
||||
protected $tableName='release_app';
|
||||
|
||||
public function addCms($cms,$code='',$tpl=''){
|
||||
|
@ -21,14 +21,14 @@ class ReleaseApp extends BaseModel{
|
|||
}
|
||||
|
||||
$cms['module']='cms';
|
||||
$cms['uptime']=$cms['uptime']>0?$cms['uptime']:NOW_TIME;
|
||||
$cms['uptime']=$cms['uptime']>0?$cms['uptime']:time();
|
||||
|
||||
if(!preg_match('/^([A-Z][a-z0-9]*){3}$/',$cms['app'])){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$codeFmt=strip_phpcode_comment($code);
|
||||
$codeFmt=\util\Funcs::strip_phpcode_comment($code);
|
||||
|
||||
if(!preg_match('/^\s*namespace\s+plugin\\\release\b/im',$codeFmt)){
|
||||
|
||||
|
@ -48,7 +48,7 @@ class ReleaseApp extends BaseModel{
|
|||
$success=true;
|
||||
}else{
|
||||
|
||||
$cms['addtime']=NOW_TIME;
|
||||
$cms['addtime']=time();
|
||||
$this->isUpdate(false)->allowField(true)->save($cms);
|
||||
$cms['id']=$this->id;
|
||||
$success=$cms['id']>0?true:false;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class Rule extends BaseModel{
|
||||
class Rule extends \skycaiji\common\model\BaseModel{
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
namespace skycaiji\admin\model;
|
||||
class Task extends BaseModel{
|
||||
class Task extends \skycaiji\common\model\BaseModel{
|
||||
public function loadConfig($taskData){
|
||||
$config=$taskData['config'];
|
||||
if(empty($config)){
|
||||
|
@ -26,44 +26,90 @@ class Task extends BaseModel{
|
|||
|
||||
static $global_config=null;
|
||||
if(!isset($global_config)){
|
||||
$global_config=$GLOBALS['_sc']['c'];
|
||||
}
|
||||
|
||||
if(!empty($global_config['download_img']['download_img'])){
|
||||
|
||||
if($config['download_img']=='n'){
|
||||
|
||||
$GLOBALS['_sc']['c']['download_img']['download_img']=0;
|
||||
}else{
|
||||
$GLOBALS['_sc']['c']['download_img']['download_img']=1;
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['c']['download_img']['download_img']=0;
|
||||
}
|
||||
|
||||
if(!empty($global_config['proxy']['open'])){
|
||||
|
||||
if($config['proxy']=='n'){
|
||||
|
||||
$GLOBALS['_sc']['c']['proxy']['open']=0;
|
||||
}else{
|
||||
$GLOBALS['_sc']['c']['proxy']['open']=1;
|
||||
}
|
||||
}else{
|
||||
$GLOBALS['_sc']['c']['proxy']['open']=0;
|
||||
$global_config=g_sc('c');
|
||||
}
|
||||
|
||||
static $imgParams=array('img_path','img_url','img_name','name_custom_path','name_custom_name');
|
||||
set_g_sc(['c','caiji','interval'],empty($config['interval'])?g_sc('c_caiji_interval'):$config['interval']);
|
||||
|
||||
set_g_sc(['c','caiji','interval_html'],empty($config['interval_html'])?$global_config['caiji']['interval_html']:$config['interval_html']);
|
||||
|
||||
|
||||
if(empty($config['real_time'])){
|
||||
|
||||
set_g_sc(['c','caiji','real_time'],$global_config['caiji']['real_time']);
|
||||
}else{
|
||||
set_g_sc(['c','caiji','real_time'],$config['real_time']=='n'?0:1);
|
||||
}
|
||||
|
||||
|
||||
if(empty($config['download_img'])){
|
||||
|
||||
set_g_sc(['c','download_img','download_img'],$global_config['download_img']['download_img']);
|
||||
}else{
|
||||
set_g_sc(['c','download_img','download_img'],$config['download_img']=='n'?0:1);
|
||||
}
|
||||
|
||||
|
||||
if(empty($config['img_func'])){
|
||||
|
||||
set_g_sc(['c','download_img','img_func'],$global_config['download_img']['img_func']);
|
||||
}else{
|
||||
|
||||
set_g_sc(['c','download_img','img_func'],$config['img_func']=='n'?'':$config['img_func']);
|
||||
}
|
||||
|
||||
|
||||
if(empty($config['proxy'])){
|
||||
|
||||
set_g_sc(['c','proxy','open'],$global_config['proxy']['open']);
|
||||
}else{
|
||||
set_g_sc(['c','proxy','open'],$config['proxy']=='n'?0:1);
|
||||
}
|
||||
|
||||
|
||||
static $imgParams=array('img_path','img_url','img_name','name_custom_path','name_custom_name','interval_img','img_func_param');
|
||||
foreach ($imgParams as $imgParam){
|
||||
|
||||
$GLOBALS['_sc']['c']['download_img'][$imgParam]=empty($config[$imgParam])?$global_config['download_img'][$imgParam]:$config[$imgParam];
|
||||
set_g_sc(['c','download_img',$imgParam],empty($config[$imgParam])?$global_config['download_img'][$imgParam]:$config[$imgParam]);
|
||||
}
|
||||
if(empty($config['img_name'])){
|
||||
|
||||
$GLOBALS['_sc']['c']['download_img']['name_custom_path']=$global_config['download_img']['name_custom_path'];
|
||||
$GLOBALS['_sc']['c']['download_img']['name_custom_name']=$global_config['download_img']['name_custom_name'];
|
||||
set_g_sc(['c','download_img','name_custom_path'],$global_config['download_img']['name_custom_path']);
|
||||
set_g_sc(['c','download_img','name_custom_name'],$global_config['download_img']['name_custom_name']);
|
||||
}
|
||||
}
|
||||
|
||||
public function backstage_task($taskId){
|
||||
set_g_sc('backstage_task_runtime',time());
|
||||
|
||||
if($this->where('id',$taskId)->count()>0){
|
||||
|
||||
$mcache=\skycaiji\admin\model\CacheModel::getInstance('backstage_task');
|
||||
$mcache->db()->strict(false)->insert(array(
|
||||
'cname'=>$taskId,
|
||||
'dateline'=>g_sc('backstage_task_runtime'),
|
||||
'ctype'=>0,
|
||||
'data'=>''
|
||||
),true);
|
||||
|
||||
if(is_null(g_sc('backstage_task_ids'))){
|
||||
set_g_sc('backstage_task_ids',array());
|
||||
}
|
||||
set_g_sc(['backstage_task_ids',$taskId],$taskId);
|
||||
|
||||
static $registered=false;
|
||||
if(!$registered){
|
||||
$registered=true;
|
||||
register_shutdown_function(function(){
|
||||
|
||||
if(!is_empty(g_sc('backstage_task_ids'))&&is_array(g_sc('backstage_task_ids'))){
|
||||
$mcache=\skycaiji\admin\model\CacheModel::getInstance('backstage_task');
|
||||
$mcache->db()->strict(false)->where('cname','in',g_sc('backstage_task_ids'))->update(array('ctype'=>1,'data'=>time()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
namespace skycaiji\admin\model;
|
||||
class Taskgroup extends BaseModel{
|
||||
class Taskgroup extends \skycaiji\common\model\BaseModel{
|
||||
/**
|
||||
* 获取分级分组
|
||||
*/
|
||||
|
|
|
@ -11,60 +11,11 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class User extends BaseModel{
|
||||
/*用户名是否正确*/
|
||||
public static function right_username($username,$name='username'){
|
||||
$return=array('name'=>$name);
|
||||
if(!preg_match('/^.{3,15}$/i', $username)){
|
||||
$return['msg']=lang('user_error_username');
|
||||
}else{
|
||||
$return['success']=true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
/*邮箱是否正确*/
|
||||
public static function right_email($email,$name='email'){
|
||||
$return=array('name'=>$name,'field'=>'email');
|
||||
if(!preg_match('/^[^\s]+\@([\w\-]+\.){1,}\w+$/i', $email)){
|
||||
$return['msg']=lang('user_error_email');
|
||||
}else{
|
||||
$return['success']=true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
/**
|
||||
* 密码格式是否正确
|
||||
* @param string $pwd
|
||||
* @param string $name
|
||||
* @return Ambigous <multitype:, multitype:string , multitype:boolean string >
|
||||
*/
|
||||
public static function right_pwd($pwd,$name='password'){
|
||||
$return=array('name'=>$name);
|
||||
if(!preg_match('/^[a-zA-Z0-9\`\~\!\@\#\$\%\^\*\(\)\-\_\+\=\|\{\}\[\]\:\;\,\.\?\&\'\"\<\>]{6,30}$/i', $pwd)){
|
||||
$return['msg']=lang('user_error_password');
|
||||
}else{
|
||||
$return['success']=true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
/**
|
||||
* 验证密码是否一致
|
||||
* @param string $pwd
|
||||
* @param string $repwd
|
||||
* @param string $name
|
||||
* @return multitype:string |multitype:boolean string
|
||||
*/
|
||||
public static function right_repwd($pwd,$repwd,$name='repassword'){
|
||||
if($pwd!=$repwd){
|
||||
return array('msg'=>lang('user_error_repassword'),'name'=>$name);
|
||||
}else{
|
||||
return array('success'=>true,'name'=>$name);
|
||||
}
|
||||
}
|
||||
class User extends \skycaiji\common\model\User{
|
||||
/*用户组*/
|
||||
public static function right_groupid($groupid,$name='groupid'){
|
||||
$return=array('name'=>$name);
|
||||
$count=model('Usergroup')->where('id',$groupid)->count();
|
||||
$count=model('admin/Usergroup')->where('id',$groupid)->count();
|
||||
if(empty($count)||$count<=0){
|
||||
$return['msg']=lang('user_error_groupid');
|
||||
}else{
|
||||
|
@ -97,24 +48,6 @@ class User extends BaseModel{
|
|||
}
|
||||
return $check;
|
||||
}
|
||||
/*获取随机盐*/
|
||||
public static function rand_salt($len=20){
|
||||
$salt="QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm";
|
||||
$salt=str_shuffle($salt);
|
||||
if($len>=strlen($salt)){
|
||||
return $salt;
|
||||
}else{
|
||||
return substr($salt,mt_rand(0,strlen($salt)-$len-1),$len);
|
||||
}
|
||||
}
|
||||
/*密码加密*/
|
||||
public static function pwd_encrypt($pwd,$salt=''){
|
||||
$pwd=sha1($pwd);
|
||||
if(!empty($salt)){
|
||||
$pwd.=$salt;
|
||||
}
|
||||
return md5($pwd);
|
||||
}
|
||||
|
||||
/*检测用户名正确且是否存在*/
|
||||
public function checkUsername($username){
|
||||
|
@ -177,6 +110,48 @@ class User extends BaseModel{
|
|||
}
|
||||
return array('success'=>true);
|
||||
}
|
||||
|
||||
/*用户名小写化*/
|
||||
public static function lower_username($username){
|
||||
|
||||
$name=$username?$username:'';
|
||||
$name=trim($name);
|
||||
$name=strtolower($name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
/*生成用户唯一标识*/
|
||||
public function generate_key($userData){
|
||||
$key='';
|
||||
if(!empty($userData)){
|
||||
$username=self::lower_username($userData['username']);
|
||||
$key=md5($username.':'.$userData['password']);
|
||||
}
|
||||
return $key;
|
||||
}
|
||||
|
||||
/*设置登录session*/
|
||||
public function setLoginSession($userData){
|
||||
if(empty($userData)){
|
||||
|
||||
session('user_login',null);
|
||||
session('is_admin',null);
|
||||
}else{
|
||||
|
||||
session('user_login',array(
|
||||
'uid'=>$userData['uid'],
|
||||
'key'=>$this->generate_key($userData)
|
||||
));
|
||||
|
||||
$mUg=model('admin/Usergroup');
|
||||
$isAdmin=null;
|
||||
$userGroup=$mUg->getById($userData['groupid']);
|
||||
if($mUg->is_admin($userGroup)){
|
||||
$isAdmin=true;
|
||||
}
|
||||
session('is_admin',$isAdmin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace skycaiji\admin\model;
|
||||
|
||||
class Usergroup extends BaseModel{
|
||||
class Usergroup extends \skycaiji\common\model\BaseModel{
|
||||
/*获取当前组的下属等级组*/
|
||||
public function get_sub_level($groupid){
|
||||
$group=$this->getById($groupid);
|
||||
|
@ -22,7 +22,7 @@ class Usergroup extends BaseModel{
|
|||
}
|
||||
/*等级限制:判断当前用户组等级小于等于传入的等级*/
|
||||
public function user_level_limit($level){
|
||||
if($GLOBALS['_sc']['user']['group']['level']<=$level){
|
||||
if(g_sc('user','group','level')<=$level){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace skycaiji\admin\validate;
|
|||
use think\Validate;
|
||||
class Taskgroup extends Validate{
|
||||
protected $rule = [
|
||||
'name'=>'require|unique:taskgroup',
|
||||
'name'=>'require|unique:taskgroup',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
|
|
|
@ -12,7 +12,7 @@ function apiop_show_msg(msg,success){
|
|||
var apiName={'install':'安装','uninstall':'卸载','upgrade':'升级'};
|
||||
var apiUrl='{$apiUrl}';
|
||||
var op='{$op}';
|
||||
$.ajax({
|
||||
ajaxOpen({
|
||||
type:'get',
|
||||
dataType:'json',
|
||||
url:apiUrl,
|
||||
|
@ -20,7 +20,7 @@ function apiop_show_msg(msg,success){
|
|||
if(typeof(data)=='object'){
|
||||
if(data.status==1){
|
||||
//接口执行成功
|
||||
$.ajax({
|
||||
ajaxOpen({
|
||||
type:'get',
|
||||
dataType:'json',
|
||||
url:"{:url('App/'.$op.'?success=1&app='.$app)}",
|
||||
|
|
|
@ -18,47 +18,51 @@
|
|||
<a href="javascript:;" id="enable" data-app="{$appData['app']}" data-enable="{$appData['config']['enable']}">{$appData['config']['enable']?'已开启':'已关闭'}</a>
|
||||
</dd>
|
||||
<dt>名称</dt>
|
||||
<dd>{$appData['config']['name']}</dd>
|
||||
<dd>{$appData['config']['name']} </dd>
|
||||
<dt>标识</dt>
|
||||
<dd>{$appData['app']}</dd>
|
||||
<dd>{$appData['app']} </dd>
|
||||
<dt>版本</dt>
|
||||
<dd>
|
||||
{$appData['config']['version']}
|
||||
{$appData['config']['version']}
|
||||
{if $newest_version}
|
||||
<a href="javascript:;" id="newest_version" data-app="{$appData['app']}">新版本{$newest_version}</a>
|
||||
<a href="javascript:;" id="newest_version" data-app="{$appData['app']}">新版本{$newest_version}</a>
|
||||
{/if}
|
||||
</dd>
|
||||
<dt>框架</dt>
|
||||
<dd>{$appData['config']['framework']?($appData['config']['framework'].$appData['config']['framework_version']):'自定义'}</dd>
|
||||
<dd>{$appData['config']['framework']?($appData['config']['framework'].$appData['config']['framework_version']):'自定义'} </dd>
|
||||
{if !empty($appData['config']['phpv'])}
|
||||
<dt>PHP</dt>
|
||||
<dd>最低要求php{$appData['config']['phpv']}版本</dd>
|
||||
<dd>≥ {$appData['config']['phpv']}</dd>
|
||||
{/if}
|
||||
<dt>首页</dt>
|
||||
<dd>
|
||||
<a href="{$appUrl}" target="_blank">应用首页</a>
|
||||
</dd>
|
||||
{if !empty($appData['config']['author'])}
|
||||
<dt>作者</dt>
|
||||
<dd>{$appData['config']['author']}</dd>
|
||||
{/if}
|
||||
{if !empty($provData)}
|
||||
<dt>开发</dt>
|
||||
<dd><a href="{:url('Develop/app?app='.$app)}" class="develop">开发应用</a></dd>
|
||||
{if !empty($storeUrl)}
|
||||
<dt>平台</dt>
|
||||
<dd><a href="{:url('admin/mystore/store?url='.urlencode($provData['url']))}">第三方平台</a></dd>
|
||||
{if $storeUrl==1}
|
||||
<dd><a href="{:url('admin/mystore/store')}">云平台</a></dd>
|
||||
{else/}
|
||||
<dd><a href="{:url('admin/mystore/store?url='.rawurlencode($storeUrl))}">第三方平台</a></dd>
|
||||
{/if}
|
||||
{elseif !empty($appData['config']['website'])}
|
||||
<dt>网站</dt>
|
||||
<dd><a href="{$appData['config']['website']}" target="_blank">作者网站</a></dd>
|
||||
{/if}
|
||||
{if !empty($appData['config']['author'])}
|
||||
<dt>作者</dt>
|
||||
<dd>{$appData['config']['author']} </dd>
|
||||
{/if}
|
||||
{if $appData['config']['desc']}
|
||||
<dt>描述</dt>
|
||||
<dd>{$appData['config']['desc']}</dd>
|
||||
<dd>{$appData['config']['desc']} </dd>
|
||||
{/if}
|
||||
<dt>开发</dt>
|
||||
<dd><a href="{:url('Develop/app?app='.$app)}" class="develop">开发应用</a></dd>
|
||||
</dl>
|
||||
{else /}
|
||||
<div class="manage-wrap">
|
||||
<div class="iframe-loading"><div class="loading"> </div>页面加载中...</div>
|
||||
<div class="iframe-loading"><div class="loading"></div>页面加载中...</div>
|
||||
<iframe src="{$navPacks[$navid]['nav_link']}" id="iframe_main" class="iframe-main" width="100%" height="100%" frameborder="0" scrolling="yes"></iframe>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -12,32 +12,5 @@
|
|||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
//任务列表
|
||||
function win_bk_task_list(op,url){
|
||||
$('#win_bk_'+op).html('<img src="'+window.site_config.pub+'/static/images/load1.gif" />');
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
async:true,
|
||||
url:(url?url:ulink('admin/backstage/backstageTask?op='+op)),
|
||||
success: function (data){
|
||||
if(data.code==1&&data.data){
|
||||
var count=parseInt(data.data.count);
|
||||
$('#win_backstage_task').find('a[href="#win_bk_'+op+'"]').tab('show').find('span').text(count);//显示数量
|
||||
$('#win_bk_'+op).html(data.data.html);
|
||||
}else{
|
||||
$('#win_bk_'+op).html('无任务');
|
||||
}
|
||||
backstageTask();//重置数量
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//加载任务列表
|
||||
$('#win_backstage_task a[href="#win_bk_task0"],#win_backstage_task a[href="#win_bk_task1"]').bind('click',function(){
|
||||
var op=$($(this).attr('href')).attr('data-op');
|
||||
win_bk_task_list(op);
|
||||
});
|
||||
$('#win_backstage_task a[href="#win_bk_task0"]').trigger('click');//默认触发
|
||||
winBackstageTask('init');
|
||||
</script>
|
|
@ -1,56 +1,42 @@
|
|||
{if $list}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover datatable" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>已发布至</th>
|
||||
<th>发布方式</th>
|
||||
<th>添加时间</th>
|
||||
<th class="url">源网址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{php}$curIx=0;{/php}
|
||||
{foreach name="list" item="item"}
|
||||
<tr>
|
||||
<td>{php}$curIx++;{/php}{$curIx}</td>
|
||||
<td class="desc">
|
||||
{if condition="!empty($item['error'])"}
|
||||
失败:{$item['error']}
|
||||
{else /}
|
||||
{$item['target']} {$item['desc']?$item['desc']:''}
|
||||
{/if}
|
||||
</td>
|
||||
<td>{:lang('collected_rele_'.$item['release'])}</td>
|
||||
<td>{:date('Y-m-d H:i:s',$item['addtime'])}</td>
|
||||
<td class="url"><a href="{$item['url']}" target="_blank">{$item['url']}</a></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{if $pagenav}
|
||||
<div class="box-body">{$pagenav}</div>
|
||||
{/if}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover datatable" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>已发布至</th>
|
||||
<th>发布方式</th>
|
||||
<th>添加时间</th>
|
||||
<th class="url">源网址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{php}$curIx=0;{/php}
|
||||
{foreach name="list" item="item"}
|
||||
<tr>
|
||||
<td>{php}$curIx++;{/php}{$curIx}</td>
|
||||
<td class="desc">
|
||||
{if condition="!empty($item['error'])"}
|
||||
失败:{$item['error']}
|
||||
{else /}
|
||||
{$item['target']} {$item['desc']?$item['desc']:''}
|
||||
{/if}
|
||||
</td>
|
||||
<td>{:lang('collected_rele_'.$item['release'])}</td>
|
||||
<td>{:date('Y-m-d H:i:s',$item['addtime'])}</td>
|
||||
<td class="url"><a href="{$item['url']}" target="_blank">{$item['url']}</a></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{if $pagenav}
|
||||
<div class="box-body">{$pagenav}</div>
|
||||
{/if}
|
||||
{else /}
|
||||
<div class="box-body">无数据</div>
|
||||
{/if}
|
||||
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
$('[id^="win_bk_t_list_"] .pagination').addClass('pagination-sm');
|
||||
$('[id^="win_bk_t_list_"] .pagination a').bind('click',function(){
|
||||
var taskId=$(this).parents('[id^="win_bk_t_list_"]').eq(0).attr('data-task-id');
|
||||
if(window.interval_bk_tasks[taskId]){
|
||||
//停止自动刷新
|
||||
clearInterval(window.interval_bk_tasks[taskId]);
|
||||
}
|
||||
win_bk_task_collected(taskId,$(this).attr('href'));
|
||||
return false;
|
||||
});
|
||||
{if $taskStatus}
|
||||
//正在采集任务已完成
|
||||
$('#win_bk_task_list_0').find('a[href="#win_bk_t_list_{$taskId}"]').find('small').text('已结束');
|
||||
{/if}
|
||||
winBackstageTask('init_collected',{taskStatus:'{$taskStatus}',taskId:'{$taskId}'});
|
||||
</script>
|
|
@ -10,7 +10,7 @@
|
|||
({$cacheList[$task['id']]['collected_count']})
|
||||
<small>{$cacheList[$task['id']]['enddate']} 结束 </small>
|
||||
{else /}
|
||||
<small style="color:inherit;"><span class="fa fa-refresh fa-spin"></span></small>
|
||||
<div class="is_loading" style="display:inline;"><div class="loading-sm"></div></div>
|
||||
{/if}
|
||||
</a>
|
||||
</h4>
|
||||
|
@ -18,7 +18,6 @@
|
|||
</div>
|
||||
<div id="win_bk_t_list_{$task['id']}" data-task-id="{$task['id']}" class="panel-collapse collapse">
|
||||
<div class="box-body">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -33,67 +32,5 @@
|
|||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
//任务已采集数据
|
||||
function win_bk_task_collected(taskId,url){
|
||||
$('#win_bk_t_list_'+taskId+' .box-body').html('<img src="'+window.site_config.pub+'/static/images/load1.gif" />');
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'html',
|
||||
async:true,
|
||||
url:(url?url:ulink('admin/backstage/backstageTask?op=collected&tid='+taskId)),
|
||||
success: function (data){
|
||||
$('#win_bk_t_list_'+taskId).html(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(!window.interval_bk_tasks){
|
||||
//定时器全局变量
|
||||
window.interval_bk_tasks={};
|
||||
}
|
||||
|
||||
$('#win_bk_task_list_0 a[data-parent="#win_bk_task_list_0"]').bind('click',function(){
|
||||
var taskId=$($(this).attr('href')).attr('data-task-id');
|
||||
win_bk_task_collected(taskId);//先读取一次
|
||||
//正在采集自动刷新
|
||||
if(window.interval_bk_tasks[taskId]){
|
||||
//先停止
|
||||
clearInterval(window.interval_bk_tasks[taskId]);
|
||||
}
|
||||
window.interval_bk_tasks[taskId]=setInterval(function(){
|
||||
if($('#win_bk_t_list_'+taskId).is(":hidden")){
|
||||
//元素不可见停止刷新
|
||||
clearInterval(window.interval_bk_tasks[taskId]);
|
||||
}else{
|
||||
win_bk_task_collected(taskId);
|
||||
}
|
||||
},3000);
|
||||
});
|
||||
$('#win_bk_task_list_1 a[data-parent="#win_bk_task_list_1"]').bind('click',function(){
|
||||
//已采集任务
|
||||
var taskId=$($(this).attr('href')).attr('data-task-id');
|
||||
win_bk_task_collected(taskId);
|
||||
});
|
||||
|
||||
$('[id^="win_bk_task_list_"] .fa-remove').bind('click',function(){
|
||||
//删除后台任务
|
||||
var obj=$(this);
|
||||
var taskId=$(this).attr('data-task-id');
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
async:true,
|
||||
url:ulink('admin/task/bkdelete?id='+taskId),
|
||||
success: function (data){
|
||||
obj.parents('.panel').remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#win_bk_task_list_{$taskType} .pagination').addClass('pagination-sm');
|
||||
$('#win_bk_task_list_{$taskType} .pagination a').bind('click',function(){
|
||||
var op=$(this).parents('.tab-pane[data-op]').eq(0).attr('data-op');
|
||||
win_bk_task_list(op,$(this).attr('href'));
|
||||
return false;
|
||||
});
|
||||
winBackstageTask('init_list',{taskType:'{$taskType}'});
|
||||
</script>
|
|
@ -4,44 +4,44 @@
|
|||
{/block}
|
||||
{block name="content"}
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-aqua"><i class="icon ion-ios-pulse"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">今日采集</span>
|
||||
<span class="info-box-number">{$runInfo['today_success']|intval}<small>条成功</small></span>
|
||||
<span class="info-box-number">{$runInfo['today_error']|intval}<small>条失败</small></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-aqua"><i class="icon ion-ios-pulse"></i></span>
|
||||
<div class="info-box-content">
|
||||
<div class="info-box-text">今日采集</div>
|
||||
<div class="info-box-number">{$runInfo['today_success']|intval}<div class="tips">条成功</div></div>
|
||||
<div class="info-box-number">{$runInfo['today_error']|intval}<div class="tips">条失败</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-red"><i class="icon ion-stats-bars"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">已采集数据</span>
|
||||
<span class="info-box-number">{$runInfo['total_success']|intval}<small>条成功</small></span>
|
||||
<span class="info-box-number">{$runInfo['total_error']|intval}<small>条失败</small></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-red"><i class="icon ion-stats-bars"></i></span>
|
||||
<div class="info-box-content">
|
||||
<div class="info-box-text">已采集数据</div>
|
||||
<div class="info-box-number">{$runInfo['total_success']|intval}<div class="tips">条成功</div></div>
|
||||
<div class="info-box-number">{$runInfo['total_error']|intval}<div class="tips">条失败</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix visible-sm-block"></div>
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="icon ion-ios-settings-strong"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">任务</span>
|
||||
<span class="info-box-number">{$runInfo['task_auto']|intval}<small>个自动任务</small></span>
|
||||
<span class="info-box-number">{$runInfo['task_other']|intval}<small>个手动任务</small></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="col-lg-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-yellow"><i class="icon ion-load-b"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">自动采集</span>
|
||||
<span class="info-box-number" style="margin-top:7px;">{$runInfo['auto_status']}</span>
|
||||
</div>
|
||||
<span class="info-box-icon bg-green"><i class="icon ion-ios-settings-strong"></i></span>
|
||||
<div class="info-box-content">
|
||||
<div class="info-box-text">任务</div>
|
||||
<div class="info-box-number">{$runInfo['task_auto']|intval}<div class="tips">个自动任务</div></div>
|
||||
<div class="info-box-number">{$runInfo['task_other']|intval}<div class="tips">个手动任务</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-yellow"><i class="icon ion-load-b"></i></span>
|
||||
<div class="info-box-content">
|
||||
<div class="info-box-text">自动采集</div>
|
||||
<div class="info-box-number" style="margin-top:7px;">{$runInfo['auto_status']}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -77,8 +77,10 @@
|
|||
<tr>
|
||||
<th>官方网站</th>
|
||||
<td>
|
||||
<a href="http://bbs.skycaiji.com" target="_blank">社区</a>
|
||||
<a href="http://www.skycaiji.com" target="_blank">官网</a>
|
||||
<ul class="in-line-mg">
|
||||
<li><a href="http://bbs.skycaiji.com" target="_blank">社区</a></li>
|
||||
<li><a href="https://www.skycaiji.com" target="_blank">官网</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -117,10 +119,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if !empty($openBasedir)}
|
||||
<div class="alert alert-warning alert-dismissible" id="box_open_basedir">
|
||||
<button type="button" class="close">×</button>
|
||||
您的网站开启了目录访问限制(open_basedir),受保护的站点目录:{$openBasedir},这会影响到站点目录外的文件读写和CMS程序的访问。如果您未更改图片保存目录(站点目录外)并且cms程序都在站点目录内则可忽略该问题!
|
||||
</div>
|
||||
{/if}
|
||||
{if !empty($systemWarning)}
|
||||
<div class="callout callout-warning">
|
||||
<div class="alert alert-danger">
|
||||
{if !empty($systemWarning['php'])}
|
||||
请开启PHP模块:{:implode(' , ',$systemWarning['php'])}<br/>
|
||||
PHP缺少功能:{:implode(' , ',$systemWarning['php'])}<br/>
|
||||
{/if}
|
||||
{if !empty($systemWarning['path_write'])}
|
||||
请设置可写权限:{:implode(' , ',$systemWarning['path_write'])}<br/>
|
||||
|
@ -130,7 +138,11 @@
|
|||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div id="invalid_list" style="display:none;">
|
||||
<div class="alert alert-danger">
|
||||
功能失效:<div data-box="1" style="display:inline;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<button type="button" id="btn_clear_error" class="btn btn-sm btn-warning" style="padding:2px 10px;">一键清理失败的数据</button>
|
||||
</div>
|
||||
<form id="form_list" method="post" ajax-submit="true" action="{:url('Collected/op')}">
|
||||
{:html_usertoken()}
|
||||
<div class="table-responsive">
|
||||
<table id="list_table" class="table table-hover datatable">
|
||||
<thead>
|
||||
|
@ -65,6 +66,7 @@
|
|||
<!-- /.box -->
|
||||
<div class="list-footer">
|
||||
<form id="form_search" method="post" action="{:url('Collected/list')}" class="form-inline">
|
||||
{:html_usertoken()}
|
||||
<div class="form-group form-group-sm">
|
||||
<label>每页显示</label>
|
||||
<select name="num" class="form-control">
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
collectorEchoMsg('run',{is_backstage:'{$is_backstage}',interval:'{$interval}',server_is_cli:'{$server_is_cli}',differ_seconds:'{$differ_seconds}'});
|
||||
</script>
|
|
@ -1,17 +0,0 @@
|
|||
{if condition="!empty($collData)"}
|
||||
<script src="__PUBLIC__/static/js/admin/store.js?{$Think.config.html_v}"></script>
|
||||
<div>
|
||||
<form id="win_form_save2store" action="https://www.skycaiji.com/client/rule/upload" method="post" target="myModalIframe">
|
||||
<input type="hidden" name="rule" value="{:base64_encode(serialize($collData))}" />
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
/*利用iframe+form post提交*/
|
||||
var formhtml=$('#win_form_save2store').prop("outerHTML")+'<script type="text\/javascript">$("#win_form_save2store").submit()<\/script>';
|
||||
windowStore('正在上传...','',{addonBody:formhtml});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
{else /}
|
||||
规则不存在
|
||||
{/if}
|
|
@ -4,10 +4,12 @@
|
|||
{/block}
|
||||
{block name="content"}
|
||||
<form id="form_coll" class="form-item" method="post" ajax-submit="true" role="form" action="{:url('Collector/set')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="task_id" value="{$taskData['id']}" />
|
||||
<input type="hidden" name="module" value="{$taskData['module']}" />
|
||||
<input type="hidden" name="tab_link" value="{:input('tab_link')}" />
|
||||
<input type="hidden" name="effective" value="" />
|
||||
<input type="hidden" name="effective_edit" value="" />
|
||||
{if input('?easymode')}
|
||||
<input type="hidden" name="easymode" value="1" />
|
||||
{/if}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{if condition="!empty($GLOBALS['_sc']['browser_is_old'])"}
|
||||
<div class="alert alert-error alert-dismissible fade in" role="alert" style="position:fixed;top:0;z-index:9999;width:100%;">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
您的浏览器版本过低,不能完全展现页面效果,请使用谷歌、火狐或IE9及以上版本的浏览器!
|
||||
</div>
|
||||
{/if}
|
|
@ -2,44 +2,5 @@
|
|||
$_WP['title']=$msg;
|
||||
{/php}
|
||||
{include file="common:header_public" /}
|
||||
<style type="text/css">
|
||||
.content-wrapper{background:#fff;}
|
||||
.breadcrumb{display:none!important;}
|
||||
.msg_title{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#2E99D4;
|
||||
margin-top:10px;
|
||||
font:16px "microsoft yahei",Arial,Verdana;
|
||||
font-weight:bold;
|
||||
}
|
||||
.msg_message{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#5C5C5C;
|
||||
font:14px "microsoft yahei",Arial,Verdana;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="hold-transition">
|
||||
|
||||
<div style="text-align:center;padding:100px 0;">
|
||||
<img src="__PUBLIC__/static/images/error.png" />
|
||||
<p class="msg_title">{$msg}</p>
|
||||
<p class="msg_message">{:lang('return_home',array('url'=>$url,'time'=>'<span id="tmv" style="color:red;font-weight:bold;"></span>'))}</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var waitTm={$wait?$wait:'3'};
|
||||
function goHome(){
|
||||
if(waitTm>=1){
|
||||
document.getElementById('tmv').innerHTML=waitTm;
|
||||
waitTm--;
|
||||
setTimeout("goHome()",1000);
|
||||
}else{
|
||||
window.location.href="{$url}";
|
||||
}
|
||||
}
|
||||
goHome();
|
||||
</script>
|
||||
{include file="common@common:message" _success="" /}
|
||||
{include file="common:footer_public" /}
|
|
@ -5,42 +5,5 @@ $_WP['title']=$msg;
|
|||
{block name="cssjs"}
|
||||
{/block}
|
||||
{block name="content"}
|
||||
<style type="text/css">
|
||||
.content-wrapper{background:#fff;}
|
||||
.breadcrumb{display:none!important;}
|
||||
.msg_title{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#2E99D4;
|
||||
margin-top:10px;
|
||||
font:16px "microsoft yahei",Arial,Verdana;
|
||||
font-weight:bold;
|
||||
}
|
||||
.msg_message{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#5C5C5C;
|
||||
font:14px "microsoft yahei",Arial,Verdana;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="text-align:center;padding:50px 0;">
|
||||
<img src="__PUBLIC__/static/images/error.png" />
|
||||
<p class="msg_title">{$msg}</p>
|
||||
<p class="msg_message">{:lang('return_home',array('url'=>$url,'time'=>'<span id="tmv" style="color:red;font-weight:bold;"></span>'))}</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var waitTm={$wait?$wait:'3'};
|
||||
function goHome(){
|
||||
if(waitTm>=1){
|
||||
document.getElementById('tmv').innerHTML=waitTm;
|
||||
waitTm--;
|
||||
setTimeout("goHome()",1000);
|
||||
}else{
|
||||
window.location.href="{$url}";
|
||||
}
|
||||
}
|
||||
goHome();
|
||||
</script>
|
||||
{include file="common@common:message" _success="" /}
|
||||
{/block}
|
|
@ -1,4 +1,4 @@
|
|||
{include file="common:browser_is_old" /}
|
||||
{include file="common@common:browser_is_old" /}
|
||||
{include file="common@common:page_translator" /}
|
||||
<footer class="footer-end">
|
||||
<p>Powered by <a href="https://www.skycaiji.com" target="_blank">蓝天采集器</a></p>
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<title>蓝天采集器 后台管理</title>
|
||||
<title>{:g_sc('p_title')?(g_sc('p_title').' - '):''}蓝天采集器后台管理</title>
|
||||
<meta name="generator" content="skycaiji" />
|
||||
<link rel="icon" href="data:image/ico;base64,aWNv">
|
||||
<!-- Bootstrap 3.3.7 -->
|
||||
<link rel="stylesheet" href="__PUBLIC__/bootstrap/css/bootstrap.min.css?{$Think.config.html_v}">
|
||||
<!-- Font Awesome -->
|
||||
|
@ -45,4 +46,4 @@
|
|||
<script src="__PUBLIC__/static/js/admin.js?{$Think.config.html_v}"></script>
|
||||
<link href="__PUBLIC__/static/css/admin.css?{$Think.config.html_v}" rel="stylesheet" type="text/css">
|
||||
<script type="text/javascript" src="__PUBLIC__/static/js/langs/{php}echo defined('LANG_SET')?LANG_SET:config('DEFAULT_LANG');{/php}.js?{$Think.config.html_v}"></script>
|
||||
<script type="text/javascript">var site_config={root:"__ROOT__",pub:"__PUBLIC__",clientinfo:"{$GLOBALS['_sc']['clientinfo']}"};</script>
|
||||
<script type="text/javascript">var site_config={root:"__ROOT__",pub:"__PUBLIC__",usertoken:"{:g_sc('usertoken')}",clientinfo:"{:g_sc('clientinfo')}"};</script>
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-user"></span>
|
||||
<span>{$GLOBALS['_sc']['user']['username']}</span>
|
||||
<span>{:g_sc('user','username')}</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{:url('User/edit?uid='.$GLOBALS['_sc']['user']['uid'])}">{$Think.lang.user_edit}</a></li>
|
||||
<li><a href="{:url('User/edit?uid='.g_sc('user','uid'))}">{$Think.lang.user_edit}</a></li>
|
||||
<li><a href="{:url('Admin/Index/logout')}">{$Think.lang.logout}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -52,6 +52,7 @@
|
|||
<ul class="treeview-menu">
|
||||
<li><a href="{:url('Admin/Setting/caiji')}"><i class="fa fa-circle-o"></i> {$Think.lang.setting_caiji}</a></li>
|
||||
<li><a href="{:url('Admin/Setting/site')}"><i class="fa fa-circle-o"></i> {$Think.lang.setting_site}</a></li>
|
||||
<li><a href="{:url('Admin/Setting/store')}"><i class="fa fa-circle-o"></i> {$Think.lang.setting_store}</a></li>
|
||||
<li><a href="{:url('Admin/Setting/email')}"><i class="fa fa-circle-o"></i> {$Think.lang.setting_email}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -86,7 +87,7 @@
|
|||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu">
|
||||
<li><a href="{:url('Admin/Mystore/store')}"><i class="fa fa-circle-o"></i> 云平台</a></li>
|
||||
<li><a href="{:url('Admin/Mystore/store')}" target="_blank"><i class="fa fa-circle-o"></i> 云平台</a></li>
|
||||
<li><a href="{:url('Admin/Provider/list')}"><i class="fa fa-circle-o"></i> 第三方</a></li>
|
||||
<li class="treeview menu-open">
|
||||
<a href="#"><i class="fa fa-circle-o"></i> 已下载
|
||||
|
@ -147,7 +148,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li><a href="{:url('Admin/Tool/fileManager')}"><i class="fa fa-circle-o"></i> 文件管理</a></li>
|
||||
<li><a href="{:url('Admin/Tool/json_tree')}" target="_blank"><i class="fa fa-circle-o"></i> JSON解析</a></li>
|
||||
<li><a href="{:url('Admin/Tool/json_tree')}"><i class="fa fa-circle-o"></i> JSON解析</a></li>
|
||||
<li><a href="{:url('Admin/Tool/logs')}"><i class="fa fa-circle-o"></i> 错误日志</a></li>
|
||||
<li class="treeview{$curSubm['checkfile']}{$curSubm['checkdb']}">
|
||||
<a href="#"><i class="fa fa-circle-o"></i> 校验
|
||||
|
@ -183,10 +184,10 @@
|
|||
</aside>
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1>{$GLOBALS['_sc']['p_name']}</h1>
|
||||
<h1>{:g_sc('p_name')}</h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{:url('Admin/Backstage/index')}"><i class="fa fa-dashboard"></i> {$Think.lang.admincp}</a></li>
|
||||
{$GLOBALS['_sc']['p_nav']}
|
||||
{:g_sc('p_nav')}
|
||||
</ol>
|
||||
</section>
|
||||
<section class="content">
|
||||
|
|
|
@ -2,44 +2,5 @@
|
|||
$_WP['title']=$msg;
|
||||
{/php}
|
||||
{include file="common:header_public" /}
|
||||
<style type="text/css">
|
||||
.content-wrapper{background:#fff;}
|
||||
.breadcrumb{display:none!important;}
|
||||
.msg_title{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#2E99D4;
|
||||
margin-top:10px;
|
||||
font:16px "microsoft yahei",Arial,Verdana;
|
||||
font-weight:bold;
|
||||
}
|
||||
.msg_message{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#5C5C5C;
|
||||
font:14px "microsoft yahei",Arial,Verdana;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="hold-transition">
|
||||
|
||||
<div style="text-align:center;padding:100px 0;">
|
||||
<img src="__PUBLIC__/static/images/success.jpg" />
|
||||
<p class="msg_title">{$msg}</p>
|
||||
<p class="msg_message">{:lang('return_home',array('url'=>$url,'time'=>'<span id="tmv" style="color:red;font-weight:bold;"></span>'))}</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var waitTm={$wait?$wait:'3'};
|
||||
function goHome(){
|
||||
if(waitTm>=1){
|
||||
document.getElementById('tmv').innerHTML=waitTm;
|
||||
waitTm--;
|
||||
setTimeout("goHome()",1000);
|
||||
}else{
|
||||
window.location.href="{$url}";
|
||||
}
|
||||
}
|
||||
goHome();
|
||||
</script>
|
||||
{include file="common@common:message" _success="1" /}
|
||||
{include file="common:footer_public" /}
|
|
@ -5,42 +5,5 @@ $_WP['title']=$msg;
|
|||
{block name="cssjs"}
|
||||
{/block}
|
||||
{block name="content"}
|
||||
<style type="text/css">
|
||||
.content-wrapper{background:#fff;}
|
||||
.breadcrumb{display:none!important;}
|
||||
.msg_title{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#2E99D4;
|
||||
margin-top:10px;
|
||||
font:16px "microsoft yahei",Arial,Verdana;
|
||||
font-weight:bold;
|
||||
}
|
||||
.msg_message{
|
||||
line-height:30px;
|
||||
margin-left:20px;
|
||||
color:#5C5C5C;
|
||||
font:14px "microsoft yahei",Arial,Verdana;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="text-align:center;padding:50px 0;">
|
||||
<img src="__PUBLIC__/static/images/success.jpg" />
|
||||
<p class="msg_title">{$msg}</p>
|
||||
<p class="msg_message">{:lang('return_home',array('url'=>$url,'time'=>'<span id="tmv" style="color:red;font-weight:bold;"></span>'))}</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var waitTm={$wait?$wait:'3'};
|
||||
function goHome(){
|
||||
if(waitTm>=1){
|
||||
document.getElementById('tmv').innerHTML=waitTm;
|
||||
waitTm--;
|
||||
setTimeout("goHome()",1000);
|
||||
}else{
|
||||
window.location.href="{$url}";
|
||||
}
|
||||
}
|
||||
goHome();
|
||||
</script>
|
||||
{include file="common@common:message" _success="1" /}
|
||||
{/block}
|
|
@ -16,11 +16,11 @@
|
|||
<span class="skycaiji-b-l">当前元素的xpath:</span>
|
||||
<div class="skycaiji-b-c"><input skycaiji-id="xpath" /></div>
|
||||
<div class="skycaiji-b-r">
|
||||
<a href="javascript:;" skycaiji-id="show-xpath" data-val="1">显示</a> /
|
||||
<a href="javascript:;" title="当前元素的所有属性" skycaiji-id="obj-prop">属性</a> /
|
||||
<a href="javascript:;" title="清理界面" skycaiji-id="obj-clear">清理</a> /
|
||||
<a href="javascript:;" title="当前元素的父元素" skycaiji-id="obj-parent">父元素</a> /
|
||||
<a href="javascript:;" title="当前元素的子元素" skycaiji-id="obj-child">子元素</a>
|
||||
<div style="display:inline;"><a href="javascript:;" skycaiji-id="show-xpath" data-val="1">显示</a> /</div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="当前元素的所有属性" skycaiji-id="obj-prop">属性</a> /</div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="清理界面" skycaiji-id="obj-clear">清理</a> /</div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="当前元素的父元素" skycaiji-id="obj-parent">父元素</a> /</div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="当前元素的子元素" skycaiji-id="obj-child">子元素</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="skycaiji-block">
|
||||
|
|
|
@ -1,34 +1,22 @@
|
|||
{extend name="common:main_clean" /}
|
||||
{block name="cssjs"}
|
||||
<link rel="stylesheet" href="__PUBLIC__/static/css/cpattern_browser.css?{$Think.config.html_v}">
|
||||
<script type="text/javascript" src="__PUBLIC__/jquery/jquery.min.js?{$Think.config.html_v}"></script>
|
||||
<script type="text/javascript" src="__PUBLIC__/static/js/admin/cpattern_browser.js?{$Think.config.html_v}"></script>
|
||||
|
||||
<style type="text/css">
|
||||
#json_tree{width:100%;overflow:hidden;}
|
||||
#json_tree ul{list-style:none;margin:0px;padding:0px;padding-left:20px;}
|
||||
#json_tree li{padding:0;margin:0;}
|
||||
#json_tree .tree{cursor:pointer;margin-left:-16px;margin-right:2px;}
|
||||
|
||||
#json_tree .node{color:#7F007F;}
|
||||
#json_tree .val{}
|
||||
</style>
|
||||
<script src="__PUBLIC__/static/js/admin/json_tree.js?{$Think.config.html_v}"></script>
|
||||
<script src="__PUBLIC__/static/js/admin/tool_json_tree.js?{$Think.config.html_v}"></script>
|
||||
{/block}
|
||||
{block name="content"}
|
||||
<div class="form-group" style="padding-top:10px;">
|
||||
<label>抓取到JSON字符串</label>
|
||||
<textarea id="txt_json" rows="3" class="form-control">{$jsonHtml}</textarea>
|
||||
<textarea id="txt_json" rows="3" class="form-control">{$jsonHtml|htmlspecialchars}</textarea>
|
||||
</div>
|
||||
<label>JSON解析</label>
|
||||
<div id="json_tree"></div>
|
||||
<div id="tool_json_tree"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
$(document).ready(function(){
|
||||
jsonTree.treeId='#json_tree';
|
||||
jsonTree.treeClass='.tree';
|
||||
jsonTree.load($('#txt_json').val());
|
||||
window.tool_json_tree.treeId='#tool_json_tree';
|
||||
window.tool_json_tree.load($('#txt_json').val());
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
</ul>
|
||||
</div>
|
||||
<input type="text" id="browser_url" class="form-control" placeholder="请输入网址" />
|
||||
<input type="hidden" id="browser_urls" />
|
||||
<div class="input-group-addon" style="padding:0;border:0;width:110px;">
|
||||
<select class="form-control" id="browser_source">
|
||||
<option value="">页面类型</option>
|
||||
{foreach $pageSources as $k=>$v}
|
||||
<option value="{$k}"{if $k=='url'} selected="selected"{/if}>{$v}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-primary" type="button" id="btn_browser">分析网页</button>
|
||||
</span>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<form id="form_field" method="post" action="{:url('Cpattern/field')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="is_submit" value="1" />
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
|
@ -37,33 +39,7 @@
|
|||
</div>
|
||||
<div id="c_p_field_module">
|
||||
<div class="c-p-field-module" module="rule">
|
||||
<div class="form-group">
|
||||
<label>规则</label>
|
||||
<div class="input-group">
|
||||
<textarea name="field[rule]" class="form-control" rows="3" placeholder="{$Think.lang.tips_match}">{$field['rule']}</textarea>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'field[rule]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match}" class="blk" onclick="cpMatch('[name=\'field[rule]\']')">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group}" class="blk" onclick="cpMatch('[name=\'field[rule]\']',{group:1})">捕获组</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>拼接成最终内容</label>
|
||||
<div class="input-group">
|
||||
<textarea name="field[rule_merge]" class="form-control" rows="2" placeholder="默认拼接所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn}">{$field['rule_merge']}</textarea>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'field[rule]\']','[name=\'field[rule_merge]\']')">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="checkbox"><label><input type="checkbox" name="field[rule_multi]" value="1" {$field['rule_multi']?'checked="checked"':''}"> 允许匹配多个元素</label></div>
|
||||
<div class="input-group" style="display:none;" id="c_p_field_rule_multi_str">
|
||||
<div class="input-group-addon" style="border-right:0;"><label class="radio-inline"><input type="radio" name="field[rule_multi_type]" value="">拼接为文本</label></div>
|
||||
<input type="text" style="border-left-style:dashed;" name="field[rule_multi_str]" class="form-control" placeholder="多个元素之间分隔符">
|
||||
<div class="input-group-addon"><label class="radio-inline"><input type="radio" name="field[rule_multi_type]" value="loop">循环入库</label></div>
|
||||
</div>
|
||||
{include file="cpattern:field_rule" _type="rule" _name_pre="" _allow_loop="1" /}
|
||||
</div>
|
||||
<div class="c-p-field-module" module="auto" style="display:none;">
|
||||
<div class="form-group" style="text-align:center;">
|
||||
|
@ -89,37 +65,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="c-p-field-module" module="xpath" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label>规则</label>
|
||||
<textarea name="field[xpath]" class="form-control" rows="3">{$field['xpath']}</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>属性</label>
|
||||
<select name="field[xpath_attr]" class="form-control">
|
||||
<option value="">无</option>
|
||||
<option value="innerHtml">innerHtml</option>
|
||||
<option value="outerHtml">outerHtml</option>
|
||||
<option value="text">text</option>
|
||||
<option value="value">value</option>
|
||||
<option value="id">id</option>
|
||||
<option value="class">class</option>
|
||||
<option value="name">name</option>
|
||||
<option value="href">href</option>
|
||||
<option value="src">src</option>
|
||||
<option value="style">style</option>
|
||||
<option value="width">width</option>
|
||||
<option value="height">height</option>
|
||||
<option value="alt">alt</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="field[xpath_attr_custom]" style="margin-top:10px;display:none;">
|
||||
<div class="checkbox"><label><input type="checkbox" name="field[xpath_multi]" value="1" {$field['xpath_multi']?'checked="checked"':''}> 允许匹配多个节点</label></div>
|
||||
<div class="input-group" style="display:none;" id="c_p_field_xpath_multi_str">
|
||||
<div class="input-group-addon" style="border-right:0;"><label class="radio-inline"><input type="radio" name="field[xpath_multi_type]" value="">拼接为文本</label></div>
|
||||
<input type="text" style="border-left-style:dashed;" name="field[xpath_multi_str]" class="form-control" placeholder="多个节点之间分隔符">
|
||||
<div class="input-group-addon"><label class="radio-inline"><input type="radio" name="field[xpath_multi_type]" value="loop">循环入库</label></div>
|
||||
</div>
|
||||
{include file="cpattern:field_rule" _type="xpath" _name_pre="" _allow_loop="1" /}
|
||||
</div>
|
||||
<div class="c-p-field-module" module="words" style="display:none;">
|
||||
<textarea name="field[words]" class="form-control" rows="3">{$field['words']}</textarea>
|
||||
|
@ -137,10 +83,17 @@
|
|||
<div class="input-group-addon">格式</div>
|
||||
<input type="text" name="field[time_format]" class="form-control" />
|
||||
</div>
|
||||
<p class="help-block" id="c_p_field_time_format_list">
|
||||
标签:<a href="javascript:;" data-val="[年]">[年]</a> <a href="javascript:;" data-val="[月]">[月]</a> <a href="javascript:;" data-val="[日]">[日]</a>
|
||||
<a href="javascript:;" data-val="[时]">[时]</a> <a href="javascript:;" data-val="[分]">[分]</a> <a href="javascript:;" data-val="[秒]">[秒]</a>
|
||||
</p>
|
||||
<div class="help-block" id="c_p_field_time_format_list">
|
||||
<span>标签:</span>
|
||||
<ul class="in-line-mg">
|
||||
<li><a href="javascript:;" data-val="[年]">[年]</a></li>
|
||||
<li><a href="javascript:;" data-val="[月]">[月]</a></li>
|
||||
<li><a href="javascript:;" data-val="[日]">[日]</a></li>
|
||||
<li><a href="javascript:;" data-val="[时]">[时]</a></li>
|
||||
<li><a href="javascript:;" data-val="[分]">[分]</a></li>
|
||||
<li><a href="javascript:;" data-val="[秒]">[秒]</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">范围随机</div>
|
||||
<input type="text" name="field[time_start]" class="form-control" placeholder="默认当前时间" />
|
||||
|
@ -159,28 +112,12 @@
|
|||
<div id="c_p_field_merge_list" style="margin-top:5px;"></div>
|
||||
</div>
|
||||
<div class="c-p-field-module" module="json" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label>提取规则</label>
|
||||
<input type="text" name="field[json]" class="form-control" />
|
||||
<p class="help-block">直接输入键名,子元素用:[a][b][c]或a.b.c,通配符*</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox"><label><input type="checkbox" name="field[json_loop]" value="1" {$field['json_loop']?'checked="checked"':''}> 匹配到多个节点允许循环入库</label></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>节点值是数组转换为</label>
|
||||
<select name="field[json_arr]" class="form-control">
|
||||
<option value="implode">字符串</option>
|
||||
<option value="jsonencode">json编码</option>
|
||||
<option value="serialize">序列化</option>
|
||||
</select>
|
||||
<textarea name="field[json_arr_implode]" class="form-control" rows="1" placeholder="输入分隔符" style="margin-top:5px;">{$field['json_arr_implode']}</textarea>
|
||||
</div>
|
||||
{include file="cpattern:field_rule" _type="json" _name_pre="" _allow_loop="1" /}
|
||||
</div>
|
||||
<div class="c-p-field-module" module="extract" style="display:none;">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">选择字段</div>
|
||||
<div class="input-group-addon" style="background:#f4f4f4;">选择字段</div>
|
||||
<select name="field[extract]" class="form-control">
|
||||
<option value="">请选择</option>
|
||||
</select>
|
||||
|
@ -188,7 +125,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">提取内容</div>
|
||||
<div class="input-group-addon" style="background:#f4f4f4;">提取内容</div>
|
||||
<select name="field[extract_module]" class="form-control">
|
||||
<option value="">请选择</option>
|
||||
<option value="cover">第一张图片</option>
|
||||
|
@ -201,63 +138,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="c-p-field-extract-module" extract-module="rule" style="display:none;">
|
||||
<div class="input-group">
|
||||
<textarea name="field[extract_rule]" class="form-control" rows="3" placeholder="{$Think.lang.tips_match_only}">{$field['extract_rule']}</textarea>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'field[extract_rule]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match_only}" class="blk" onclick="cpMatch('[name=\'field[extract_rule]\']',{only:1})">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group_only}" class="blk" onclick="cpMatch('[name=\'field[extract_rule]\']',{only:1,group:1})">捕获组</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block"><b>{:cp_sign('match')}</b>标签可获取匹配的数据,否则获取完全匹配的数据</p>
|
||||
{include file="cpattern:field_rule" _type="rule" _name_pre="extract_" _allow_loop="" /}
|
||||
</div>
|
||||
<div class="c-p-field-extract-module" extract-module="xpath" style="display:none;">
|
||||
<textarea name="field[extract_xpath]" class="form-control" rows="2" placeholder="xpath规则">{$field['extract_xpath']}</textarea>
|
||||
<div class="input-group" style="margin-top:10px;">
|
||||
<div class="input-group-addon">属性</div>
|
||||
<select name="field[extract_xpath_attr]" class="form-control">
|
||||
<option value="">无</option>
|
||||
<option value="innerHtml">innerHtml</option>
|
||||
<option value="outerHtml">outerHtml</option>
|
||||
<option value="text">text</option>
|
||||
<option value="value">value</option>
|
||||
<option value="id">id</option>
|
||||
<option value="class">class</option>
|
||||
<option value="name">name</option>
|
||||
<option value="href">href</option>
|
||||
<option value="src">src</option>
|
||||
<option value="style">style</option>
|
||||
<option value="width">width</option>
|
||||
<option value="height">height</option>
|
||||
<option value="alt">alt</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="field[extract_xpath_attr_custom]" placeholder="自定义属性" style="margin-top:10px;display:none;">
|
||||
{include file="cpattern:field_rule" _type="xpath" _name_pre="extract_" _allow_loop="" /}
|
||||
</div>
|
||||
<div class="c-p-field-extract-module" extract-module="json" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label>提取规则</label>
|
||||
<input type="text" name="field[extract_json]" class="form-control" />
|
||||
<p class="help-block">直接输入键名,子元素用:[a][b][c]或a.b.c,通配符*</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>结果是数组则转换为</label>
|
||||
<select name="field[extract_json_arr]" class="form-control">
|
||||
<option value="implode">字符串</option>
|
||||
<option value="jsonencode">json编码</option>
|
||||
<option value="serialize">序列化</option>
|
||||
</select>
|
||||
<textarea name="field[extract_json_arr_implode]" class="form-control" rows="1" placeholder="输入分隔符" style="margin-top:5px;">{$field['extract_json_arr_implode']}</textarea>
|
||||
</div>
|
||||
{include file="cpattern:field_rule" _type="json" _name_pre="extract_" _allow_loop="" /}
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-p-field-module" module="sign" style="display:none;">
|
||||
<div class="form-group">
|
||||
<textarea name="field[sign]" class="form-control" rows="3" placeholder="填入数据源“提取网址规则”中的{:cp_sign('match')}标签">{$field['sign']}</textarea>
|
||||
<div id="c_p_field_sign_list" style="margin-top:5px;"></div>
|
||||
<p class="help-block"></p>
|
||||
<textarea name="field[sign]" class="form-control" rows="3" placeholder="填入数据源页面中区域规则或网址规则里的{:cp_sign('match')}标签">{$field['sign']}</textarea>
|
||||
<div id="c_p_field_sign_list" style="margin-top:10px;"></div>
|
||||
<p class="help-block">如果区域和网址中存在同名标签,实际获取网址中的标签</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -269,8 +163,8 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
{if condition="$field"}
|
||||
c_pattern.field_op('init',{field:{$field|json_encode}});
|
||||
c_pattern.cpField.init({$field|json_encode});
|
||||
{else /}
|
||||
c_pattern.field_op('init');
|
||||
c_pattern.cpField.init();
|
||||
{/if}
|
||||
</script>
|
|
@ -0,0 +1,102 @@
|
|||
{assign name="_tpl_type" value="[_type]" /}
|
||||
{assign name="_tpl_name_pre" value="[_name_pre]" /}
|
||||
{assign name="_tpl_allow_loop" value="[_allow_loop]" /}
|
||||
|
||||
{if $_tpl_type=='rule'}
|
||||
<div class="form-group">
|
||||
<label>规则</label>
|
||||
<div class="input-group">
|
||||
<textarea name="field[{$_tpl_name_pre}rule]" class="form-control" rows="3" placeholder="{$Think.lang.tips_match}"></textarea>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'field[{$_tpl_name_pre}rule]\']')">{$Think.lang.sign_wildcard}</a></div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'field[{$_tpl_name_pre}rule]\']')">{:cp_sign('match')}</a></div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_group}" class="blk" onclick="cpMatch('[name=\'field[{$_tpl_name_pre}rule]\']',{group:1})">捕获组</a></div>
|
||||
<div>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
<a href="javascript:;" title="提示信息" class="glyphicon glyphicon-info-sign" style="font-size:11px;" onclick="cpRuleTips()"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">规则中无{:cp_sign('match')}标签时,自动将完全匹配的值保存为{:cp_sign('match')}标签以供拼接调用</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>拼接成最终内容</label>
|
||||
<div class="input-group">
|
||||
<textarea name="field[{$_tpl_name_pre}rule_merge]" class="form-control" rows="2" placeholder="默认拼接规则中所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn}"></textarea>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'field[{$_tpl_name_pre}rule]\']','[name=\'field[{$_tpl_name_pre}rule_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="checkbox"><label><input type="checkbox" name="field[{$_tpl_name_pre}rule_multi]" value="1"> 允许匹配多个结果</label></div>
|
||||
<div class="input-group" style="display:none;" id="c_p_field_{$_tpl_name_pre}rule_multi_str">
|
||||
{if $_tpl_allow_loop}
|
||||
<div class="input-group-addon" style="border-right:0;"><label class="radio-inline"><input type="radio" name="field[{$_tpl_name_pre}rule_multi_type]" value="">拼接为文本 <span title="提示信息" class="glyphicon glyphicon-info-sign icon-delimiter-tips" onclick="cpDelimiterTips()"></span></label></div>
|
||||
<input type="text" style="border-left-style:dashed;" name="field[{$_tpl_name_pre}rule_multi_str]" class="form-control" placeholder="多个结果之间分隔符">
|
||||
<div class="input-group-addon"><label class="radio-inline"><input type="radio" name="field[{$_tpl_name_pre}rule_multi_type]" value="loop">循环入库</label></div>
|
||||
{else /}
|
||||
<input type="text" name="field[{$_tpl_name_pre}rule_multi_str]" class="form-control" placeholder="多个结果之间分隔符" />
|
||||
<div class="input-group-addon" style="padding-left:9px;padding-right:9px;"><span title="提示信息" class="glyphicon glyphicon-info-sign icon-delimiter-tips" onclick="cpDelimiterTips()"></span></div>
|
||||
{/if}
|
||||
</div>
|
||||
{elseif $_tpl_type=='xpath' /}
|
||||
<div class="form-group">
|
||||
<label>规则</label>
|
||||
<textarea name="field[{$_tpl_name_pre}xpath]" class="form-control" rows="3" placeholder="xpath规则"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>属性</label>
|
||||
<select name="field[{$_tpl_name_pre}xpath_attr]" class="form-control">
|
||||
<option value="">无</option>
|
||||
<option value="innerHtml">innerHtml</option>
|
||||
<option value="outerHtml">outerHtml</option>
|
||||
<option value="text">text</option>
|
||||
<option value="value">value</option>
|
||||
<option value="id">id</option>
|
||||
<option value="class">class</option>
|
||||
<option value="name">name</option>
|
||||
<option value="href">href</option>
|
||||
<option value="src">src</option>
|
||||
<option value="style">style</option>
|
||||
<option value="width">width</option>
|
||||
<option value="height">height</option>
|
||||
<option value="alt">alt</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
<input type="text" class="form-control" name="field[{$_tpl_name_pre}xpath_attr_custom]" style="margin-top:10px;display:none;">
|
||||
</div>
|
||||
<div class="checkbox"><label><input type="checkbox" name="field[{$_tpl_name_pre}xpath_multi]" value="1"> 允许匹配多个结果</label></div>
|
||||
<div class="input-group" style="display:none;" id="c_p_field_{$_tpl_name_pre}xpath_multi_str">
|
||||
{if $_tpl_allow_loop}
|
||||
<div class="input-group-addon" style="border-right:0;"><label class="radio-inline"><input type="radio" name="field[{$_tpl_name_pre}xpath_multi_type]" value="">拼接为文本 <span title="提示信息" class="glyphicon glyphicon-info-sign icon-delimiter-tips" onclick="cpDelimiterTips()"></span></label></div>
|
||||
<input type="text" style="border-left-style:dashed;" name="field[{$_tpl_name_pre}xpath_multi_str]" class="form-control" placeholder="多个结果之间分隔符">
|
||||
<div class="input-group-addon"><label class="radio-inline"><input type="radio" name="field[{$_tpl_name_pre}xpath_multi_type]" value="loop">循环入库</label></div>
|
||||
{else /}
|
||||
<input type="text" name="field[{$_tpl_name_pre}xpath_multi_str]" class="form-control" placeholder="多个结果之间分隔符" />
|
||||
<div class="input-group-addon" style="padding-left:9px;padding-right:9px;"><span title="提示信息" class="glyphicon glyphicon-info-sign icon-delimiter-tips" onclick="cpDelimiterTips()"></span></div>
|
||||
{/if}
|
||||
</div>
|
||||
{elseif $_tpl_type=='json' /}
|
||||
<div class="form-group">
|
||||
<label>提取规则</label>
|
||||
<input type="text" name="field[{$_tpl_name_pre}json]" class="form-control" />
|
||||
<p class="help-block">直接输入键名,子元素用:[a][b][c]或a.b.c,通配符*</p>
|
||||
</div>
|
||||
{if $_tpl_allow_loop}
|
||||
<div class="form-group">
|
||||
<div class="checkbox"><label><input type="checkbox" name="field[{$_tpl_name_pre}json_loop]" value="1"> 匹配到多个结果允许循环入库</label></div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group">
|
||||
<label>结果是数组则转换为</label>
|
||||
<select name="field[{$_tpl_name_pre}json_arr]" class="form-control">
|
||||
<option value="implode">字符串</option>
|
||||
<option value="jsonencode">json编码</option>
|
||||
<option value="serialize">序列化</option>
|
||||
</select>
|
||||
<div class="input-group" id="c_p_field_{$_tpl_name_pre}json_arr_implode" style="margin-top:5px;">
|
||||
<textarea name="field[{$_tpl_name_pre}json_arr_implode]" class="form-control" rows="1" placeholder="输入分隔符"></textarea>
|
||||
<div class="input-group-addon" style="padding-left:9px;padding-right:9px;"><span title="提示信息" class="glyphicon glyphicon-info-sign icon-delimiter-tips" onclick="cpDelimiterTips()"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -1,114 +1,20 @@
|
|||
<form id="form_level_url" method="post" action="{:url('Cpattern/level_url')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="is_submit" value="1" />
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<label class="control-label">多级名称</label>
|
||||
<label class="control-label">多级页名称</label>
|
||||
<input type="text" class="form-control" name="level_url[name]" placeholder=""/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">获取网址区域</label>
|
||||
<div class="input-group">
|
||||
<textarea name="level_url[area]" class="form-control" rows="3" data-placeholder-json="请输入json规则,默认获取所有字符" data-placeholder-xpath="请输入xpath规则,默认获取整个页面" placeholder="默认整个页面,{$Think.lang.tips_match_only}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="level_url[area_module]" data-rule-input="level_url[area]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="level_url[area_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'level_url[area]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match_only}" onclick="cpMatch('[name=\'level_url[area]\']',{only:1})">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group_only}" class="blk" onclick="cpMatch('[name=\'level_url[area]\']',{only:1,group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="level_url[area_module]">
|
||||
<span data-module=""><b>{:cp_sign('match')}</b>标签可获取匹配的数据,否则获取完全匹配的数据</span>
|
||||
<span data-module="xpath" style="display:none;">获取匹配节点的html代码</span>
|
||||
<span data-module="json" style="display:none;">获取匹配的json字符串</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">提取网址规则</label>
|
||||
<div class="input-group">
|
||||
<textarea class="form-control" name="level_url[url_rule]" rows="3" data-placeholder-xpath="请输入xpath规则,默认获取所有链接" data-placeholder-json="请输入json规则" placeholder="默认获取所有链接并自动保存为[内容]标签以供拼接调用;{$Think.lang.tips_match_url}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="level_url[url_rule_module]" data-rule-input="level_url[url_rule]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="level_url[url_rule_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'level_url[url_rule]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'level_url[url_rule]\']')">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group}" class="blk" onclick="cpMatch('[name=\'level_url[url_rule]\']',{group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="level_url[url_rule_module]">
|
||||
<span data-module="xpath" style="display:none;">XPATH匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="json" style="display:none;">JSON匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">拼接成最终网址</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="level_url[url_merge]" placeholder="默认拼接所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn_url}"/>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'level_url[url_rule]\']','[name=\'level_url[url_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">结果网址过滤</label>
|
||||
<div class="input-group" style="margin-bottom:7px;">
|
||||
<span class="input-group-addon">必须包含</span>
|
||||
<input type="text" name="level_url[url_must]" class="form-control" placeholder="可模糊匹配" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'level_url[url_must]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">不能包含</span>
|
||||
<input type="text" name="level_url[url_ban]" class="form-control" placeholder="可模糊匹配" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'level_url[url_ban]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="cpattern:set_page" _page_type="level_url" /}
|
||||
<div class="form-group form-group-sm">
|
||||
<button type="submit" class="btn btn-primary btn-block">确定</button>
|
||||
</div>
|
||||
<div class="panel panel-default panel-sign-field">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
<a data-toggle="collapse" href="#c_p_sign_field_level_url">将{:cp_sign('match')}添加为字段</a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus add-level-field" data-val="" title="添加"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="c_p_sign_field_level_url" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<div class="c-p-sign-field-list"></div>
|
||||
<p class="help-block">将“提取网址规则”中的{:cp_sign('match')}标签添加为字段</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
{if condition="$level_url"}
|
||||
c_pattern.level_url_op('init',{level_url:{$level_url|json_encode}});
|
||||
c_pattern.cpLevelUrl.init({$level_url|json_encode});
|
||||
{else /}
|
||||
c_pattern.level_url_op('init');
|
||||
c_pattern.cpLevelUrl.init();
|
||||
{/if}
|
||||
</script>
|
|
@ -1,4 +1,5 @@
|
|||
<form id="form_paging_field" method="post" action="{:url('Cpattern/paging_field')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
|
@ -9,9 +10,12 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">分页分隔符</span>
|
||||
<div class="input-group-addon">分页分隔符 <span title="提示信息" class="glyphicon glyphicon-info-sign icon-delimiter-tips" onclick="cpDelimiterTips()"></span></div>
|
||||
<input type="text" name="paging_field[delimiter]" class="form-control" placeholder="选填,内容多页之间插入字符" />
|
||||
</div>
|
||||
{if !empty($isLoop)}
|
||||
<p class="help-block">注意:循环入库已开启,分页分隔符在循环模式中无效仅在非循环模式中将分页内容拼接,循环模式中分页内容以列表形式展现</p>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="form-group form-group-sm">
|
||||
<button type="submit" class="btn btn-primary btn-block">确定</button>
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
<select name="process[module]" class="form-control">
|
||||
<option value="">请选择</option>
|
||||
<option value="html">{$Think.lang.process_module_html}</option>
|
||||
<option value="substr">{$Think.lang.process_module_substr}</option>
|
||||
<option value="insert">{$Think.lang.process_module_insert}</option>
|
||||
<option value="replace">{$Think.lang.process_module_replace}</option>
|
||||
<option value="batch">{$Think.lang.process_module_batch}</option>
|
||||
<option value="tool">{$Think.lang.process_module_tool}</option>
|
||||
<option value="translate">{$Think.lang.process_module_translate}</option>
|
||||
<option value="filter">{$Think.lang.process_module_filter}</option>
|
||||
<option value="if">{$Think.lang.process_module_if}</option>
|
||||
<option value="substr">{$Think.lang.process_module_substr}</option>
|
||||
<option value="translate">{$Think.lang.process_module_translate}</option>
|
||||
<option value="tool">{$Think.lang.process_module_tool}</option>
|
||||
<option value="func">{$Think.lang.process_module_func}</option>
|
||||
<option value="api">{$Think.lang.process_module_api}</option>
|
||||
</select>
|
||||
|
@ -23,6 +24,7 @@
|
|||
{include file="cpattern:process_module" /}
|
||||
{if condition="empty($type)"}
|
||||
<form id="form_process" method="post" action="{:url('Cpattern/process?op=sub')}" style="display:none;">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<div class="panel-group c-p-process-accordion">
|
||||
|
@ -37,11 +39,11 @@
|
|||
<script type="text/javascript">
|
||||
{if condition="empty($type)"}
|
||||
{if condition="!empty($process)"}
|
||||
c_pattern.process_op('init',{process:{$process|json_encode}});
|
||||
c_pattern.cpProcess.init({$process|json_encode},false,false);
|
||||
{else /}
|
||||
c_pattern.process_op('init');
|
||||
c_pattern.cpProcess.init(null,false,false);
|
||||
{/if}
|
||||
{elseif condition="$type eq 'common'" /}
|
||||
c_pattern.process_op('init',{formObj:'#coll_pattern_process'});
|
||||
c_pattern.cpProcess.init(null,true,false);
|
||||
{/if}
|
||||
</script>
|
|
@ -3,6 +3,6 @@
|
|||
</div>
|
||||
<script type="text/javascript">
|
||||
{if condition="$type eq 'common'"}
|
||||
c_pattern.process_op('init',{formObj:'#coll_pattern_process',boxObj:'#c_p_process_load',process:{$process|json_encode}});
|
||||
c_pattern.cpProcess.init({$process|json_encode},true,true);
|
||||
{/if}
|
||||
</script>
|
|
@ -41,6 +41,21 @@
|
|||
<p class="help-block">其它标签可直接输入,用空格或逗号分隔</p>
|
||||
</section>
|
||||
</div>
|
||||
<div class="c-p-process-module" module="insert">
|
||||
<div class="form-group">
|
||||
<label>位置</label>
|
||||
<select data-process="insert:insert_loc" class="form-control">
|
||||
<option value="head">开头</option>
|
||||
<option value="" selected="selected">结尾</option>
|
||||
<option value="rand">随机</option>
|
||||
</select>
|
||||
<p class="help-block" style="display:none;">随机在换行(<p> <br>)标签中插入内容,没有换行标签则在开头、结尾中随机插入</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>内容</label>
|
||||
<textarea data-process="insert:insert_txt" rows="3" class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-p-process-module" module="replace">
|
||||
<div class="input-group">
|
||||
<textarea data-process="replace:replace_from" rows="3" class="form-control"></textarea>
|
||||
|
@ -74,7 +89,9 @@
|
|||
<section>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">条件判断</span>
|
||||
<span class="input-group-addon">
|
||||
<a href="javascript:;" class="glyphicon glyphicon-info-sign p-m-if-info" style="color:#999;"></a>
|
||||
</span>
|
||||
<select data-process="if:if_type" class="form-control">
|
||||
<option value="1">{$Think.lang.p_m_if_1}</option>
|
||||
<option value="2">{$Think.lang.p_m_if_2}</option>
|
||||
|
@ -171,15 +188,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<a href="javascript:;" class="input-group-addon p-m-if-func-info"><span class="glyphicon glyphicon-info-sign"></span></a>
|
||||
<div class="p-m-if-func-tips" style="display:none;">
|
||||
先选择函数(取反可获取函数结果的相反值),默认会传入当前字段值
|
||||
<br>如需传入多个参数,一行一个值,用###表示当前字段值
|
||||
<br>如需扩展系统函数,请在根目录/data/config.php中添加配置:'EXTEND_PROCESS_IF'=>array('PHP函数名'=>'描述')
|
||||
<br>如需扩展插件函数,可以创建<a href="{:url('Develop/func')}" target="_blank">函数插件</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td style="padding:0;padding-top:10px;">
|
||||
<td style="padding:0;padding-top:13px;">
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:11px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:11px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove p-m-if-del" style="font-size:11px;"></a>
|
||||
|
@ -187,13 +198,6 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="help-block">
|
||||
执行顺序:从上至下判断,逻辑符“并且”的优先级高于“或者”<br>
|
||||
例如(字母表示条件):<br>
|
||||
a && b || c && d && e || f || g && h && i && j 等价于<br>
|
||||
(a && b) || (c && d && e) || f || (g && h && i && j)<br>
|
||||
从左到右执行, 括号中的条件都为真时才是真否则为假,整条语句中任意一个括号的结果为真最终结果为真,都为假最终结果为假
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -266,7 +270,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label>传入参数</label>
|
||||
<textarea data-process="func:func_param" rows="2" class="form-control" placeholder="默认传入当前字段的值"></textarea>
|
||||
<textarea data-process="func:func_param" rows="2" class="form-control" data-placeholder="默认传入当前字段的值"></textarea>
|
||||
<div class="help-block">
|
||||
一行一个值,可输入任何内容或
|
||||
<div class="dropdown p-m-func-fields" style="display:inline;">
|
||||
|
@ -278,12 +282,7 @@
|
|||
<li><a href="javascript:;" data-val="###">###表示当前字段</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
,请按函数传参,否则运行出错!<a href="javascript:;" onclick="$(this).parent().find('.p-m-func-tips').show();">扩展函数</a>
|
||||
<div class="p-m-func-tips" style="display:none;">
|
||||
如需扩展系统函数,请在根目录/data/config.php中添加配置:
|
||||
'EXTEND_PROCESS_FUNC'=>array('PHP函数名'=>'描述')
|
||||
<br>如需扩展插件函数,可以创建<a href="{:url('Develop/func')}" target="_blank">函数插件</a>
|
||||
</div>
|
||||
请按函数传参,否则运行出错!<a href="javascript:;" onclick="pluginFuncTips('process')">扩展函数</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -303,15 +302,29 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>请求参数</label>
|
||||
<label>数据编码</label>
|
||||
<div class="input-group input-select-custom">
|
||||
<div class="input-group-btn">
|
||||
<select data-process="api:api_charset" class="form-control">
|
||||
<option value="">utf-8</option>
|
||||
<option value="gbk">gbk</option>
|
||||
<option value="gb2312">gb2312</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" class="form-control" data-process="api:api_charset_custom">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>发送数据</label>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus p-m-api-add" title="添加"></a>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover p-m-api-table" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>值</th>
|
||||
<th style="width:50px;">删除</th>
|
||||
<td>名称</td>
|
||||
<td>值</th>
|
||||
<td style="width:50px;">删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -342,11 +355,39 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>请求头信息</label>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus p-m-api-header-add" title="添加"></a>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover p-m-api-header-table" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td style="width:50px;">删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="p-m-api-header-table-tpl" style="display:none;">
|
||||
<td>
|
||||
<input type="text" data-process="api:api_headers:name:" class="form-control">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" data-process="api:api_headers:val:" class="form-control">
|
||||
</td>
|
||||
<td>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove p-m-api-header-del" style="margin-top:8px;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>提取结果</label>
|
||||
<input type="text" data-process="api:api_json" class="form-control" />
|
||||
<p class="help-block">json规则: a.b.c 通配符 *</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>结果是数组则转换为</label>
|
||||
<select data-process="api:api_json_arr" class="form-control">
|
||||
<option value="implode">字符串</option>
|
||||
|
@ -355,6 +396,21 @@
|
|||
</select>
|
||||
<textarea data-process="api:api_json_implode" class="form-control" rows="1" placeholder="输入分隔符" style="margin-top:5px;"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>调用间隔(毫秒,1000毫秒=1秒)</label>
|
||||
<input type="number" data-process="api:api_interval" class="form-control" />
|
||||
<p class="help-block">如接口有频率限制,可设置间隔时间避免调用过快导致失败</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>失败等待(秒)</label>
|
||||
<input type="number" data-process="api:api_wait" class="form-control" />
|
||||
<p class="help-block">一般情况下调用失败都是频繁请求接口导致被禁用,设置该值等待一段时间让接口恢复正常</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>失败重试</label>
|
||||
<input type="number" data-process="api:api_retry" class="form-control" />
|
||||
<p class="help-block">调用失败重试次数,留空或0表示不重试</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,6 @@
|
|||
<form id="form_relation_url" method="post" action="{:url('Cpattern/relation_url')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="is_submit" value="1" />
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<label class="control-label">关联页名称</label>
|
||||
|
@ -10,92 +12,15 @@
|
|||
<option value="">默认内容页</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">获取网址区域</label>
|
||||
<div class="input-group">
|
||||
<textarea name="relation_url[area]" class="form-control" rows="3" data-placeholder-json="请输入json规则,默认获取所有字符" data-placeholder-xpath="请输入xpath规则,默认获取整个页面" placeholder="默认整个页面,{$Think.lang.tips_match_only}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="relation_url[area_module]" data-rule-input="relation_url[area]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="relation_url[area_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'relation_url[area]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match_only}" onclick="cpMatch('[name=\'relation_url[area]\']',{only:1})">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group_only}" class="blk" onclick="cpMatch('[name=\'relation_url[area]\']',{only:1,group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="relation_url[area_module]">
|
||||
<span data-module=""><b>{:cp_sign('match')}</b>标签可获取匹配的数据,否则获取完全匹配的数据</span>
|
||||
<span data-module="xpath" style="display:none;">获取匹配节点的html代码</span>
|
||||
<span data-module="json" style="display:none;">获取匹配的json字符串</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">提取网址规则</label>
|
||||
<div class="input-group">
|
||||
<textarea class="form-control" name="relation_url[url_rule]" rows="3" data-placeholder-xpath="请输入xpath规则" data-placeholder-json="请输入json规则" placeholder="必须填写规则,{$Think.lang.tips_match_url}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="relation_url[url_rule_module]" data-rule-input="relation_url[url_rule]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="relation_url[url_rule_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'relation_url[url_rule]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'relation_url[url_rule]\']')">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group}" class="blk" onclick="cpMatch('[name=\'relation_url[url_rule]\']',{group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="relation_url[url_rule_module]">
|
||||
<span data-module="xpath" style="display:none;">XPATH匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="json" style="display:none;">JSON匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">拼接成最终网址</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="relation_url[url_merge]" placeholder="默认拼接所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn_url}"/>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'relation_url[url_rule]\']','[name=\'relation_url[url_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{include file="cpattern:set_page" _page_type="relation_url" /}
|
||||
<div class="form-group form-group-sm">
|
||||
<button type="submit" class="btn btn-primary btn-block">确定</button>
|
||||
</div>
|
||||
<div class="panel panel-default panel-sign-field">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
<a data-toggle="collapse" href="#c_p_sign_field_relation_url">将{:cp_sign('match')}添加为字段</a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus add-relation-field" data-val="" title="添加"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="c_p_sign_field_relation_url" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<div class="c-p-sign-field-list"></div>
|
||||
<p class="help-block">将“提取网址规则”中的{:cp_sign('match')}标签添加为字段</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
{if condition="$relation_url"}
|
||||
c_pattern.relation_url_op('init',{relation_url:{$relation_url|json_encode}});
|
||||
c_pattern.cpRelationUrl.init({$relation_url|json_encode});
|
||||
{else /}
|
||||
c_pattern.relation_url_op('init');
|
||||
c_pattern.cpRelationUrl.init();
|
||||
{/if}
|
||||
</script>
|
|
@ -4,11 +4,10 @@
|
|||
<li><a href="#coll_pattern_link" data-toggle="tab">内容页网址</a></li>
|
||||
<li><a href="#coll_pattern_field" data-toggle="tab">获取内容</a></li>
|
||||
{if condition="!empty($collData)"}
|
||||
<li class="dropdown nav-save2store">
|
||||
<li class="dropdown nav-save-rule">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">另存为 <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="{:url('Collector/export?coll_id='.$collData['id'])}" target="_blank">导出至本地</a></li>
|
||||
<li><a href="{:url('Collector/save2store?coll_id='.$collData['id'])}" title="云端存储,保存规则更方便!" onclick="windowModal('保存到云端',$(this).attr('href'));return false;">上传至云端</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
|
@ -22,21 +21,25 @@
|
|||
<input type="text" class="form-control" name="name" value="{$collData['name']}" placeholder="选填">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">网站编码</label>
|
||||
<select name="config[charset]" class="form-control">
|
||||
<option value="">自动检测</option>
|
||||
<option value="utf-8">utf-8</option>
|
||||
<option value="gbk">gbk</option>
|
||||
<option value="gb2312">gb2312</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
<input type="text" class="form-control" name="config[charset_custom]" style="margin-top:10px;display:none;">
|
||||
<label class="control-label">网页编码</label>
|
||||
<div class="input-group input-select-custom">
|
||||
<div class="input-group-btn">
|
||||
<select name="config[charset]" class="form-control">
|
||||
<option value="">自动检测</option>
|
||||
<option value="utf-8">utf-8</option>
|
||||
<option value="gbk">gbk</option>
|
||||
<option value="gb2312">gb2312</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" name="config[charset_custom]" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">自动补全网址</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[url_complete]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_complete]" value="0"> 否</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_complete]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">将所有页面源码中的相对地址转换成绝对地址(包含超链接、图片、JS链接等)</p>
|
||||
</div>
|
||||
|
@ -44,7 +47,7 @@
|
|||
<label class="control-label">网址不排重</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[url_repeat]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_repeat]" value="0"> 否</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_repeat]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">默认将已采集网址排重过滤,选择“是”允许重复采集</p>
|
||||
</div>
|
||||
|
@ -52,7 +55,7 @@
|
|||
<label class="control-label">倒序采集</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[url_reverse]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_reverse]" value="0"> 否</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_reverse]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">以相反的顺序采集内容页网址</p>
|
||||
</div>
|
||||
|
@ -60,10 +63,22 @@
|
|||
<label class="control-label">页面渲染</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[page_render]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[page_render]" value="0"> 否</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[page_render]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">需先配置<a href="{:url('Setting/page_render')}">页面渲染</a>,可自动加载ajax内容,注意:渲染后的html源码与未渲染时的不相同,原先的规则可能会失效!</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">正则匹配模式</label>
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" name="config[regexp_flags][]" value="case"> 区分大小写
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" name="config[regexp_flags][]" value="unicode"> 识别unicode字符
|
||||
</label>
|
||||
</div>
|
||||
<p class="help-block">使用正则规则时进行以上模式匹配,默认情况下仅忽略大小写</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
|
@ -74,67 +89,116 @@
|
|||
</div>
|
||||
<div id="coll_pattern_request_headers" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div class="form-group" style="margin-bottom:0;">
|
||||
<label class="control-label">开启</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][open]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][open]" value="0"> 否</label>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#c_p_request_headers_open" aria-expanded="false">抓取页面</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="c_p_request_headers_open" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">全局开启</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][open]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][open]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">采集起始页、多级页、内容页和关联页时使用请求头信息</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">UserAgent 浏览器标识</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="config[request_headers][useragent]" placeholder="留空不设置" />
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><em style="font-style:normal">常用标识</em> <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu dropdown-menu-right dm-useragent">
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11">谷歌浏览器(pc端)</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1">火狐浏览器</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)">IE8</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)">IE6</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Linux; U; Android 4.0.3; zh-cn; M032 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30">安卓系统</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1">IPhone 6</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1">iPad</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Mobile Safari/537.36">三星 Galaxy S5</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Cookie 缓存数据</label>
|
||||
<input type="text" class="form-control" name="config[request_headers][cookie]" placeholder="留空不设置" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Referer 来源网址</label>
|
||||
<input type="text" class="form-control" name="config[request_headers][referer]" placeholder="留空不设置" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">自定义 <a href="javascript:;" class="glyphicon glyphicon-plus add-request-header" title="添加"></a></label>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered c-p-request-headers" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td>删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="help-block">添加新的或者覆盖已有的请求头信息</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="c_p_request_headers_open" style="display:none;margin-top:15px;">
|
||||
<div class="form-group">
|
||||
<label class="control-label">UserAgent 浏览器标识</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="config[request_headers][useragent]">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><em style="font-style:normal">常用标识</em> <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu dropdown-menu-right dm-useragent">
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11">谷歌浏览器(pc端)</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1">火狐浏览器</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)">IE8</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)">IE6</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Linux; U; Android 4.0.3; zh-cn; M032 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30">安卓系统</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1">IPhone 6</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1">iPad</a></li>
|
||||
<li><a href="javascript:;" data-useragent="Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Mobile Safari/537.36">三星 Galaxy S5</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Cookie 缓存数据</label>
|
||||
<input type="text" class="form-control" name="config[request_headers][cookie]">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Referer 来源网址</label>
|
||||
<input type="text" class="form-control" name="config[request_headers][referer]">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">自定义 <a href="javascript:;" class="glyphicon glyphicon-plus add-request-header" title="添加" style="font-size:12px;"></a></label>
|
||||
<div class="table-responsive">
|
||||
<table class="table c-p-request-headers" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-xs-4">名称</th>
|
||||
<th class="col-xs-6">值</th>
|
||||
<th class="col-xs-2">删除</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">下载图片使用请求头</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][download_img]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][download_img]" value="0"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">下载图片时是否使用该请求头设置</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default" style="margin-bottom:0;">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#c_p_request_headers_img" aria-expanded="false">下载图片</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="c_p_request_headers_img" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">开启</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][img]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][img]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">下载图片时使用请求头</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">使用全局请求头</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][img_use_page]" value="" checked="checked"> 默认</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][img_use_page]" value="y"> 强制使用</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[request_headers][img_use_page]" value="n"> 强制禁用</label>
|
||||
</div>
|
||||
<p class="help-block">默认使用采集器设置»请求头信息»抓取页面中的设置(受全局开启状态影响)</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">自定义 <a href="javascript:;" class="glyphicon glyphicon-plus add-request-header-img" title="添加"></a></label>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered c-p-request-headers-img" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td>删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="help-block">添加新的或者覆盖已有的请求头信息</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -171,14 +235,14 @@
|
|||
<div class="panel panel-default" id="panel_coll_pattern_level_url">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#coll_pattern_level_url" aria-expanded="false">多级网址获取</a>
|
||||
<a data-toggle="collapse" href="#coll_pattern_level_url" aria-expanded="false">多级页网址获取</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="coll_pattern_level_url" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div class="h-title">
|
||||
<span class="is-loading"></span>
|
||||
<label class="control-label">多级网址规则</label>
|
||||
<label class="control-label">多级页规则</label>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus add-level-url" title="添加"></a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
|
@ -187,6 +251,7 @@
|
|||
<tr>
|
||||
<th>级别</th>
|
||||
<th>名称</th>
|
||||
<th class="sign" title="区域和网址规则中的{:cp_sign('match')}标签"><span class="sign-th">{:cp_sign('match')}标签</span></th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -203,161 +268,7 @@
|
|||
<h4 class="panel-title">内容页网址获取</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<!-- coll_pattern_link -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#coll_pattern_link_area" aria-expanded="false" class="collapsed">从选定区域中提取网址</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="coll_pattern_link_area" class="panel-collapse collapse" aria-expanded="false" style="height: 0px;">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">获取网址区域</label>
|
||||
<div class="input-group">
|
||||
<textarea name="config[area]" class="form-control" rows="3" data-placeholder-json="请输入json规则,默认获取所有字符" data-placeholder-xpath="请输入xpath规则,默认获取整个页面" placeholder="默认整个页面,{$Think.lang.tips_match_only}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="config[area_module]" data-rule-input="config[area]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="config[area_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'config[area]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match_only}" onclick="cpMatch('[name=\'config[area]\']',{only:1})">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group_only}" class="blk" onclick="cpMatch('[name=\'config[area]\']',{only:1,group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="config[area_module]">
|
||||
<span data-module=""><b>{:cp_sign('match')}</b>标签可获取匹配的数据,否则获取完全匹配的数据</span>
|
||||
<span data-module="xpath" style="display:none;">获取匹配节点的html代码</span>
|
||||
<span data-module="json" style="display:none;">获取匹配的json字符串</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#coll_pattern_link_match" class="" aria-expanded="true">匹配内容网址</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="coll_pattern_link_match" class="panel-collapse collapse" aria-expanded="false" style="height: 0px;">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">提取网址规则</label>
|
||||
<div class="input-group">
|
||||
<textarea class="form-control" name="config[url_rule]" rows="3" data-placeholder-xpath="请输入xpath规则,默认获取所有链接" data-placeholder-json="请输入json规则" placeholder="默认获取所有链接并自动保存为[内容]标签以供拼接调用;{$Think.lang.tips_match_url}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="config[url_rule_module]" data-rule-input="config[url_rule]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="config[url_rule_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'config[url_rule]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'config[url_rule]\']')">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group}" class="blk" onclick="cpMatch('[name=\'config[url_rule]\']',{group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="config[url_rule_module]">
|
||||
<span data-module="xpath" style="display:none;">XPATH匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="json" style="display:none;">JSON匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">拼接成最终网址</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="config[url_merge]" placeholder="默认拼接所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn_url}"/>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'config[url_rule]\']','[name=\'config[url_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">将{:cp_sign('match')}添加为字段 <a href="javascript:;" class="glyphicon glyphicon-plus add-link-field" data-val="" title="添加" style="font-size:12px;"></a></label>
|
||||
<div id="c_p_sign_field_link">
|
||||
<div class="c-p-sign-field-list"></div>
|
||||
</div>
|
||||
<p class="help-block">将“提取网址规则”中的{:cp_sign('match')}标签添加为字段</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#coll_pattern_link_filter" class="collapsed" aria-expanded="false">结果网址过滤</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="coll_pattern_link_filter" class="panel-collapse collapse in" aria-expanded="true">
|
||||
<div class="panel-body">
|
||||
<div class="input-group" style="margin-bottom:7px;">
|
||||
<span class="input-group-addon">必须包含</span>
|
||||
<input type="text" name="config[url_must]" class="form-control" placeholder="可模糊匹配" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'config[url_must]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">不能包含</span>
|
||||
<input type="text" name="config[url_ban]" class="form-control" placeholder="可模糊匹配" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'config[url_ban]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default" style="margin-bottom:0;">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#coll_pattern_link_post" class="collapsed" aria-expanded="false">POST模式</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="coll_pattern_link_post" class="panel-collapse collapse" aria-expanded="false" style="height: 0px;">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">开启POST</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[url_post]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[url_post]" value="0"> 否</label>
|
||||
</div>
|
||||
<p class="help-block">开启后内容页网址中的get参数将以post形式提交</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">附加参数 <a href="javascript:;" class="glyphicon glyphicon-plus add-url-post" title="添加" style="font-size:12px;"></a></label>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover c-p-url-posts" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-xs-4">名称</th>
|
||||
<th class="col-xs-6">值</th>
|
||||
<th class="col-xs-2">删除</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end coll_pattern_link -->
|
||||
{include file="cpattern:set_page" _page_type="url" /}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -380,6 +291,7 @@
|
|||
<tr>
|
||||
<th>名称</th>
|
||||
<th>从页面中提取</th>
|
||||
<th class="sign" title="区域和网址规则中的{:cp_sign('match')}标签"><span class="sign-th">{:cp_sign('match')}标签</span></th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -391,7 +303,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{if condition="!empty($collData)"}
|
||||
{if condition="!empty($collData['id'])"}
|
||||
<div class="form-group">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-default btn-block dropdown-toggle" type="button" id="dropdownMenuTestSourceUrl" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
|
@ -399,8 +311,8 @@
|
|||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" style="width:100%;text-align:center;" aria-labelledby="dropdownMenuTestSourceUrl">
|
||||
<li><a href="{:url('Cpattern/test?op=source_urls&coll_id='.$collData['id'])}" target="_blank" onclick="windowModal('测试',$(this).attr('href'),{lg:1});return false;">测试抓取内容页网址</a></li>
|
||||
<li><a href="{:url('Cpattern/test?op=cont_url&coll_id='.$collData['id'])}&test=get_relation_urls" target="_blank" onclick="windowModal('测试',$(this).attr('href'),{lg:1});return false;">测试抓取关联页网址</a></li>
|
||||
<li><a href="{:url('cpattern_test/source_urls?coll_id='.$collData['id'])}" target="_blank" onclick="windowModal('测试',$(this).attr('href'),{lg:1});return false;">测试抓取内容页网址</a></li>
|
||||
<li><a href="{:url('cpattern_test/test_url?coll_id='.$collData['id'])}&test=get_relation_urls" target="_blank">测试抓取关联页网址</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -412,7 +324,7 @@
|
|||
<div class="h-title">
|
||||
<label class="control-label">字段列表</label>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus add-field" title="添加"></a>
|
||||
<a href="javascript:;" onclick="c_pattern.add_default_fields()" style="float:right;font-weight:normal;">添加默认</a>
|
||||
<a href="javascript:;" class="add-field-default" style="float:right;font-weight:normal;">添加默认</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover c-p-field-list" style="margin-bottom:0px;">
|
||||
|
@ -463,110 +375,29 @@
|
|||
<label class="control-label">开启分页</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="config[paging][open]" value="1"> 是</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[paging][open]" value="0"> 否</label>
|
||||
<label class="radio-inline"><input type="radio" name="config[paging][open]" value="0" checked="checked"> 否</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="c_p_paging_open" style="display:none;margin-top:15px;">
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
分页内容字段
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus add-paging-field" title="添加"></a>
|
||||
</label>
|
||||
<div id="c_p_paging_fields"></div>
|
||||
<p class="help-block">只有选中的字段才会在分页中获取到内容</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">获取分页区域</label>
|
||||
<div class="input-group">
|
||||
<textarea name="config[paging][area]" class="form-control" rows="3" data-placeholder-json="请输入json规则,默认获取所有字符" data-placeholder-xpath="请输入xpath规则,默认获取整个页面" placeholder="默认整个页面,{$Think.lang.tips_match_only}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="config[paging][area_module]" data-rule-input="config[paging][area]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="config[paging][area_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'config[paging][area]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match_only}" onclick="cpMatch('[name=\'config[paging][area]\']',{only:1})">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group_only}" class="blk" onclick="cpMatch('[name=\'config[paging][area]\']',{only:1,group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="config[paging][area_module]">
|
||||
<span data-module=""><b>{:cp_sign('match')}</b>标签可获取匹配的数据,否则获取完全匹配的数据</span>
|
||||
<span data-module="xpath" style="display:none;">获取匹配节点的html代码</span>
|
||||
<span data-module="json" style="display:none;">获取匹配的json字符串</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">分页链接规则</label>
|
||||
<div class="input-group">
|
||||
<textarea name="config[paging][url_rule]" class="form-control" rows="3" data-placeholder-xpath="请输入xpath规则" data-placeholder-json="请输入json规则" placeholder="必须填写规则,{$Think.lang.tips_match_url}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="config[paging][url_rule_module]" data-rule-input="config[paging][url_rule]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul data-rule-op="config[paging][url_rule_module]" class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'config[paging][url_rule]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'config[paging][url_rule]\']')">{:cp_sign('match')}</a>
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_group}" class="blk" onclick="cpMatch('[name=\'config[paging][url_rule]\']',{group:1})">捕获组</a>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block" data-rule-set="config[paging][url_rule_module]">
|
||||
<span data-module="">规则中无{:cp_sign('match')}标签时,自动将完全匹配的数据保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="xpath" style="display:none;">XPATH匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="json" style="display:none;">JSON匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">拼接成最终分页链接</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="config[paging][url_merge]" placeholder="默认拼接所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn_url}"/>
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'config[paging][url_rule]\']','[name=\'config[paging][url_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">分页网址过滤</label>
|
||||
<div class="input-group" style="margin-bottom:7px;">
|
||||
<span class="input-group-addon">必须包含</span>
|
||||
<input type="text" name="config[paging][url_must]" class="form-control" placeholder="选填,可模糊匹配" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'config[paging][url_must]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">不能包含</span>
|
||||
<input type="text" name="config[paging][url_ban]" class="form-control" placeholder="选填,可模糊匹配" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'config[paging][url_ban]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">最大分页数</label>
|
||||
<input type="number" class="form-control" name="config[paging][max]" value="10">
|
||||
<p class="help-block">填0表示不限制会自动循环抓取到最后一页,为防止出现无限循环的情况,最好设置一个数值</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
分页内容字段
|
||||
<a href="javascript:;" class="glyphicon glyphicon-plus add-paging-field" title="添加"></a>
|
||||
</label>
|
||||
<div id="c_p_paging_fields"></div>
|
||||
<p class="help-block">只有选中的字段才会在分页中获取到内容</p>
|
||||
</div>
|
||||
{include file="cpattern:set_page" _page_type="paging_url" /}
|
||||
<div class="form-group">
|
||||
<label class="control-label">最大分页数</label>
|
||||
<input type="number" class="form-control" name="config[paging][max]" value="10">
|
||||
<p class="help-block">填0表示不限制会自动循环抓取到最后一页,为防止出现无限循环的情况,最好设置一个数值</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if condition="!empty($collData)"}
|
||||
{if condition="!empty($collData['id'])"}
|
||||
<div class="form-group">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-default btn-block dropdown-toggle" type="button" id="dropdownMenuTestUrl" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
|
@ -574,8 +405,8 @@
|
|||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" style="width:100%;text-align:center;" aria-labelledby="dropdownMenuTestUrl">
|
||||
<li><a href="{:url('Cpattern/test?op=cont_url&coll_id='.$collData['id'])}" target="_blank">测试抓取数据</a></li>
|
||||
<li><a href="{:url('Cpattern/test?op=match&coll_id='.$collData['id'])}" target="_blank">模拟匹配数据</a></li>
|
||||
<li><a href="{:url('cpattern_test/test_url?coll_id='.$collData['id'])}" target="_blank">测试抓取数据</a></li>
|
||||
<li><a href="{:url('cpattern_test/match?coll_id='.$collData['id'])}" target="_blank">模拟匹配数据</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -585,33 +416,91 @@
|
|||
<div style="display:none;">
|
||||
<table>
|
||||
<tr id="coll_tpl_request_headers">
|
||||
<td><input type="text" data-name="config[request_headers][custom_names][]" class="form-control" /></td>
|
||||
<td><input type="text" data-name="config[request_headers][custom_vals][]" class="form-control" /></td>
|
||||
<td><input type="text" data-name="config[request_headers][custom_names][]" class="form-control" autocomplete="off" /></td>
|
||||
<td><input type="text" data-name="config[request_headers][custom_vals][]" class="form-control" autocomplete="off" /></td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-request-header"></a></td>
|
||||
</tr>
|
||||
<tr id="coll_tpl_url_posts">
|
||||
<td><input type="text" data-name="config[url_posts][names][]" class="form-control" /></td>
|
||||
<td><input type="text" data-name="config[url_posts][vals][]" class="form-control" /></td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-url-post"></a></td>
|
||||
<tr id="coll_tpl_request_headers_img">
|
||||
<td><input type="text" data-name="config[request_headers][img_names][]" class="form-control" autocomplete="off" /></td>
|
||||
<td><input type="text" data-name="config[request_headers][img_vals][]" class="form-control" autocomplete="off" /></td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-request-header-img"></a></td>
|
||||
</tr>
|
||||
<tr id="coll_tpl_url_web_form">
|
||||
<td><input type="text" data-name="[url_web][form_names][]" class="form-control" autocomplete="off" /></td>
|
||||
<td>
|
||||
<div class="input-group c-p-url-page-signs" data-page-type="" data-input-name="[url_web][form_vals][]">
|
||||
<input type="text" data-name="[url_web][form_vals][]" class="form-control" autocomplete="off" />
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle btn-page-signs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" style="padding:10px;">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>页面</th>
|
||||
<th>区域</th>
|
||||
<th>网址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-url-web-form"></a></td>
|
||||
</tr>
|
||||
<tr id="coll_tpl_url_web_header">
|
||||
<td><input type="text" data-name="[url_web][header_names][]" class="form-control" autocomplete="off" /></td>
|
||||
<td>
|
||||
<div class="input-group c-p-url-page-signs" data-page-type="" data-input-name="[url_web][header_vals][]">
|
||||
<input type="text" data-name="[url_web][header_vals][]" class="form-control" autocomplete="off" />
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle btn-page-signs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" style="padding:10px;">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>页面</th>
|
||||
<th>区域</th>
|
||||
<th>网址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-url-web-header"></a></td>
|
||||
</tr>
|
||||
<tr id="coll_tpl_level_url">
|
||||
<td>第<span class="level">级</span></td>
|
||||
<td><a href="javascript:;" class="name" data-val=""></a></td>
|
||||
<td class="sign"><input type="text" class="form-control signs" readonly="true" /></td>
|
||||
<td>
|
||||
<input type="hidden" data-name="config[level_urls][]" />
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove delete" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" title="上移" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" title="下移" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-copy clone" title="复制" style="font-size:12px;top:0.5px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove delete" title="删除" style="font-size:12px;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="coll_tpl_relation_url">
|
||||
<td><a href="javascript:;" class="name" data-val=""></a></td>
|
||||
<td class="page"></td>
|
||||
<td class="sign"><input type="text" class="form-control signs" readonly="true" /></td>
|
||||
<td>
|
||||
<input type="hidden" data-name="config[relation_urls][]" />
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove delete" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" title="上移" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" title="下移" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-copy clone" title="复制" style="font-size:12px;top:0.5px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove delete" title="删除" style="font-size:12px;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="coll_tpl_field">
|
||||
|
@ -622,9 +511,10 @@
|
|||
<input type="hidden" data-name="config[field_list][]" />
|
||||
<input type="hidden" data-name="config[field_process][]" />
|
||||
<a href="javascript:;" class="field-process">数据处理</a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove field-del" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" title="上移" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" title="下移" style="font-size:12px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-copy field-clone" title="复制" style="font-size:12px;top:0.5px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove field-del" title="删除" style="font-size:12px;"></a>
|
||||
</td>
|
||||
<td><label class="radio-inline"><input type="radio" data-name="config[field_title]">绑定</label></td>
|
||||
</tr>
|
||||
|
@ -638,10 +528,11 @@
|
|||
<input type="text" style="display:none;border-radius:2px;border:1px solid #ccc;line-height:16px;margin-left:2px;padding:1px 1px 1px 2px;" />
|
||||
</div>
|
||||
<div class="panel-title-ops" style="float:right;">
|
||||
<a href="javascript:;" class="glyphicon glyphicon-tags" title="标题"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove" onclick="c_pattern.process_op('delete',{obj:this})"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-tag c-p-process-title" title="标题"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" title="上移"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" title="下移"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-copy c-p-process-clone" title="复制" style="top:0.5px;"></a>
|
||||
<a href="javascript:;" class="glyphicon glyphicon-remove c-p-process-del" title="删除"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -650,18 +541,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="coll_tpl_sign_field" class="c-p-sign-field">
|
||||
<a href="javascript:;" class="field" data-val="" data-source="" title=""></a>
|
||||
<em class="glyphicon glyphicon-remove-circle delete" data-val=""></em>
|
||||
</div>
|
||||
</div>
|
||||
<link href="__PUBLIC__/static/css/jquery.datetimepicker.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="__PUBLIC__/static/js/jquery.datetimepicker.js"></script>
|
||||
<link href="__PUBLIC__/static/css/jquery.datetimepicker.css?{$Think.config.html_v}" rel="stylesheet">
|
||||
<script type="text/javascript" src="__PUBLIC__/static/js/jquery.datetimepicker.js?{$Think.config.html_v}"></script>
|
||||
<script type="text/javascript">
|
||||
var c_pattern=new CollectorPattern('form_coll');
|
||||
var c_pattern=new CollectorPattern();
|
||||
c_pattern.init();
|
||||
|
||||
{if condition="!empty($collData['config'])"}
|
||||
c_pattern.load({$collData['config']|json_encode});
|
||||
{if !empty($collData)}
|
||||
{if empty($collData['config'])}
|
||||
c_pattern.load(null);
|
||||
{else/}
|
||||
c_pattern.load({$collData['config']|json_encode});
|
||||
{/if}
|
||||
{/if}
|
||||
</script>
|
|
@ -0,0 +1,270 @@
|
|||
{assign name="_tpl_page_type" value="[_page_type]" /}
|
||||
|
||||
{php}$_tpl_vars=array('title'=>'页面','is_level_url'=>false,'is_url'=>false,'is_relation_url'=>false,'is_paging_url'=>false);{/php}
|
||||
{if 'level_url'==$_tpl_page_type}
|
||||
{php}$_tpl_vars['title']='多级页';$_tpl_vars['id']='c_p_level_url';$_tpl_vars['name']='level_url';$_tpl_vars['is_level_url']=true;{/php}
|
||||
{elseif 'relation_url'==$_tpl_page_type}
|
||||
{php}$_tpl_vars['title']='关联页';$_tpl_vars['id']='c_p_relation_url';$_tpl_vars['name']='relation_url';$_tpl_vars['is_relation_url']=true;{/php}
|
||||
{elseif 'url'==$_tpl_page_type}
|
||||
{php}$_tpl_vars['title']='内容页';$_tpl_vars['id']='coll_pattern_link';$_tpl_vars['name']='config';$_tpl_vars['is_url']=true;{/php}
|
||||
{elseif 'paging_url'==$_tpl_page_type}
|
||||
{php}$_tpl_vars['title']='分页';$_tpl_vars['id']='coll_pattern_paging';$_tpl_vars['name']='config[paging]';$_tpl_vars['is_paging_url']=true;{/php}
|
||||
{/if}
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#{$_tpl_vars['id']}_area" aria-expanded="false" class="collapsed">从选定区域中提取网址</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div data-module-select="{$_tpl_vars['name']}[area_module]" id="{$_tpl_vars['id']}_area" class="panel-collapse collapse" aria-expanded="false">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">获取网址区域</label>
|
||||
<div class="input-group">
|
||||
<textarea name="{$_tpl_vars['name']}[area]" class="form-control" rows="3" data-placeholder-json="请输入json规则,默认获取所有字符并保存为{:cp_sign('match')}标签以供拼接调用" data-placeholder-xpath="请输入xpath规则,默认获取整个页面并保存为{:cp_sign('match')}标签以供拼接调用" placeholder="默认获取整个页面并保存为{:cp_sign('match')}标签以供拼接调用,{$Think.lang.tips_match_area}"></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="{$_tpl_vars['name']}[area_module]" data-module-input="{$_tpl_vars['name']}[area]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'{$_tpl_vars['name']}[area]\']')">{$Think.lang.sign_wildcard}</a></div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'{$_tpl_vars['name']}[area]\']',{zimu:{$_tpl_vars['is_paging_url']?0:1}})">{:cp_sign('match')}</a></div>
|
||||
<div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_group}" onclick="cpMatch('[name=\'{$_tpl_vars['name']}[area]\']',{group:1,zimu:{$_tpl_vars['is_paging_url']?0:1}})">捕获组</a></div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="提示信息" class="glyphicon glyphicon-info-sign" style="font-size:11px;" onclick="cpRuleTips({$_tpl_vars['is_paging_url']?'':1})"></a></div>
|
||||
</div>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">
|
||||
<span data-module="">规则中无{:cp_sign('match')}标签时,自动将完全匹配的值保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="xpath" style="display:none;">XPATH匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="json" style="display:none;">JSON匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">拼接成最终区域</label>
|
||||
<div class="input-group c-p-url-page-signs" data-page-type="{$_tpl_page_type}" data-input-name="{$_tpl_vars['name']}[area_merge]">
|
||||
<textarea name="{$_tpl_vars['name']}[area_merge]" placeholder="默认拼接区域规则中所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn_area}" class="form-control" rows="2"></textarea>
|
||||
{if !$_tpl_vars['is_paging_url']}
|
||||
<div class="input-group-addon">
|
||||
<a href="javascript:;" role="button" class="dropdown-toggle btn-page-signs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{:cp_sign('match','N')}
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" style="padding:10px;">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>页面</th>
|
||||
<th>区域</th>
|
||||
<th>网址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{else/}
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'{$_tpl_vars['name']}[area]\']','[name=\'{$_tpl_vars['name']}[area_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#{$_tpl_vars['id']}_url" {if $_tpl_vars['is_relation_url']||$_tpl_vars['is_paging_url']}aria-expanded="true"{else/}aria-expanded="false" class="collapsed"{/if}>匹配{$_tpl_vars['title']}网址</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div data-module-select="{$_tpl_vars['name']}[url_rule_module]" id="{$_tpl_vars['id']}_url" {if $_tpl_vars['is_relation_url']||$_tpl_vars['is_paging_url']}class="panel-collapse collapse in" aria-expanded="true"{else/}class="panel-collapse collapse" aria-expanded="false"{/if}>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">提取网址规则</label>
|
||||
<div class="input-group">
|
||||
<textarea class="form-control" name="{$_tpl_vars['name']}[url_rule]" rows="3" {if $_tpl_vars['is_relation_url']||$_tpl_vars['is_paging_url']}data-placeholder-xpath="请输入xpath规则" data-placeholder-json="请输入json规则" placeholder="必须填写规则,{$Think.lang.tips_match_url}"{else/}data-placeholder-xpath="请输入xpath规则,默认获取所有链接并保存为{:cp_sign('match')}标签以供拼接调用" data-placeholder-json="请输入json规则" placeholder="默认获取所有链接并保存为{:cp_sign('match')}标签以供拼接调用,{$Think.lang.tips_match_url}"{/if}></textarea>
|
||||
<div class="input-group-addon iga-rt iga-rt1">
|
||||
<select name="{$_tpl_vars['name']}[url_rule_module]" data-module-input="{$_tpl_vars['name']}[url_rule]" class="slt">
|
||||
<option value="">正则</option>
|
||||
<option value="xpath">xpath</option>
|
||||
<option value="json">json</option>
|
||||
</select>
|
||||
<ul class="op">
|
||||
<li data-module="" style="display:block;">
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" onclick="cpWildcard('[name=\'{$_tpl_vars['name']}[url_rule]\']')">{$Think.lang.sign_wildcard}</a></div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_match}" onclick="cpMatch('[name=\'{$_tpl_vars['name']}[url_rule]\']',{zimu:{$_tpl_vars['is_paging_url']?0:1}})">{:cp_sign('match')}</a></div>
|
||||
<div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="{$Think.lang.tips_sign_group}" onclick="cpMatch('[name=\'{$_tpl_vars['name']}[url_rule]\']',{group:1,zimu:{$_tpl_vars['is_paging_url']?0:1}})">捕获组</a></div>
|
||||
<div style="display:inline;"><a href="javascript:;" title="提示信息" class="glyphicon glyphicon-info-sign" style="font-size:11px;" onclick="cpRuleTips({$_tpl_vars['is_paging_url']?'':1})"></a></div>
|
||||
</div>
|
||||
</li>
|
||||
<li data-module="xpath">xpath语法</li>
|
||||
<li data-module="json">格式 a.b.c<br>通配符 *</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">
|
||||
<span data-module="">规则中无{:cp_sign('match')}标签时,自动将完全匹配的值保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="xpath" style="display:none;">XPATH匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
<span data-module="json" style="display:none;">JSON匹配到的值自动保存为{:cp_sign('match')}标签以供拼接调用</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">拼接成最终网址</label>
|
||||
<div class="input-group c-p-url-page-signs" data-page-type="{$_tpl_page_type}" data-input-name="{$_tpl_vars['name']}[url_merge]">
|
||||
<input type="text" class="form-control" name="{$_tpl_vars['name']}[url_merge]" placeholder="默认拼接网址规则中所有{:cp_sign('match')}标签,{$Think.lang.tips_matchn_url}" autocomplete="off" />
|
||||
{if !$_tpl_vars['is_paging_url']}
|
||||
<div class="input-group-addon">
|
||||
<a href="javascript:;" role="button" class="dropdown-toggle btn-page-signs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{:cp_sign('match','N')}
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" style="padding:10px;">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>页面</th>
|
||||
<th>区域</th>
|
||||
<th>网址</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{else/}
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="调用规则中的标签" onclick="cpMatchN('[name=\'{$_tpl_vars['name']}[url_rule]\']','[name=\'{$_tpl_vars['name']}[url_merge]\']',{def:1})">{:cp_sign('match','N')}</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#{$_tpl_vars['id']}_filter" {if $_tpl_vars['is_relation_url']||$_tpl_vars['is_paging_url']}aria-expanded="false" class="collapsed"{else/}aria-expanded="true"{/if}>结果网址过滤</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="{$_tpl_vars['id']}_filter" {if $_tpl_vars['is_relation_url']||$_tpl_vars['is_paging_url']}class="panel-collapse collapse" aria-expanded="false"{else/}class="panel-collapse collapse in" aria-expanded="true"{/if}>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<div class="input-group" style="margin-bottom:7px;">
|
||||
<span class="input-group-addon">必须包含</span>
|
||||
<input type="text" name="{$_tpl_vars['name']}[url_must]" class="form-control" placeholder="选填,可模糊匹配" autocomplete="off" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'{$_tpl_vars['name']}[url_must]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">不能包含</span>
|
||||
<input type="text" name="{$_tpl_vars['name']}[url_ban]" class="form-control" placeholder="选填,可模糊匹配" autocomplete="off" />
|
||||
<div class="input-group-addon iga-rt">
|
||||
<a href="javascript:;" title="{$Think.lang.tips_sign_wildcard}" class="mgr" onclick="cpWildcard('[name=\'{$_tpl_vars['name']}[url_ban]\']')">{$Think.lang.sign_wildcard}</a>
|
||||
<span title="{$Think.lang.tips_regular}">正则</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if !$_tpl_vars['is_paging_url']}
|
||||
<div class="panel panel-default"{if $_tpl_vars['is_url']} style="margin-bottom:0;"{/if}>
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#{$_tpl_vars['id']}_web" aria-expanded="false" class="collapsed">请求网址</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="{$_tpl_vars['id']}_web" class="panel-collapse collapse" aria-expanded="false">
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="control-label">自定义请求</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="{$_tpl_vars['name']}[url_web][open]" value="1">是</label>
|
||||
<label class="radio-inline"><input type="radio" name="{$_tpl_vars['name']}[url_web][open]" value="0" checked="checked">否</label>
|
||||
</div>
|
||||
<p class="help-block">请求网址时使用自定义设置</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">页面编码</label>
|
||||
<div class="input-group input-select-custom">
|
||||
<div class="input-group-btn">
|
||||
<select name="{$_tpl_vars['name']}[url_web][charset]" class="form-control">
|
||||
<option value="">默认为采集器设置»网页编码</option>
|
||||
<option value="utf-8">utf-8</option>
|
||||
<option value="gbk">gbk</option>
|
||||
<option value="gb2312">gb2312</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="{$_tpl_vars['name']}[url_web][charset_custom]">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>请求方式</label>
|
||||
<select name="{$_tpl_vars['name']}[url_web][form_method]" class="form-control">
|
||||
<option value="">GET</option>
|
||||
<option value="post">POST</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">发送数据 <a href="javascript:;" class="glyphicon glyphicon-plus add-url-web-form" title="添加" style="font-size:12px;"></a></label>
|
||||
<table class="table table-bordered table-hover c-p-url-web-form" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td>删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">使用全局请求头</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="{$_tpl_vars['name']}[url_web][header_global]" value="" checked="checked">默认</label>
|
||||
<label class="radio-inline"><input type="radio" name="{$_tpl_vars['name']}[url_web][header_global]" value="y">强制使用</label>
|
||||
<label class="radio-inline"><input type="radio" name="{$_tpl_vars['name']}[url_web][header_global]" value="n">强制禁用</label>
|
||||
</div>
|
||||
<p class="help-block">默认使用采集器设置»请求头信息»抓取页面中的设置(受全局开启状态影响)</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">请求头信息 <a href="javascript:;" class="glyphicon glyphicon-plus add-url-web-header" title="添加" style="font-size:12px;"></a></label>
|
||||
<table class="table table-bordered table-hover c-p-url-web-header" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td>删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="help-block">添加新的或者覆盖已有的请求头信息</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -6,7 +6,8 @@
|
|||
#form_source .source-params textarea{vertical-align:middle}
|
||||
</style>
|
||||
<form id="form_source" method="post" action="{:url('Cpattern/source')}">
|
||||
<input type="hidden" name="sub" value="1" />
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="is_submit" value="1" />
|
||||
<input type="hidden" name="source[type]" value="custom" />
|
||||
<input type="hidden" name="source[uid]" value="{$source['uid']}" />
|
||||
<ul class="nav nav-tabs c-p-source-tab">
|
||||
|
@ -25,7 +26,7 @@
|
|||
<div class="input-group" style="margin-bottom:10px;">
|
||||
<span class="input-group-addon">网址格式</span>
|
||||
<input type="text" class="form-control" name="source[url]" id="source_url"/>
|
||||
<div class="input-group-addon" style="background:#fff;"><a href="javascript:;" onclick='cpMatch("#source_url",{only:1})'>{:cp_sign('match')}</a></div>
|
||||
<div class="input-group-addon" style="background:#fff;"><a href="javascript:;" id="source_url_sign">{:cp_sign('match')}</a></div>
|
||||
</div>
|
||||
<div class="input-group-addon" ><span class="glyphicon glyphicon-arrow-up"></span> 将 {:cp_sign('match')} 替换成 <span class="glyphicon glyphicon-arrow-down"></span></div>
|
||||
<div class="radio form-inline form-group form-group-sm" source-param="num">
|
||||
|
|
|
@ -1,275 +0,0 @@
|
|||
<style type="text/css">
|
||||
#win_json_tree{width:100%;overflow:hidden;}
|
||||
#win_json_tree ul{list-style:none;margin:0px;padding:0px;padding-left:20px;}
|
||||
#win_json_tree li{padding:0;margin:0;}
|
||||
#win_json_tree .tree{cursor:pointer;margin-left:-16px;margin-right:2px;}
|
||||
|
||||
#win_json_tree .node{color:#7F007F;}
|
||||
#win_json_tree .val{}
|
||||
</style>
|
||||
<script src="__PUBLIC__/static/js/admin/json_tree.js?{$Think.config.html_v}"></script>
|
||||
<div id="win_test_cont_url">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><em class="test-tips" style="font-style:normal">抓取字段</em> <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:;" data-test="get_fields" data-title="抓取字段">抓取字段</a></li>
|
||||
<li><a href="javascript:;" data-test="get_html" data-title="抓取源码">抓取源码</a></li>
|
||||
<li><a href="javascript:;" data-test="elements" data-title="分析网页">分析网页</a></li>
|
||||
<li><a href="javascript:;" data-test="get_paging_urls" data-title="抓取分页">抓取分页</a></li>
|
||||
<li><a href="javascript:;" data-test="get_relation_urls" data-title="抓取关联页">抓取关联页</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{if condition="!empty($url_post)"}
|
||||
<div class="input-group-addon" style="color:green;border-right:0;">POST模式</div>
|
||||
{/if}
|
||||
<input type="text" class="form-control" name="url" value="{$cont_url}" placeholder="输入内容页网址" />
|
||||
<div class="input-group-btn"><button type="button" class="btn btn-default test-sub">确定</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if condition="!empty($input_urls)"}
|
||||
<div id="win_get_fields_input">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">有字段需要从以下数据源抓取页面,请输入网址</div>
|
||||
<div class="panel-body">
|
||||
{if condition="isset($input_urls['source_url'])"}
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">起始页</div>
|
||||
<input type="text" name="source_url" class="form-control" value="{$input_urls['source_url']}" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if condition="is_array($input_urls['level_url'])"}
|
||||
{foreach $input_urls['level_url'] as $level_url}
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">多级页:{$level_url['name']}</div>
|
||||
<input type="text" name="level_{$level_url['level']}" class="form-control" value="{$level_url['url']}" />
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="vals">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
//预览
|
||||
function win_test_view(id){
|
||||
if($('#'+id).next().attr('id')=='ifm_test_view'){
|
||||
//折叠
|
||||
$('#ifm_test_view').remove();
|
||||
}else{
|
||||
$('#ifm_test_view').remove();//删除旧的
|
||||
var html=$('#'+id).val();
|
||||
html=html.replace(/<script[^<>]*>[\s\S]*?<\/script>/ig,'');//去掉脚本代码
|
||||
html=html.replace(/<meta[^<>]*charset[^<>]*>/i,'');//去掉编码
|
||||
var ifm='<iframe id="ifm_test_view" style="width:100%;border:1px solid #ccc;"></iframe>';
|
||||
$('#'+id).after(ifm);
|
||||
$('#ifm_test_view').bind('load',function(){
|
||||
if($("#ifm_test_view").contents().find('body').html().length<=0){
|
||||
//火狐浏览器需要重新赋值
|
||||
$("#ifm_test_view").contents().find('body').html(html);
|
||||
}
|
||||
var iframeObj = document.getElementById('ifm_test_view');
|
||||
var height=(iframeObj.Document?iframeObj.Document.body.scrollHeight:iframeObj.contentDocument.body.offsetHeight);
|
||||
$('#ifm_test_view').attr('height',height+'px');
|
||||
});
|
||||
$("#ifm_test_view").contents().find('body').html(html);
|
||||
}
|
||||
}
|
||||
|
||||
//分析网页
|
||||
function test_elements(id){
|
||||
var cont_url=$('#win_test_cont_url input[name="url"]').val();
|
||||
var url="{:url('Cpattern/browser?coll_id='.$collData['id'].'&url=_url_')}";
|
||||
url=url.replace('_url_',encodeURIComponent(cont_url));
|
||||
window.open(url,'_blank');
|
||||
}
|
||||
//下拉选择
|
||||
$('#win_test_cont_url .dropdown-menu a[data-test]').bind('click',function(){
|
||||
var btnObj=$(this).parents('.dropdown-menu').eq(0).siblings('button.dropdown-toggle').eq(0);
|
||||
btnObj.attr('data-test',$(this).attr('data-test'));
|
||||
btnObj.find('.test-tips').text($(this).attr('data-title'));
|
||||
if($(this).attr('data-test')=='get_fields'){
|
||||
//显示输入数据源网址
|
||||
$('#win_get_fields_input').show();
|
||||
}else{
|
||||
$('#win_get_fields_input').hide();
|
||||
}
|
||||
});
|
||||
|
||||
{if condition="!empty($test)"}
|
||||
$('#win_test_cont_url .dropdown-menu a[data-test="{$test}"]').trigger('click');
|
||||
{/if}
|
||||
|
||||
//测试按钮
|
||||
$('#win_test_cont_url button.test-sub').bind('click',function(){
|
||||
var cont_url=$('#win_test_cont_url input[name="url"]').val();
|
||||
if(!cont_url){
|
||||
toastr.error('请输入网址');
|
||||
}else{
|
||||
$('#win_test_cont_url .vals').html('<img src="'+window.site_config.pub+'/static/images/loading.gif">');
|
||||
var testOp=$('#win_test_cont_url button.dropdown-toggle').attr('data-test');
|
||||
testOp=testOp?testOp:'get_fields';//默认获取字段
|
||||
var url="{:url('Cpattern/test?op=_op_&coll_id='.$collData['id'].'&cont_url=_url_')}";
|
||||
url=url.replace('_op_',testOp).replace('_url_',encodeURIComponent(cont_url));
|
||||
if(testOp=='elements'){
|
||||
test_elements();
|
||||
$('#win_test_cont_url .vals').html('已过滤所有脚本代码,页面所见即所得!');
|
||||
}else if(testOp=='get_html'){
|
||||
//获取源码,防止源代码输出错误
|
||||
$.ajax({
|
||||
type:'get',
|
||||
url:url,
|
||||
dataType:'html',
|
||||
success:function(data){
|
||||
if(htmlIsJson(data)){
|
||||
//AJAX错误提示
|
||||
var json=eval('(' + data + ')');
|
||||
if(json.msg){
|
||||
//json提示
|
||||
$('#win_test_cont_url .vals').html(json.msg);
|
||||
}else{
|
||||
//json源码
|
||||
var html='<label>源码:</label><textarea class="form-control" rows="5">'+data
|
||||
+'</textarea><label style="margin-top:15px;">JSON解析:</label><div id="win_json_tree"></div>';
|
||||
$('#win_test_cont_url .vals').html(html);
|
||||
//加载json树形
|
||||
jsonTree.treeId='#win_json_tree';
|
||||
jsonTree.treeClass='.tree';
|
||||
jsonTree.load(data);
|
||||
}
|
||||
}else{
|
||||
var eleId=generateUUID();
|
||||
data=data.replace(/\</g,'<').replace(/\>/g,'>');//编码
|
||||
var html='<label>源码:</label><a href="javascript:;" onclick="test_elements()">分析网页</a><textarea id="'
|
||||
+eleId+'" class="form-control" rows="20">'+data+'</textarea>';
|
||||
$('#win_test_cont_url .vals').html(html);
|
||||
}
|
||||
}
|
||||
});
|
||||
}else{
|
||||
if(testOp=='get_fields'){
|
||||
//附加数据源网址
|
||||
$('#win_get_fields_input').find('input').each(function(){
|
||||
url+='&'+$(this).attr('name')+'='+encodeURIComponent($(this).val());
|
||||
});
|
||||
//表格标题左右拉伸
|
||||
window.win_test_table_thead_mousedown=null;//点击初始
|
||||
var thEle='.table-test-loop thead th';
|
||||
$('#win_test_cont_url').off('mousedown',thEle).on('mousedown',thEle,function(e){
|
||||
$(this).css('background','#f1f1f1');
|
||||
window.win_test_table_thead_mousedown={
|
||||
table_width:$('#win_test_cont_url .table-test-loop').width(),
|
||||
th_width:$(this).width(),
|
||||
page_x:e.pageX
|
||||
};
|
||||
$(this).off('mousemove').bind('mousemove',function(e){
|
||||
var def=window.win_test_table_thead_mousedown;
|
||||
if(def){
|
||||
var moveWidth=e.pageX-def.page_x;
|
||||
$("#win_test_cont_url .table-test-loop").width(def.table_width+moveWidth);
|
||||
$(this).width(def.th_width+moveWidth);
|
||||
}
|
||||
});
|
||||
$(this).off('mouseout mouseup').bind('mouseout mouseup',function(e){
|
||||
$(this).css('background','');
|
||||
window.win_test_table_thead_mousedown=null;//结束
|
||||
});
|
||||
});
|
||||
}
|
||||
$.ajax({
|
||||
type:'get',
|
||||
url:url,
|
||||
dataType:'json',
|
||||
success:function(data){
|
||||
if(data.code==1){
|
||||
var html='';
|
||||
if(testOp=='get_paging_urls'){
|
||||
html='<div class="page-header"><b>成功抓取到分页链接</b></div><ul>';
|
||||
for(var i in data.data){
|
||||
html+='<li>'+data.data[i]+'</li>';
|
||||
}
|
||||
html+='</ul>';
|
||||
}else if(testOp=='get_fields'){
|
||||
if(data.msg){
|
||||
toastr.success(data.msg);
|
||||
}
|
||||
if(data.data.length>1){
|
||||
//循环数据
|
||||
html+='<div class="table-responsive"><table class="table table-bordered table-hover table-test-loop"><thead><tr><td></td>';
|
||||
var fields=data.data[0];//第一条数据
|
||||
for(var f in fields){
|
||||
html+='<th>'+f+'</th>';
|
||||
}
|
||||
html+='</tr></thead><tbody>';
|
||||
|
||||
var curNum=0;
|
||||
for(var i in data.data){
|
||||
curNum++;
|
||||
var vals=data.data[i];//每条数据
|
||||
html+='<tr><td>'+curNum+'</td>';
|
||||
for(var f in vals){
|
||||
if(vals[f]){
|
||||
html+='<td><input type="text" value="'+(vals[f].replace(/"/g, '"'))+'" /></td>';
|
||||
}else{
|
||||
html+='<td></td>';
|
||||
}
|
||||
}
|
||||
html+='</tr>';
|
||||
}
|
||||
html+='</tbody>';
|
||||
}else{
|
||||
//一条数据
|
||||
var vals=data.data[0];
|
||||
for(var f in vals){
|
||||
var browse='';
|
||||
var eleId=generateUUID();
|
||||
if((/<[^<>]*>/).test(vals[f])){
|
||||
//检测到html代码
|
||||
browse='<a href="javascript:;" onclick="win_test_view(\''+eleId+'\')">预览</a>';
|
||||
}
|
||||
vals[f]=vals[f].replace(/\</g,'<').replace(/\>/g,'>');//编码
|
||||
html+='<label>'+f+':</label>'+browse+'<textarea id="'+eleId+'" class="form-control">'+vals[f]+'</textarea><br>';
|
||||
}
|
||||
}
|
||||
}else if(testOp=='get_relation_urls'){
|
||||
html='<div class="page-header"><b>关联页网址</b></div><ul>';
|
||||
for(var i in data.data){
|
||||
html+='<li>'+i+':'+data.data[i]+'</li>';
|
||||
}
|
||||
html+='</ul>';
|
||||
}
|
||||
$('#win_test_cont_url .vals').html(html);
|
||||
}else{
|
||||
$('#win_test_cont_url .vals').html(data.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//回车测试
|
||||
$('#win_test_cont_url input[name="url"]').bind('keyup',function(event){
|
||||
if(event.keyCode=="13"){
|
||||
$('#win_test_cont_url button').trigger("click");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if($('#win_test_cont_url input[name="url"]').val().length>0){
|
||||
//有网址自动触发
|
||||
$('#win_test_cont_url button').trigger("click");
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
{if condition="!empty($input_urls)"}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">需要从以下页面中抓取数据,请输入网址</div>
|
||||
<div class="panel-body">
|
||||
{if condition="isset($input_urls['source_url'])"}
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-addon">起始页</div>
|
||||
<input type="text" name="source_url" class="form-control" value="{$input_urls['source_url']}" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if condition="is_array($input_urls['level_url'])"}
|
||||
{foreach $input_urls['level_url'] as $level_url}
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-addon">多级页:{$level_url['name']}</div>
|
||||
<input type="text" name="level_{$level_url['level']}" class="form-control" value="{$level_url['url']}" />
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
{if condition="isset($input_urls['url'])"}
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-addon">内容页</div>
|
||||
<input type="text" name="url" class="form-control" value="{$input_urls['url']}" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
|
@ -1,5 +1,6 @@
|
|||
{extend name="common:main" /}
|
||||
{block name="cssjs"}
|
||||
<script type="text/javascript" src="__PUBLIC__/static/js/admin/collector.js?{$Think.config.html_v}"></script>
|
||||
{/block}
|
||||
{block name="content"}
|
||||
<div class="box box-default">
|
||||
|
|
|
@ -1,52 +1,134 @@
|
|||
<div id="win_test_match">
|
||||
<form method="post" action="{:url('Cpattern/test')}">
|
||||
<form method="post" action="{:url('cpattern_test/match')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="coll_id" value="{$collData['id']}" />
|
||||
<input type="hidden" name="op" value="match" />
|
||||
<div class="form-group">
|
||||
<label>输入网址或内容</label>
|
||||
<textarea rows="5" class="form-control" name="content"></textarea>
|
||||
<p class="help-block">网址必须以http://或https://开头</p>
|
||||
<label>模拟类型</label>
|
||||
<select class="form-control" name="input_type">
|
||||
<option value="content">内容</option>
|
||||
<option value="url">网址</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="input_type_content">
|
||||
<div class="form-group">
|
||||
<label>输入内容</label>
|
||||
<textarea rows="5" class="form-control" name="content"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div id="input_type_url" style="display:none;">
|
||||
<div class="form-group">
|
||||
<label>输入网址</label>
|
||||
<input type="text" name="url" class="form-control" />
|
||||
<p class="help-block">网址必须以http://或https://开头</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">页面编码</label>
|
||||
<div class="input-group input-select-custom">
|
||||
<div class="input-group-btn">
|
||||
<select name="charset" class="form-control">
|
||||
<option value="">默认为采集器设置»网页编码</option>
|
||||
<option value="utf-8">utf-8</option>
|
||||
<option value="gbk">gbk</option>
|
||||
<option value="gb2312">gb2312</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="charset_custom">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">请求方式</label>
|
||||
<select name="form_method" class="form-control">
|
||||
<option value="">GET</option>
|
||||
<option value="post">POST</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group form">
|
||||
<label class="control-label">发送数据 <a href="javascript:;" class="glyphicon glyphicon-plus add" title="添加" style="font-size:12px;"></a></label>
|
||||
<table class="table table-bordered table-hover" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td>删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">使用全局请求头</label>
|
||||
<div class="input-group">
|
||||
<label class="radio-inline"><input type="radio" name="header_global" value="" checked="checked">默认</label>
|
||||
<label class="radio-inline"><input type="radio" name="header_global" value="y">强制使用</label>
|
||||
<label class="radio-inline"><input type="radio" name="header_global" value="n">强制禁用</label>
|
||||
</div>
|
||||
<p class="help-block">默认使用采集器设置»请求头信息»抓取页面中的设置(受全局开启状态影响)</p>
|
||||
</div>
|
||||
<div class="form-group header">
|
||||
<label class="control-label">请求头信息 <a href="javascript:;" class="glyphicon glyphicon-plus add" title="添加" style="font-size:12px;"></a></label>
|
||||
<table class="table table-bordered table-hover" style="margin-bottom:0;">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>名称</td>
|
||||
<td>值</td>
|
||||
<td>删除</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="help-block">添加新的或者覆盖已有的请求头信息</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>方式</label>
|
||||
<label>获取方式</label>
|
||||
<select class="form-control" name="type">
|
||||
<option value="rule">规则匹配</option>
|
||||
<option value="rule" checked="checked">规则匹配</option>
|
||||
<option value="xpath">XPath匹配</option>
|
||||
<option value="json">JSON提取</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>输入规则</label>
|
||||
<textarea class="form-control" name="match"></textarea>
|
||||
<p class="help-block">输入所选方式的规则</p>
|
||||
|
||||
<div class="form-group" id="type_rule">
|
||||
{include file="cpattern:field_rule" _type="rule" _name_pre="" _allow_loop="" /}
|
||||
</div>
|
||||
<div class="form-group" id="type_xpath" style="display:none;">
|
||||
{include file="cpattern:field_rule" _type="xpath" _name_pre="" _allow_loop="" /}
|
||||
</div>
|
||||
<div class="form-group" id="type_json" style="display:none;">
|
||||
{include file="cpattern:field_rule" _type="json" _name_pre="" _allow_loop="" /}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-default btn-block">开始测试</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="form-group test-match-val" style="display:none;">
|
||||
<label>匹配结果</label>
|
||||
<textarea rows="3" class="form-control"></textarea>
|
||||
<div><label>匹配结果</label><a href="javascript:;" class="visualize" style="margin-left:5px;display:none;">预览</a></div>
|
||||
<textarea id="test_match_val" rows="10" class="form-control"></textarea>
|
||||
</div>
|
||||
|
||||
<table style="display:none">
|
||||
<tr id="tpl_tr_form">
|
||||
<td><input type="text" name="form_names[]" class="form-control" /></td>
|
||||
<td><input type="text" name="form_vals[]" class="form-control" /></td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete" style="margin-top:8px;"></a></td>
|
||||
</tr>
|
||||
<tr id="tpl_tr_header">
|
||||
<td><input type="text" name="header_names[]" class="form-control" /></td>
|
||||
<td><input type="text" name="header_vals[]" class="form-control" /></td>
|
||||
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete" style="margin-top:8px;"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#win_test_match form').bind('submit',function(){
|
||||
$.ajax({
|
||||
type:'post',
|
||||
url:$(this).attr('action'),
|
||||
dataType:'json',
|
||||
data:$(this).serialize(),
|
||||
success:function(data){
|
||||
if(data.code==1){
|
||||
$('#win_test_match .test-match-val').show().find('textarea').val(data.msg);
|
||||
}else{
|
||||
toastr.error(data.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
'use strict';//严格模式
|
||||
|
||||
$.getScript("__PUBLIC__/static/js/admin/cpattern_test.js?{$Think.config.html_v}", function() {
|
||||
CpTestMatch();
|
||||
});
|
||||
</script>
|
|
@ -1,9 +1,15 @@
|
|||
<style type="text/css">
|
||||
#test_source_urls .source_url{padding:5px;}
|
||||
#test_source_urls p{margin:0;}
|
||||
#test_source_urls ol{padding-left:15px;}
|
||||
#win_test_source_urls .set-test-num{padding:5px;padding-top:0;display:none;}
|
||||
#win_test_source_urls .source_url{padding:5px;}
|
||||
#win_test_source_urls p{margin:0;}
|
||||
#win_test_source_urls ol{padding-left:15px;}
|
||||
</style>
|
||||
<div id="test_source_urls">
|
||||
<div id="win_test_source_urls">
|
||||
<div class="set-test-num">
|
||||
<b>多级页只测试前</b> <input type="number" value="" class="form-control input-sm set-num" style="display:inline;width:40px;height:20px;padding:1px 2px 1px 2px;" /> <b>条数据</b>
|
||||
<button type="button" class="btn btn-default btn-xs set-num-btn">保存</button>
|
||||
</div>
|
||||
|
||||
{if condition="empty($source_urls)"}
|
||||
没有起始页网址
|
||||
{else /}
|
||||
|
@ -45,142 +51,14 @@
|
|||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
var max_num=3;//测试时最多显示数量
|
||||
var url_ajax_requests=new Array();//ajax对象
|
||||
$(document).ready(function(){
|
||||
$('#test_source_urls .source_url').each(function(index){
|
||||
//起始页开始测试
|
||||
{if condition="!$config['source_is_url']"}
|
||||
var source_url=$(this).attr('url');
|
||||
{if condition="!empty($config['level_urls'])"}
|
||||
//有多级
|
||||
if(index<max_num){
|
||||
//测试前几页
|
||||
get_cont_urls(source_url,$(this),1);
|
||||
}
|
||||
{else /}
|
||||
get_cont_urls(source_url,$(this),0);
|
||||
{/if}
|
||||
{/if}
|
||||
});
|
||||
|
||||
//测试
|
||||
$('#test_source_urls').on('click','.cont_ceshi',function(){
|
||||
var test_cont_url="{:url('Cpattern/test?op=cont_url&coll_id='.$collData['id'])}&cont_url=_url_";
|
||||
test_cont_url=test_cont_url.replace('_url_',encodeURIComponent($(this).attr('url')));
|
||||
var urls={};
|
||||
$(this).parents('.source_url').each(function(){
|
||||
var surl=$(this).attr('url');
|
||||
if(surl){
|
||||
if($(this).attr('level')){
|
||||
//是级别
|
||||
urls['level_'+$(this).attr('level')]=surl;
|
||||
}else{
|
||||
//是起始页
|
||||
urls['source_url']=surl;
|
||||
}
|
||||
}
|
||||
});
|
||||
if(urls){
|
||||
//加上多级和起始网址
|
||||
for(var i in urls){
|
||||
test_cont_url+='&'+i+'='+encodeURIComponent(urls[i]);
|
||||
}
|
||||
}
|
||||
window.open(test_cont_url,'_blank');
|
||||
$.getScript("__PUBLIC__/static/js/admin/cpattern_test.js?{$Think.config.html_v}", function() {
|
||||
var cpTestSourceUrls=new CpTestSourceUrls("{$collData['id']}",{$testNum|intval},{$config['source_is_url']?1:0},{:empty($config['level_urls'])?0:1});
|
||||
$(document).ready(function(){
|
||||
cpTestSourceUrls.init();
|
||||
});
|
||||
|
||||
//分析
|
||||
$('#test_source_urls').on('click','.cont_element',function(){
|
||||
if((/\beasymode\s*\=/i).test(window.self.location.href)&&window.top){
|
||||
//简单模式
|
||||
window.top.postMessage('browser_url:'+$(this).attr('url'),'*');
|
||||
}else{
|
||||
var ele_cont_url="{:url('Cpattern/browser?coll_id='.$collData['id'])}&url=_url_";
|
||||
ele_cont_url=ele_cont_url.replace('_url_',encodeURIComponent($(this).attr('url')));
|
||||
window.open(ele_cont_url,'_blank');
|
||||
}
|
||||
});
|
||||
|
||||
//展开收起
|
||||
$('#test_source_urls').on('click','.cont_urls_num a',function(){
|
||||
var status=$(this).attr('status');
|
||||
if(status==1){
|
||||
$(this).html('[展开]');
|
||||
$(this).attr('status',0);
|
||||
$(this).parents('.cont_urls_num').eq(0).siblings('.cont_urls_list').hide();
|
||||
}else{
|
||||
$(this).html('[收起]');
|
||||
$(this).attr('status',1);
|
||||
$(this).parents('.cont_urls_num').eq(0).siblings('.cont_urls_list').show();
|
||||
}
|
||||
});
|
||||
|
||||
//获取网址
|
||||
function get_cont_urls(source_url,curObj,level){
|
||||
if(source_url){
|
||||
curObj.children('.cont_urls_list').html('<img src="'+window.site_config.pub+'/static/images/load1.gif">').show();
|
||||
|
||||
var url="{:url('Cpattern/test?op=cont_urls&coll_id='.$collData['id'].'&source_url=_url_&level=_level_')}";
|
||||
url=url.replace('_url_',encodeURIComponent(source_url)).replace('_level_',level);
|
||||
var url_ajax_request=$.ajax({
|
||||
type:'get',
|
||||
url:url,
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(data.code==1){
|
||||
//内容网址列表
|
||||
var urls=data.data.urls;
|
||||
var list='<ul style="list-style-type:'+(level>0?'decimal':'square')+';padding-left:15px;white-space:normal;overflow-x:scroll;">';
|
||||
if(level>0){
|
||||
//抓取级别网址
|
||||
for(var i in urls){
|
||||
if(i<max_num){
|
||||
//测试前几页
|
||||
list+='<li class="source_url" url="'+urls[i]+'" level="'+level+'"><p><b>抓取第'+level+'级页面 “'+data.data.levelName+'”:</b>'+urls[i]+'</p><p class="cont_urls_num"></p><div class="cont_urls_list"></div></li>';
|
||||
}
|
||||
}
|
||||
list+='</ul>';
|
||||
|
||||
curObj.children('.cont_urls_list').html(list).show();
|
||||
curObj.children('.cont_urls_num').html('获取到'+urls.length+'条网址'+(urls.length>max_num?'(只测试前'+max_num+'条)':'')+' <a href="javascript:;" status="1">[收起]</a>');
|
||||
|
||||
curObj.children('.cont_urls_list').find('.source_url').each(function(){
|
||||
var obj=$(this);
|
||||
get_cont_urls(obj.attr('url'),obj,data.data.nextLevel);//抓取下一级或内容页
|
||||
});
|
||||
|
||||
}else{
|
||||
//无级别,显示测试网址
|
||||
for(var i in urls){
|
||||
list+='<li>[<a href="javascript:;" class="cont_ceshi" url="'+urls[i]+'">测试</a>] '
|
||||
+'[<a href="javascript:;" class="cont_element" url="'+urls[i]+'">分析</a>] '+urls[i]+'</li>';
|
||||
}
|
||||
list+='</ul>';
|
||||
|
||||
//没有下一级
|
||||
curObj.children('.cont_urls_list').html(list).hide();
|
||||
curObj.children('.cont_urls_num').html('获取到'+urls.length+'条网址 <a href="javascript:;" status="0">[展开]</a>');
|
||||
}
|
||||
}else{
|
||||
//错误信息
|
||||
curObj.children('.cont_urls_list').html('<span style="color:red">'+data.msg+'</span>').show();
|
||||
}
|
||||
},
|
||||
dataType:'json'
|
||||
});
|
||||
window.url_ajax_requests.push(url_ajax_request);
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#myModal').on('hide.bs.modal', function (e) {
|
||||
if(window.url_ajax_requests){
|
||||
//退出时清除所有ajax请求
|
||||
for(var i in window.url_ajax_requests){
|
||||
window.url_ajax_requests[i].abort();//终止ajax
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -1,10 +1,10 @@
|
|||
{extend name="common:main" /}
|
||||
{block name="cssjs"}
|
||||
{/block}
|
||||
{block name="content"}
|
||||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
{include file="cpattern:test_cont_url_ajax" /}
|
||||
</div>
|
||||
</div>
|
||||
{extend name="common:main" /}
|
||||
{block name="cssjs"}
|
||||
{/block}
|
||||
{block name="content"}
|
||||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
{include file="cpattern:test_test_url_ajax" /}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
|
@ -0,0 +1,43 @@
|
|||
<style type="text/css">
|
||||
#win_input_urls>.panel{margin-bottom:10px;}
|
||||
</style>
|
||||
<div id="win_test_url">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><em class="test-tips" style="font-style:normal">抓取字段</em> <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:;" data-test="get_fields" data-title="抓取字段">抓取字段</a></li>
|
||||
<li><a href="javascript:;" data-test="get_signs" data-title="内容标签">内容标签</a></li>
|
||||
<li><a href="javascript:;" data-test="get_html" data-title="抓取源码">抓取源码</a></li>
|
||||
<li><a href="javascript:;" data-test="get_elements" data-title="分析网页">分析网页</a></li>
|
||||
<li><a href="javascript:;" data-test="get_paging_urls" data-title="抓取分页">抓取分页</a></li>
|
||||
<li><a href="javascript:;" data-test="get_relation_urls" data-title="抓取关联页">抓取关联页</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="test_url" value="{$test_url}" placeholder="输入内容页网址" />
|
||||
<div class="input-group-addon test-page-sources" style="padding:0;border:0;width:110px;display:none;">
|
||||
<select class="form-control" name="page_source">
|
||||
<option value="">页面类型</option>
|
||||
{foreach $pageSources as $k=>$v}
|
||||
<option value="{$k}"{if $k=='url'} selected="selected"{/if}>{$v}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group-btn"><button type="button" class="btn btn-default test-sub">确定</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="url_params" value="{$urlParams}" />
|
||||
<div id="win_input_urls" style="display:none;"></div>
|
||||
<div class="field-vals"></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
'use strict';//严格模式
|
||||
|
||||
$.getScript("__PUBLIC__/static/js/admin/cpattern_test.js?{$Think.config.html_v}", function() {
|
||||
var cpTestUrl=new CpTestUrl("{$collData['id']}","{$test}");
|
||||
$(document).ready(function(){
|
||||
cpTestUrl.init();
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -6,6 +6,7 @@
|
|||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
<form id="form_app" method="post" ajax-submit="true" action="{:url('Admin/Develop/app')}">
|
||||
{:html_usertoken()}
|
||||
{if !empty($appData)}
|
||||
<input type="hidden" name="edit" value="1" />
|
||||
<input type="hidden" name="app" value="{$appData['app']}" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<form id="win_form_pack" method="post" action="{:url('Develop/appAddPack')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<label>名称</label>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<form id="win_form_param" method="post" action="{:url('Develop/cmsAddParam')}">
|
||||
{:html_usertoken()}
|
||||
<input type="hidden" name="objid" value="{$objid}" />
|
||||
<div class="form-group">
|
||||
<label>变量名(英文)</label>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
<form id="form_func" method="post" ajax-submit="true" action="{:url('Admin/Develop/func')}">
|
||||
{:html_usertoken()}
|
||||
{if !empty($funcClass)}
|
||||
<input type="hidden" name="edit" value="1" />
|
||||
<input type="hidden" name="app" value="{$funcClass['app']}" />
|
||||
|
@ -18,7 +19,6 @@
|
|||
<button type="button" class="btn btn-default btn-block dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">插件另存为 <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu" style="width:100%;text-align:center;background:#f4f4f4;">
|
||||
<li><a href="{:url('Admin/Develop/export?type=func&app='.$funcClass['app'])}" target="_blank">导出至本地</a></li>
|
||||
<li><a href="{:url('Admin/Develop/save2store?type=func&app='.$funcClass['app'])}" title="云端存储,保存插件更方便!" onclick="windowModal('保存到云端',$(this).attr('href'));return false;">上传至云端</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
<form id="form_cms" method="post" ajax-submit="true" action="{:url('Admin/Develop/releaseCms')}">
|
||||
{:html_usertoken()}
|
||||
{if condition="$config['is_edit']"}
|
||||
{if $is_old_plugin}
|
||||
<div class="alert alert-error">
|
||||
<div class="alert alert-danger">
|
||||
{:lang('release_upgrade')}
|
||||
</div>
|
||||
{else/}
|
||||
|
@ -21,7 +22,6 @@
|
|||
<button type="button" class="btn btn-default btn-block dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">插件另存为 <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu" style="width:100%;text-align:center;background:#f4f4f4;">
|
||||
<li><a href="{:url('Admin/Develop/export?type=release&app='.$config['app'])}" target="_blank">导出至本地</a></li>
|
||||
<li><a href="{:url('Admin/Develop/save2store?type=release&app='.$config['app'])}" title="云端存储,保存插件更方便!" onclick="windowModal('保存到云端',$(this).attr('href'));return false;">上传至云端</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>插件功能标识</label>
|
||||
<label>功能标识</label>
|
||||
<input type="text" name="identifier" class="form-control">
|
||||
<p class="help-block">表示该插件的作用,只能输入字母或数字</p>
|
||||
</div>
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
{if condition="!empty($pluginData)"}
|
||||
<script src="__PUBLIC__/static/js/admin/store.js?{$Think.config.html_v}"></script>
|
||||
<div>
|
||||
<form id="win_form_save2store" action="https://www.skycaiji.com/client/plugin/upload" method="post" target="myModalIframe">
|
||||
<input type="hidden" name="plugin" value="{:base64_encode(serialize($pluginData))}" />
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
/*利用iframe+form post提交*/
|
||||
var formhtml=$('#win_form_save2store').prop("outerHTML")+'<script type="text\/javascript">$("#win_form_save2store").submit()<\/script>';
|
||||
windowStore('正在上传...','',{addonBody:formhtml});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
{else /}
|
||||
插件不存在
|
||||
{/if}
|
|
@ -18,11 +18,11 @@
|
|||
<input type="text" name="username" class="form-control" placeholder="{$Think.lang.find_pwd_username}" />
|
||||
</div>
|
||||
</div>
|
||||
{if condition="$GLOBALS['_sc']['c']['site']['verifycode']"}
|
||||
{if condition="g_sc_c('site','verifycode')"}
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input type="text" name="verifycode" class="form-control" placeholder="{$Think.lang.verifycode}" />
|
||||
<div class="input-group-btn"><img src="{:url('Admin/Index/verify')}" class="verify-img" onclick="refreshVerify(this)" /></div>
|
||||
<div class="input-group-btn"><img src="{:url('Admin/Index/verify')}" class="verify-img" onclick="refreshVerify(this)" onerror="verifyImgError()" /></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue