master v2.7
skycaiji 10 months ago
parent 281acc380f
commit a4d3531d5d

@ -11,7 +11,7 @@ class Demo extends BaseDiy{
'db_pwd' => '', //密码
'db_port' => 3306, //端口
'db_prefix' => '', //表前缀
'db_charset' => 'utf8', //编码
'db_charset' => 'utf8mb4', //编码
);
/**
* 导入数据

@ -6,6 +6,56 @@
.info-box-content .info-box-number{font-weight:normal;line-height:25px;}
.info-box-content .info-box-number .tips{margin-left:5px;font-size:14px;display:inline;}
.help-block{color:#aaa;}
/*左侧宽度*/
.content-wrapper,.main-footer{margin-left: 200px;}
.main-header .navbar {
margin-left: 200px;
}
.main-header .logo {
width: 200px;
font-size:19px;
text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
font-family:'Microsoft YaHei';
}
.main-sidebar {
width: 200px;
}
.control-sidebar-bg,.control-sidebar {
right: -200px;
width: 200px;
}
@media (min-width: 768px) {
.sidebar-collapse .content-wrapper,.sidebar-collapse .main-footer {
margin-left:0
}
.sidebar-collapse .main-sidebar {
-webkit-transform:translate(-200px, 0);
-ms-transform: translate(-200px, 0);
-o-transform: translate(-200px, 0);
transform: translate(-200px, 0)
}
.control-sidebar-open .content-wrapper,.control-sidebar-open .right-side,.control-sidebar-open .main-footer {
margin-right:200px
}
}
@media (max-width: 767px) {
.content-wrapper,.main-footer {
margin-left:0
}
.sidebar-open .content-wrapper,.sidebar-open .main-footer {
-webkit-transform:translate(200px, 0);
-ms-transform: translate(200px, 0);
-o-transform: translate(200px, 0);
transform: translate(200px, 0)
}
.main-sidebar {
-webkit-transform:translate(-200px, 0);
-ms-transform: translate(-200px, 0);
-o-transform: translate(-200px, 0);
transform: translate(-200px, 0)
}
}
/*取消动画*/
.content-wrapper,
.main-footer,
@ -27,6 +77,11 @@
transition:none!important;
}
/*全局*/
.treeview>ul.treeview-menu>li:FIRST-CHILD{padding-top:5px!important;}
.treeview>ul.treeview-menu>li:LAST-CHILD{padding-bottom:5px!important;}
.treeview>ul.treeview-menu>li>ul.treeview-menu>li:FIRST-CHILD{padding-top:0px!important;}
.treeview>ul.treeview-menu>li>ul.treeview-menu>li:LAST-CHILD{padding-bottom:0px!important;}
.modal-body .form-group:last-child>button[type="submit"]{margin-bottom:-15px;}
.modal-body .form-group .help-block:last-child{margin-bottom:0;}
@ -103,6 +158,9 @@ div.in-line-mg{display:inline;margin-right:5px;}
.echo-msg-lt{float:left;}
.echo-msg-lurl{float:left;margin-right:3px;height:17px;max-width:70%;overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;word-break:break-all;}
.login-logo{
font-family:'Microsoft YaHei';
}
/*皮肤*/
.skin-blue-light .treeview-skins,.skin-black-light .treeview-skins,.skin-red-light .treeview-skins,.skin-yellow-light .treeview-skins,.skin-purple-light .treeview-skins,.skin-green-light .treeview-skins{
color:#000;
@ -140,6 +198,16 @@ div.in-line-mg{display:inline;margin-right:5px;}
.skin-purple .steps-bar .current .round,.skin-purple .steps-bar .current .bar,.skin-purple-light .steps-bar .current .round,.skin-purple-light .steps-bar .current .bar{background:#605ca8;color:#fff;border-color:#605ca8;}
.skin-purple .steps-bar .current a,.skin-purple-light .steps-bar .current a {color: #555299;}
.skin-black .nav-tabs-color li.active,.skin-black-light .nav-tabs-color li.active{border-top-color:#5A6E82!important;}
.skin-green .nav-tabs-color li.active,.skin-green-light .nav-tabs-color li.active{border-top-color:#00a65a!important;}
.skin-red .nav-tabs-color li.active,.skin-red-light .nav-tabs-color li.active{border-top-color:#dd4b39!important;}
.skin-yellow .nav-tabs-color li.active,.skin-yellow-light .nav-tabs-color li.active{border-top-color:#f39c12!important;}
.skin-purple .nav-tabs-color li.active,.skin-purple-light .nav-tabs-color li.active{border-top-color:#605ca8!important;}
/*数据表*/
.datatable .sub{padding-left:50px; background:url('../images/bg_column.gif') no-repeat 15px 10px;}
.datatable td .dropdown{display:inline;}
@ -209,218 +277,19 @@ table.table thead .sorting_desc:after {
.modal-title{font-size:16px;}
.myModal .modal-body iframe{width:100%;height:100%;min-height:200px;}
.myModal button.close{font-size:18px;}
/*采集器面板*/
.coll-panel .panel-heading{background-color:#d2d6de;}
.coll-panel .panel-default .panel-default .panel-heading{background-color:#efefef;}
.coll-panel .panel-heading a{color:#333;}
.coll-alert{color:#333!important;background-color:#f5f5f5!important;border-color:#ddd!important;}
.c-p-source-urls>.form-group:first-child{margin-top:10px;}
#c_p_level_urls tbody{
counter-reset:levelcounter;
}
#c_p_level_urls .level:before{
content:counter(levelcounter);
counter-increment:levelcounter;
font-weight:bold;
}
#c_p_front_urls td.sign,#c_p_level_urls td.sign,#c_p_relation_urls td.sign{
width:50%;overflow:hidden;padding-bottom:0;
}
#c_p_front_urls .sign-th,#c_p_level_urls .sign-th,#c_p_relation_urls .sign-th{
padding-left:5px;
}
#c_p_front_urls .signs,#c_p_level_urls .signs,#c_p_relation_urls .signs{
border:0;padding:0px 5px;height:20px;line-height:14px;font-size:12px;color:#555;background:#fff;
}
/*采集器选项卡*/
.coll-tab > li:nth-child(2).active > a,.coll-tab > li:nth-child(3).active > a{background:#f5f5f5;}
.coll-tab > li{
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
-khtml-user-select:none;
user-select:none;
}
.coll-tab>li>a{
border-bottom:0;
}
/*请求头信息*/
.c-p-request-headers table,.c-p-request-headers-img table,.c-p-request-headers-file table{margin-bottom:0}
.c-p-request-headers .delete-request-header,.c-p-request-headers-img .delete-request-header-img,.c-p-request-headers-file .delete-request-header-file{margin-top:8px;}
.c-p-request-headers td:first-child,.c-p-request-headers-img td:first-child,.c-p-request-headers-file td:first-child{width:200px;}
.c-p-request-headers td:last-child,.c-p-request-headers-img td:last-child,.c-p-request-headers-file td:last-child{width:50px;text-align:center;}
/*内容标签*/
.c-p-url-content-signs{
width:auto;
overflow:hidden;
}
/*页面源码表单和请求头*/
.c-p-url-web-form table,.c-p-url-web-header table{margin-bottom:0;}
.c-p-url-web-form .delete-url-web-form,.c-p-url-web-header .delete-url-web-header{margin-top:8px;}
.c-p-url-web-form td:first-child,.c-p-url-web-header td:first-child{width:200px;}
.c-p-url-web-form td:last-child,.c-p-url-web-header td:last-child{width:50px;text-align:center;}
/*页面渲染动作*/
.c-p-url-renderer-list table{margin-bottom:0;}
.c-p-url-renderer-list .td-renderer-element,.c-p-url-renderer-list .td-renderer-content{display:none;}
.c-p-url-renderer-list .td-renderer-op{width:65px;text-align:center;}
.c-p-url-renderer-list .td-renderer-op .input-group-addon:last-child{border-left:1px solid #d2d6de;}
/*显示标签列表input-group-btn必须position:static否则dropdown-menu定位太窄*/
.c-p-url-page-signs>.input-group-btn{position:static;}
.c-p-url-page-signs .dropdown-menu{padding:0;box-shadow:none;border:0;}
.c-p-url-page-signs .c-p-url-ps-table{padding:10px;box-shadow:0 0 2px 2px #eee;border:1px solid #ddd;border-radius:4px;}
.c-p-url-page-signs .c-p-url-ps-table .table{margin-bottom:0;}
.c-p-url-page-signs .c-p-url-ps-table .table td>a,.c-p-url-page-signs .dropdown-menu .table td>span{margin-right:5px;}
.c-p-url-page-signs .c-p-url-ps-table .table td>*:last-child{margin-right:0;}
.c-p-url-page-signs .c-p-url-ps-table .table td{white-space:normal!important;width:auto!important;}
.c-p-url-page-signs .c-p-url-ps-table .table td:first-child{white-space:nowrap!important;}
.c-p-url-page-signs .c-p-url-ps-table .table td:last-child{text-align:left!important;}
/*分页字段*/
.c-p-url-pagination-fields{
width:auto;
overflow:hidden;
}
/*参数标签样式*/
.param-label{
font-size:14px;
font-weight:normal;
padding: 4px 8px;
text-decoration: none;
border-bottom: none;
color: #3c8dbc;
border: 1px #ccc solid;
margin:7px 15px 5px 0;
position:relative;
float:left;
}
.param-label em.delete{
font-style: normal;
display: block;
position: absolute;
top: -7px;
right: -5px;
z-index: 999;
background:#fff;
}
/*采集器字段*/
.c-p-field-list .field-name{color:#3c8dbc;cursor:pointer;}
.c-p-field-list .exist-process{color:green;}
.c-p-field-list thead .sort-field{font-size:12px;color:#cdcdcd;margin-left:5px;display:none;}
/*杂项*/
.form-inline label{font-weight:normal;}
.c-p-field-list td .field-process{vertical-align:middle;}
.c-p-field-list td .glyphicon.icon-drag-move{font-size:12px;vertical-align:middle;}
.c-p-field-list td .glyphicon.field-clone{font-size:12px;top:0.3px;vertical-align:middle;}
.c-p-field-list td .glyphicon.field-del{font-size:12px;top:1.1px;vertical-align:middle;}
#coll_tab_content td .glyphicon.icon-drag-move{font-size:12px;vertical-align:middle;}
#coll_tab_content td .glyphicon.clone{font-size:12px;top:0.3px;vertical-align:middle;}
#coll_tab_content td .glyphicon.delete{font-size:12px;top:1.1px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.c-p-process-title{font-size:11px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.icon-drag-move{font-size:12px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.c-p-process-clone{font-size:12px;top:0.3px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.c-p-process-del{font-size:12px;top:1.1px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .panel-title-title{float:left;}
.c-p-process-accordion .panel-heading .panel-title-title input{display:none;border-radius:2px;border:1px solid #ccc;line-height:14px;font-size:12px;margin-left:5px;padding:1px 1px 1px 2px;}
.c-p-process-accordion .panel-heading .panel-title-ops{float:right;line-height:19px;}
#task_list_folder .taskgroup-opened .icon-folder-pre:before{content:"\2212"}
#task_list_folder .taskgroup-opened .icon-folder:before{content:"\e118"}
#task_list_folder .icon-folder-pre:before{font-size:12px;content:"\002b"}
#task_list_folder .icon-folder:before{content:"\e117";margin-right:5px;}
.box-header .navbar-toggle{background:#efefef;margin-top:0;}
.box-header .navbar-toggle .icon-bar{background:#aaa;}
.form-item .form-horizontal .control-label{text-align:left;width:120px;font-weight:normal;}
.loading{background:url('../images/loading.gif') no-repeat 5px 0;background-size:27px 27px;width:32px;height:27px;}
.loading-sm{background:url('../images/load1.gif') no-repeat 0 0;background-size:11px 11px;width:11px;height:11px;display:inline-block;}
.iga-rt{text-align:left;line-height:20px;}
.iga-rt .blk{display:block;}
.iga-rt .mgr{margin-right:5px;}
.iga-rt1{padding:0;vertical-align:top;}
.iga-rt1 .slt{width:100%;min-width:58px;height:24px;display:block;color:#555;font-weight:bold;padding:1px;margin:0;border:0;background:#F1F1F1;}
.iga-rt1 .op{margin:0;padding:3px 6px;list-style:none;}
.iga-rt1 .op li{display:none;}
.nav-save-rule{float:right!important;}
/*数据处理*/
.form-control-slt{width:30px!important;text-align:center;}
.form-control-slt select.form-control{min-width:20px!important;width:20px!important;height:30px!important;float:none!important;border:0!important;padding:0!important;margin:0!important;text-indent:-20px!important;}
.p-m-func-field{display:inline;width:80px;border:0;cursor:pointer;margin:0;padding:0;height:auto;color:#555;}
.p-m-api-val-field,.p-m-api-header-field{display:none;margin-left:-1px;padding:0;}
.p-m-api-table table,.p-m-api-header-table table{margin-bottom:0;}
.p-m-api-table td:first-child,.p-m-api-header-table td:first-child{width:200px;}
.p-m-api-table td:last-child,.p-m-api-header-table td:last-child{width:50px;text-align:center;}
.p-m-api-rule-module{display:none;}
.p-m-html-tags{}
.p-m-html-tags a{font-size:12px;font-weight:normal;cursor:pointer;margin-right:5px;}
.p-m-html-tags a span{margin-right:2px;color:#999;}
.p-m-if-val-func{position:relative;}
.p-m-if-val-func a.input-group-addon{border-left:0;}
.p-m-if-val-func .input-group-btn>select{margin-left:-1px;width:auto;padding:0;padding-left:5px;text-align:center;}
.p-m-if-op{width:70px;padding:15px 0 0 8px!important;font-size:11px;}
.p-m-if-add{font-size:12px;}
.p-m-download-op{display:none;margin-top:15px;}
/*发布设置*/
.rele-db-error{margin-top:10px;color:red;font-weight:bold;}
.db-table-bind-params{padding:0;margin-bottom:0;border:0;}
.db-table-bind-params .table{margin-bottom:0;}
.db-table-bind-params .table tr>th:first-child,.db-table-bind-params .table tr>td:first-child{padding-left:15px;}
.db-table-bind-params .table thead th{padding-top:13px;padding-bottom:13px;}
.db-table-bind-op{width:auto;height:auto;display:inline;padding:0;}
.db-table-bind-where-tpl,.db-table-bind-query-tpl{display:none;}
.db-table-bind-where,.db-table-bind-query{display:none;}
.db-table-bind-data-seq{display:none;}
.db-table-bind-where,.db-table-bind-query,.db-table-bind-data{border:0;}
.db-table-bind-signs>.input-group-btn{position:static;}
.dm-db-charset li {padding:5px 15px;}
.dm-db-charset li.divider{padding:0;}
.dm-db-charset li span{padding:5px; cursor:pointer;color:#555;}
.dm-db-charset li span:hover{background:#eee;}
.toapi-param-table table,.toapi-header-table table{margin-bottom:0;}
.toapi-param-table td:first-child,.toapi-header-table td:first-child{width:200px;}
.toapi-param-table td:last-child,.toapi-header-table td:last-child{width:50px;text-align:center;}
#toapi_resp_module_help .help-block{display:none;margin:0;}
.toapi-app-table table tr td{height:50px;vertical-align:middle!important;}
.toapi-field-txt>.input-group-addon{padding:0;}
.toapi-field-txt>.input-group-addon a.dropdown-toggle{border-color:#fff;padding:6px 12px;color:#666;}
.toapi-field-txt>.input-group-addon a.dropdown-toggle:hover{color:#000;}
.toapi-field-txt>.input-group-addon a.dropdown-toggle .caret{margin-top:-2px;}
.toapi-field-slt select.form-control{min-width:120px!important;margin-right:-1px;min-height:34px;max-height:90px;}
.toapi-field-slt textarea.form-control{height:90px;}
.toapi-field-slt input.form-control,.toapi-field-slt textarea.form-control,.toapi-field-slt .input-group-addon{display:none!important;}
.toapi-field-slt-txt input.form-control,.toapi-field-slt-txt textarea.form-control,.toapi-field-slt-txt .input-group-addon{display:table-cell!important;}
footer.footer-end{display:none;}
/*步骤条*/
.steps-bar{width:100%;overflow:hidden;color:#999;}
.steps-bar a{color:#999;}
@ -496,11 +365,6 @@ table.table thead .sorting_desc:after {
border-radius: 4px;
background:#d3d3d3;
}
/**/
#cms_bind em{color:red;}
#cms_bind .box{margin-bottom:0;}
#cms_bind .table{margin-bottom:0;}
#toapi_app_params em{color:red;}
/*my store*/
.nav-tabs-color li.active{border-top-color:#3c8dbc!important;}
@ -552,39 +416,6 @@ table.table thead .sorting_desc:after {
.deve-editor-apps li{padding:2px 0;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.deve-editor-apps li a{color:#333;}
.deve-editor-apps li.cur a{font-weight:bold;}
/**/
.table-test-loop thead{background:#fafafa;}
.table-test-loop thead th,.table-test-loop thead td{
padding:0!important;
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
-khtml-user-select:none;
user-select:none;
}
.table-test-loop thead th>div{
cursor:w-resize;
padding:8px;
}
.table-test-loop tbody td{
position:relative;
}
.table-test-loop input{border:0;overflow:hidden;width:100%;min-width:150px;}
.table-test-loop .view-box{padding-left:20px;}
.table-test-loop .view-ipt{}
.table-test-loop .view-btn{position:absolute;font-size:12px;top:12px;left:5px;}
footer.footer-end{display:none;}
.skin-black .nav-tabs-color li.active,.skin-black-light .nav-tabs-color li.active{border-top-color:#5A6E82!important;}
.skin-green .nav-tabs-color li.active,.skin-green-light .nav-tabs-color li.active{border-top-color:#00a65a!important;}
.skin-red .nav-tabs-color li.active,.skin-red-light .nav-tabs-color li.active{border-top-color:#dd4b39!important;}
.skin-yellow .nav-tabs-color li.active,.skin-yellow-light .nav-tabs-color li.active{border-top-color:#f39c12!important;}
.skin-purple .nav-tabs-color li.active,.skin-purple-light .nav-tabs-color li.active{border-top-color:#605ca8!important;}
/*采集窗口*/
.win-cem-process-body{position:relative;}
@ -625,30 +456,6 @@ footer.footer-end{display:none;}
.win-cem-ifr-box iframe{width:100%;height:100%;margin:0;border:0;}
@media (min-width: 1200px) {
/*table-responsive设置overflow:inherit;可正常显示dropdown-menu*/
.c-p-url-renderer-list{overflow:inherit;}
.db-table-bind-where,.db-table-bind-query,.db-table-bind-data{overflow:inherit;}
}
@media (max-width: 1199px) {
/*dropdown-menu用fixed避免被table-responsive的overflow:hidden;影响*/
.c-p-url-renderer-list .c-p-url-page-signs .dropdown-menu{padding:0;border:4px solid #ddd;border-radius:4px;background:transparent;position:fixed;left:10px;right:10px;bottom:10px;top:auto;max-height:80%;overflow-y:scroll;}
.c-p-url-renderer-list .c-p-url-page-signs .dropdown-menu .c-p-url-ps-table{background:#fff;}
.db-table-bind-signs .dropdown-menu{padding:0;border:4px solid #ddd;border-radius:4px;background:transparent;position:fixed;left:10px;right:10px;bottom:10px;top:auto;max-height:80%;overflow-y:scroll;}
.db-table-bind-signs .dropdown-menu table{margin:0;}
}
@media (min-width: 900px) {
.toapi-app-table .table tr td:FIRST-CHILD{width:200px;white-space:nowrap;padding-right:10px;}
#cms_bind .table tr td:FIRST-CHILD{width:200px;white-space:nowrap;padding-right:10px;}
}
@media (min-width: 768px) {
.c-p-url-web-form,.c-p-url-web-header{overflow:inherit;} /*table-responsive设置overflow:inherit;可正常显示dropdown-menu*/
}
@media (max-width: 767px){
.main-header .logo{
width:140px;
@ -664,39 +471,13 @@ footer.footer-end{display:none;}
}
.content-wrapper .content{padding-top:8px;}
.c-p-url-page-signs .dropdown-menu .table td>a,.c-p-url-page-signs .dropdown-menu .table td>span{display:block;margin-right:0;}
.deve-editor-left,.deve-editor-right{padding-left:15px;padding-right:15px;margin-bottom:10px;}
/*dropdown-menu用fixed避免被table-responsive的overflow:hidden;影响*/
.c-p-url-web-form .c-p-url-page-signs .dropdown-menu,.c-p-url-web-header .c-p-url-page-signs .dropdown-menu{padding:0;border:4px solid #ddd;border-radius:4px;background:transparent;position:fixed;left:10px;right:10px;bottom:10px;top:auto;max-height:80%;overflow-y:scroll;}
.c-p-url-web-form .c-p-url-page-signs .dropdown-menu .c-p-url-ps-table,.c-p-url-web-header .c-p-url-page-signs .dropdown-menu .c-p-url-ps-table{background:#fff;}
/*元素最小宽度,防止太窄无法输入*/
.table-responsive .table input.form-control{min-width:100px;}
.table-responsive .table textarea.form-control{min-width:100px;}
}
@media (max-width: 550px){
/*采集器tab*/
.coll-tab>li{margin-bottom:5px;width:33%;}
.coll-tab>li>a{padding:7px 0;border:solid 1px #ddd;text-align:center;}
.coll-tab>li:nth-child(3).active>a{background:#fff;}
.coll-tab>li.active>a{border-radius:3px;border-bottom-color:#ddd!important;}
.coll-tab .nav-save-rule{float:left!important;}
.coll-tab .nav-save-rule>a{color:#999;}
.c-p-source-tab>li{margin-bottom:5px;margin-right:3px;width:auto;}
.c-p-source-tab>li>a{padding:5px 7px;border:solid 1px #ddd;text-align:center;}
.c-p-source-tab>li.active>a{border-radius:3px;border-bottom-color:#ddd!important;background-color:#efefef!important;}
.mobile-input-group{width:100%;}
.mobile-input-group>.input-group-addon{display:table-caption;width:100%;background:#fafafa;margin-bottom:5px;border-right:1px solid #ccc;}
.mobile-input-group1>.input-group-addon{display:block;}
/*自适应第一个td宽度*/
.c-p-request-headers td:first-child,.c-p-request-headers-img td:first-child{width:auto;}
.c-p-url-web-form td:first-child,.c-p-url-web-header td:first-child{width:auto;}
.p-m-api-table td:first-child,.p-m-api-header-table td:first-child{width:auto;}
.toapi-param-table td:first-child,.toapi-header-table td:first-child{width:auto;}
.list-footer .form-control{width:100%!important;}
}

@ -0,0 +1,220 @@
@CHARSET "UTF-8";
/*采集器面板*/
.coll-panel .panel-heading{background-color:#d2d6de;}
.coll-panel .panel-default .panel-default .panel-heading{background-color:#efefef;}
.coll-panel .panel-heading a{color:#333;}
.coll-alert{color:#333!important;background-color:#f5f5f5!important;border-color:#ddd!important;}
.c-p-source-urls>.form-group:first-child{margin-top:10px;}
#c_p_level_urls tbody{
counter-reset:levelcounter;
}
#c_p_level_urls .level:before{
content:counter(levelcounter);
counter-increment:levelcounter;
font-weight:bold;
}
#c_p_front_urls td.sign,#c_p_level_urls td.sign,#c_p_relation_urls td.sign{
width:50%;overflow:hidden;padding-bottom:0;
}
#c_p_front_urls .sign-th,#c_p_level_urls .sign-th,#c_p_relation_urls .sign-th{
padding-left:5px;
}
#c_p_front_urls .signs,#c_p_level_urls .signs,#c_p_relation_urls .signs{
border:0;padding:0px 5px;height:20px;line-height:14px;font-size:12px;color:#555;background:#fff;
}
/*采集器选项卡*/
.coll-tab > li:nth-child(2).active > a,.coll-tab > li:nth-child(3).active > a{background:#f5f5f5;}
.coll-tab > li{
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
-khtml-user-select:none;
user-select:none;
}
.coll-tab>li>a{
border-bottom:0;
}
/*请求头信息*/
.c-p-request-headers table,.c-p-request-headers-img table,.c-p-request-headers-file table{margin-bottom:0}
.c-p-request-headers .delete-request-header,.c-p-request-headers-img .delete-request-header-img,.c-p-request-headers-file .delete-request-header-file{margin-top:8px;}
.c-p-request-headers td:first-child,.c-p-request-headers-img td:first-child,.c-p-request-headers-file td:first-child{width:200px;}
.c-p-request-headers td:last-child,.c-p-request-headers-img td:last-child,.c-p-request-headers-file td:last-child{width:50px;text-align:center;}
/*内容标签*/
.c-p-url-content-signs{
width:auto;
overflow:hidden;
}
/*页面源码表单和请求头*/
.c-p-url-web-form table,.c-p-url-web-header table{margin-bottom:0;}
.c-p-url-web-form .delete-url-web-form,.c-p-url-web-header .delete-url-web-header{margin-top:8px;}
.c-p-url-web-form td:first-child,.c-p-url-web-header td:first-child{width:200px;}
.c-p-url-web-form td:last-child,.c-p-url-web-header td:last-child{width:50px;text-align:center;}
/*页面渲染动作*/
.c-p-url-renderer-list table{margin-bottom:0;}
.c-p-url-renderer-list .td-renderer-element,.c-p-url-renderer-list .td-renderer-content{display:none;}
.c-p-url-renderer-list .td-renderer-op{width:65px;text-align:center;vertical-align:middle;}
.c-p-url-renderer-list .td-renderer-op .icon-drag-move{font-size:14px!important;}
.c-p-url-renderer-list .td-renderer-op .input-group-addon:last-child{border-left:1px solid #d2d6de;}
/*显示标签列表input-group-btn必须position:static否则dropdown-menu定位太窄*/
.c-p-url-page-signs>.input-group-btn{position:static;}
.c-p-url-page-signs .dropdown-menu{padding:0;box-shadow:none;border:0;}
.c-p-url-page-signs .c-p-url-ps-table{padding:10px;box-shadow:0 0 2px 2px #eee;border:1px solid #ddd;border-radius:4px;}
.c-p-url-page-signs .c-p-url-ps-table .table{margin-bottom:0;}
.c-p-url-page-signs .c-p-url-ps-table .table td>a,.c-p-url-page-signs .dropdown-menu .table td>span{margin-right:5px;}
.c-p-url-page-signs .c-p-url-ps-table .table td>*:last-child{margin-right:0;}
.c-p-url-page-signs .c-p-url-ps-table .table td{white-space:normal!important;width:auto!important;}
.c-p-url-page-signs .c-p-url-ps-table .table td:first-child{white-space:nowrap!important;}
.c-p-url-page-signs .c-p-url-ps-table .table td:last-child{text-align:left!important;}
/*分页字段*/
.c-p-url-pagination-fields{
width:auto;
overflow:hidden;
}
/*参数标签样式*/
.param-label{
font-size:14px;
font-weight:normal;
padding: 4px 8px;
text-decoration: none;
border-bottom: none;
color: #3c8dbc;
border: 1px #ccc solid;
margin:7px 15px 5px 0;
position:relative;
float:left;
}
.param-label em.delete{
font-style: normal;
display: block;
position: absolute;
top: -7px;
right: -5px;
z-index: 999;
background:#fff;
}
/*采集器字段*/
.c-p-field-list .field-name{color:#3c8dbc;cursor:pointer;}
.c-p-field-list .exist-process{color:green;}
.c-p-field-list thead .sort-field{font-size:12px;color:#cdcdcd;margin-left:5px;display:none;}
.c-p-field-list td .field-process{vertical-align:middle;}
.c-p-field-list td .glyphicon.icon-drag-move{font-size:12px;vertical-align:middle;}
.c-p-field-list td .glyphicon.field-clone{font-size:12px;top:0.3px;vertical-align:middle;}
.c-p-field-list td .glyphicon.field-del{font-size:12px;top:1.1px;vertical-align:middle;}
#coll_tab_content td .glyphicon.icon-drag-move{font-size:12px;vertical-align:middle;}
#coll_tab_content td .glyphicon.clone{font-size:12px;top:0.3px;vertical-align:middle;}
#coll_tab_content td .glyphicon.delete{font-size:12px;top:1.1px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.c-p-process-title{font-size:11px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.icon-drag-move{font-size:12px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.c-p-process-clone{font-size:12px;top:0.3px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .glyphicon.c-p-process-del{font-size:12px;top:1.1px;vertical-align:middle;}
.c-p-process-accordion .panel-heading .panel-title-title{float:left;}
.c-p-process-accordion .panel-heading .panel-title-title input{display:none;border-radius:2px;border:1px solid #ccc;line-height:14px;font-size:12px;margin-left:5px;padding:1px 1px 1px 2px;}
.c-p-process-accordion .panel-heading .panel-title-ops{float:right;line-height:19px;}
.iga-rt{text-align:left;line-height:20px;}
.iga-rt .blk{display:block;}
.iga-rt .mgr{margin-right:5px;}
.iga-rt1{padding:0;vertical-align:top;}
.iga-rt1 .slt{width:100%;min-width:58px;height:24px;display:block;color:#555;font-weight:bold;padding:1px;margin:0;border:0;background:#F1F1F1;}
.iga-rt1 .op{margin:0;padding:3px 6px;list-style:none;}
.iga-rt1 .op li{display:none;}
.nav-save-rule{float:right!important;}
/*数据处理*/
.form-control-slt{width:30px!important;text-align:center;}
.form-control-slt select.form-control{min-width:20px!important;width:20px!important;height:30px!important;float:none!important;border:0!important;padding:0!important;margin:0!important;text-indent:-20px!important;}
.p-m-func-field,.p-m-insert-field{display:inline;width:80px;border:0;cursor:pointer;margin:0;padding:0;height:auto;color:#555;}
.p-m-api-val-field,.p-m-api-header-field{display:none;margin-left:-1px;padding:0;}
.p-m-api-table table,.p-m-api-header-table table{margin-bottom:0;}
.p-m-api-table td:first-child,.p-m-api-header-table td:first-child{width:200px;}
.p-m-api-table td:last-child,.p-m-api-header-table td:last-child{width:50px;text-align:center;}
.p-m-api-rule-module{display:none;}
.p-m-html-tags{}
.p-m-html-tags a{font-size:12px;font-weight:normal;cursor:pointer;margin-right:5px;}
.p-m-html-tags a span{margin-right:2px;color:#999;}
.p-m-if-val-func{position:relative;}
.p-m-if-val-func a.input-group-addon{border-left:0;}
.p-m-if-val-func .input-group-btn>select{margin-left:-1px;width:auto;padding:0;padding-left:5px;text-align:center;}
.p-m-if-op{width:70px;padding:15px 0 0 8px!important;font-size:11px;}
.p-m-if-add{font-size:12px;}
.p-m-download-op{display:none;margin-top:15px;}
/*测试*/
.table-test-loop thead{background:#fafafa;}
.table-test-loop thead th,.table-test-loop thead td{
padding:0!important;
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
-khtml-user-select:none;
user-select:none;
}
.table-test-loop thead th>div{
cursor:w-resize;
padding:8px;
}
.table-test-loop tbody td{
position:relative;
}
.table-test-loop input{border:0;overflow:hidden;width:100%;min-width:150px;}
.table-test-loop .view-box{padding-left:20px;}
.table-test-loop .view-ipt{}
.table-test-loop .view-btn{position:absolute;font-size:12px;top:12px;left:5px;}
@media (min-width: 1200px) {
/*table-responsive设置overflow:inherit;可正常显示dropdown-menu*/
.c-p-url-renderer-list{overflow:inherit;}
}
@media (max-width: 1199px) {
/*dropdown-menu用fixed避免被table-responsive的overflow:hidden;影响*/
.c-p-url-renderer-list .c-p-url-page-signs .dropdown-menu{padding:0;border:4px solid #ddd;border-radius:4px;background:transparent;position:fixed;left:10px;right:10px;bottom:10px;top:auto;max-height:80%;overflow-y:scroll;}
.c-p-url-renderer-list .c-p-url-page-signs .dropdown-menu .c-p-url-ps-table{background:#fff;}
}
@media (min-width: 768px) {
.c-p-url-web-form,.c-p-url-web-header{overflow:inherit;} /*table-responsive设置overflow:inherit;可正常显示dropdown-menu*/
}
@media (max-width: 767px){
.c-p-url-page-signs .dropdown-menu .table td>a,.c-p-url-page-signs .dropdown-menu .table td>span{display:block;margin-right:0;}
/*dropdown-menu用fixed避免被table-responsive的overflow:hidden;影响*/
.c-p-url-web-form .c-p-url-page-signs .dropdown-menu,.c-p-url-web-header .c-p-url-page-signs .dropdown-menu{padding:0;border:4px solid #ddd;border-radius:4px;background:transparent;position:fixed;left:10px;right:10px;bottom:10px;top:auto;max-height:80%;overflow-y:scroll;}
.c-p-url-web-form .c-p-url-page-signs .dropdown-menu .c-p-url-ps-table,.c-p-url-web-header .c-p-url-page-signs .dropdown-menu .c-p-url-ps-table{background:#fff;}
}
@media (max-width: 550px){
/*采集器tab*/
.coll-tab>li{margin-bottom:5px;width:33%;}
.coll-tab>li>a{padding:7px 0;border:solid 1px #ddd;text-align:center;}
.coll-tab>li:nth-child(3).active>a{background:#fff;}
.coll-tab>li.active>a{border-radius:3px;border-bottom-color:#ddd!important;}
.coll-tab .nav-save-rule{float:left!important;}
.coll-tab .nav-save-rule>a{color:#999;}
.c-p-source-tab>li{margin-bottom:5px;margin-right:3px;width:auto;}
.c-p-source-tab>li>a{padding:5px 7px;border:solid 1px #ddd;text-align:center;}
.c-p-source-tab>li.active>a{border-radius:3px;border-bottom-color:#ddd!important;background-color:#efefef!important;}
/*自适应第一个td宽度*/
.c-p-request-headers td:first-child,.c-p-request-headers-img td:first-child{width:auto;}
.c-p-url-web-form td:first-child,.c-p-url-web-header td:first-child{width:auto;}
.p-m-api-table td:first-child,.p-m-api-header-table td:first-child{width:auto;}
}

@ -39,7 +39,7 @@
#skycaiji_console .skycaiji-block{width:100%;overflow:hidden;line-height:20px;padding-top:5px;}
#skycaiji_console .skycaiji-block>.skycaiji-b-l{float:left;width:130px;}
#skycaiji_console .skycaiji-block>.skycaiji-b-c{margin-left:130px;margin-right:260px;}
#skycaiji_console .skycaiji-block>.skycaiji-b-c .skycaiji-b-c-i{margin-right:20px;}
#skycaiji_console .skycaiji-block>.skycaiji-b-c .skycaiji-b-c-i{margin-right:20px;min-width:300px;}
#skycaiji_console .skycaiji-block>.skycaiji-b-c input{width:100%;height:20px;float:left;}
#skycaiji_console .skycaiji-block>.skycaiji-b-c select{width:20px;height:20px;overflow:hidden;float:left;}
#skycaiji_console .skycaiji-block>.skycaiji-b-r{padding-left:5px;float:left;}

@ -0,0 +1,13 @@
@CHARSET "UTF-8";
#dataapi_list .status{color:green;}
#dataapi_list .status-close{color:red;}
#config_conds tr>th:first-child,#config_conds tr>td:first-child{padding-left:15px;}
#config_conds thead th{padding-top:13px;padding-bottom:13px;}
#config_conds tbody tr>td:last-child{vertical-align:middle;font-size:14px;}
#config_conds .config-cond-move{font-size:12px;}
#config_conds .config-cond-dlt{margin-left:2px;margin-right:2px;}
#config_conds .config-cond-sub td:FIRST-CHILD{padding-left:50px; background:url('../images/bg_column.gif') no-repeat 15px 15px;}
#config_conds .config-cond-sub .config-cond-add{display:none;}

@ -0,0 +1,51 @@
@CHARSET "UTF-8";
/*数据集*/
#dataset_list .fields{
border:0;padding:0px 5px;height:20px;line-height:14px;font-size:12px;color:#555;background:#fff;
}
#dataset_db_list td .txt-big{height:100px!important;}
#dataset_db_list td{vertical-align:middle;}
#dataset_db_list td .form-control{
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
.dataset-db-list::-webkit-scrollbar{
width: 12px;
height: 12px;
}
.dataset-search::-webkit-scrollbar{
width: 8px;
height: 8px;
}
.dataset-db-list::-webkit-scrollbar-button,.dataset-search::-webkit-scrollbar-button{
background-color:#efefef;
}
.dataset-db-list::-webkit-scrollbar-track,.dataset-search::-webkit-scrollbar-track{
background:#efefef;
}
.dataset-db-list::-webkit-scrollbar-thumb,.dataset-search::-webkit-scrollbar-thumb{
background: #ccc;
border-radius: 4px;
}
.dataset-search{width:100%;overflow-x:scroll;white-space:nowrap;padding-bottom:5px;padding-right:5px;}
#dataset_db_list input::placeholder,#dataset_db_list textarea::placeholder{color:#bbb!important;}
#dataset_fields tr>th:first-child,#dataset_fields tr>td:first-child{padding-left:15px;}
#dataset_fields thead th{padding-top:13px;padding-bottom:13px;}
.dataset-sep{
color: #999;
text-indent: -9999px;
display: inline-block;
width: 3px;
line-height: 12px;
margin-left: 2px;
border-left: 1px solid #aaa;
}

@ -0,0 +1,78 @@
@CHARSET "UTF-8";
/*发布设置*/
#dataset_config table tr td{height:50px;vertical-align:middle!important;}
.dataset-field-txt>.input-group-addon{padding:0;}
.dataset-field-txt>.input-group-addon a.dropdown-toggle{border-color:#fff;padding:6px 12px;color:#666;}
.dataset-field-txt>.input-group-addon a.dropdown-toggle:hover{color:#000;}
.dataset-field-txt>.input-group-addon a.dropdown-toggle .caret{margin-top:-2px;}
.rele-db-error{margin-top:10px;color:red;font-weight:bold;}
.db-table-bind-params{padding:0;margin-bottom:0;border:0;}
.db-table-bind-params .table{margin-bottom:0;}
.db-table-bind-params .table tr>th:first-child,.db-table-bind-params .table tr>td:first-child{padding-left:15px;}
.db-table-bind-params .table thead th{padding-top:13px;padding-bottom:13px;}
.db-table-bind-op{width:auto;height:auto;display:inline;padding:0;}
.db-table-bind-where-tpl,.db-table-bind-query-tpl{display:none;}
.db-table-bind-where,.db-table-bind-query{display:none;}
.db-table-bind-data-seq{display:none;}
.db-table-bind-where,.db-table-bind-query,.db-table-bind-data{border:0;}
.db-table-bind-signs>.input-group-btn{position:static;}
.dm-db-charset li {padding:5px 15px;}
.dm-db-charset li.divider{padding:0;}
.dm-db-charset li span{padding:5px; cursor:pointer;color:#555;}
.dm-db-charset li span:hover{background:#eee;}
.toapi-param-table table,.toapi-header-table table{margin-bottom:0;}
.toapi-param-table td:first-child,.toapi-header-table td:first-child{width:200px;}
.toapi-param-table td:last-child,.toapi-header-table td:last-child{width:50px;text-align:center;}
#toapi_resp_module_help .help-block{display:none;margin:0;}
.toapi-app-table table tr td{height:50px;vertical-align:middle!important;}
.toapi-field-txt>.input-group-addon{padding:0;}
.toapi-field-txt>.input-group-addon a.dropdown-toggle{border-color:#fff;padding:6px 12px;color:#666;}
.toapi-field-txt>.input-group-addon a.dropdown-toggle:hover{color:#000;}
.toapi-field-txt>.input-group-addon a.dropdown-toggle .caret{margin-top:-2px;}
.toapi-field-slt select.form-control{min-width:120px!important;margin-right:-1px;min-height:34px;max-height:90px;}
.toapi-field-slt textarea.form-control{height:90px;}
.toapi-field-slt input.form-control,.toapi-field-slt textarea.form-control,.toapi-field-slt .input-group-addon{display:none!important;}
.toapi-field-slt-txt input.form-control,.toapi-field-slt-txt textarea.form-control,.toapi-field-slt-txt .input-group-addon{display:table-cell!important;}
/**/
#cms_bind em{color:red;}
#cms_bind .box{margin-bottom:0;}
#cms_bind .table{margin-bottom:0;}
#toapi_app_params em{color:red;}
@media (min-width: 1200px) {
/*table-responsive设置overflow:inherit;可正常显示dropdown-menu*/
.db-table-bind-where,.db-table-bind-query,.db-table-bind-data{overflow:inherit;}
}
@media (max-width: 1199px) {
/*dropdown-menu用fixed避免被table-responsive的overflow:hidden;影响*/
.db-table-bind-signs .dropdown-menu{padding:0;border:4px solid #ddd;border-radius:4px;background:transparent;position:fixed;left:10px;right:10px;bottom:10px;top:auto;max-height:80%;overflow-y:scroll;}
.db-table-bind-signs .dropdown-menu table{margin:0;}
}
@media (min-width: 900px) {
#dataset_config .table tr td:FIRST-CHILD{width:200px;white-space:nowrap;padding-right:10px;}
.toapi-app-table .table tr td:FIRST-CHILD{width:200px;white-space:nowrap;padding-right:10px;}
#cms_bind .table tr td:FIRST-CHILD{width:200px;white-space:nowrap;padding-right:10px;}
}
@media (max-width: 550px){
.mobile-input-group{width:100%;}
.mobile-input-group>.input-group-addon{display:table-caption;width:100%;background:#fafafa;margin-bottom:5px;border-right:1px solid #ccc;}
.mobile-input-group1>.input-group-addon{display:block;}
.toapi-param-table td:first-child,.toapi-header-table td:first-child{width:auto;}
}

@ -0,0 +1,7 @@
@CHARSET "UTF-8";
#task_list_folder .taskgroup-opened .icon-folder-pre:before{content:"\2212"}
#task_list_folder .taskgroup-opened .icon-folder:before{content:"\e118"}
#task_list_folder .icon-folder-pre:before{font-size:12px;content:"\002b"}
#task_list_folder .icon-folder:before{content:"\e117";margin-right:5px;}

@ -7,10 +7,10 @@
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
'use strict';var admincpOp={init:function(){var bodyWidth=$(document.body).width();var cpConfig=window.site_config.admincp;cpConfig=cpConfig?cpConfig:{};if(cpConfig.skin){$('body').removeClass('skin-blue').addClass(cpConfig.skin)}
'use strict';var admincpOp={getConfig:function(key){var cpConfig=window.site_config.admincp;cpConfig=cpConfig?cpConfig:{};return key?cpConfig[key]:cpConfig},init:function(){var bodyWidth=$(document.body).width();var cpConfig=admincpOp.getConfig(null);if(cpConfig.skin){$('body').removeClass('skin-blue').addClass(cpConfig.skin)}
var menuOpts={};if(bodyWidth>767){if(cpConfig.mini==1){$('body').addClass('sidebar-collapse').addClass('sidebar-mini')}
if(cpConfig.narrow==1){$('body').addClass('layout-boxed')}
menuOpts={};if(window.navigator.userAgent.indexOf('MSIE')>-1){menuOpts={animationSpeed:0}}}else{menuOpts={animationSpeed:0}}
menuOpts={animationSpeed:300};if(window.navigator.userAgent.indexOf('MSIE')>-1){menuOpts={animationSpeed:0}}}else{menuOpts={animationSpeed:0}}
$('.sidebar-menu').tree(menuOpts);$(document).ready(function(){$('#treeview_skins').bind('click',function(){if($('#sidebar_skins').html().length<=0){admincpOp.skins()}});if(bodyWidth>767){if(cpConfig.mini==1){$('#chk_sidebar_mini').prop('checked',!0)}
$('#chk_sidebar_mini').bind('click',function(){var setMini=$(this).is(':checked')?1:0;admincpOp.config('mini',setMini,function(){if(setMini){$('body').addClass('sidebar-collapse').addClass('sidebar-mini')}else{$('body').removeClass('sidebar-collapse').removeClass('sidebar-mini')}})});$('.sidebar-toggle[data-toggle="push-menu"]').bind('click',function(){$('body').addClass('sidebar-mini')});if(cpConfig.narrow==1){$('#chk_sidebar_narrow').prop('checked',!0)}
$('#chk_sidebar_narrow').bind('click',function(){var setNarrow=$(this).is(':checked')?1:0;admincpOp.config('narrow',setNarrow,function(){if(setNarrow){$('body').addClass('layout-boxed')}else{$('body').removeClass('layout-boxed')}})})}else{$('#chk_sidebar_mini').parents('li').eq(0).hide();$('#chk_sidebar_narrow').parents('li').eq(0).hide()}
@ -20,8 +20,12 @@ $('body').addClass(skin)})})}};function insertAtCaret(myField,myValue){myField=$
function urlUsertoken(){return'_usertoken_='+encodeURIComponent(window.site_config.usertoken)}
function openStoreUrl(url){if(url.indexOf('clientinfo=')<0&&window.site_config.clientinfo){url+=(url.indexOf('?')>-1?'&':'?')+'clientinfo='+encodeURIComponent(window.site_config.clientinfo)}
window.open(url,'_blank')}
function eleExchange(box,move,ele){if(!window.ele_exchange_is_touch){window.ele_exchange_is_touch=1;if('ontouchstart' in window||navigator.maxTouchPoints){window.ele_exchange_is_touch=2}}
if(window.ele_exchange_is_touch==2){$(box).on('click',move,function(){var obj=$(this).parents(ele).eq(0);var next=obj.next(ele);if(next.length>0){next.after(obj)}})}else{$(box).sortable({items:ele,handle:move,axis:'y'})}}
function eleExchange(box,move,ele,options){if(!isObject(options)){options={}}
if(!window.ele_exchange_is_touch){window.ele_exchange_is_touch=1;if('ontouchstart' in window||navigator.maxTouchPoints){window.ele_exchange_is_touch=2}}
if(window.ele_exchange_is_touch==2){$(box).on('click',move,function(){var obj=$(this).parents(ele).eq(0);var next=obj.next(ele);if(next.length>0){next.after(obj)}})}else{var curTrTds={};$(box).on('mousedown',move,function(){var obj=$(this).parents(ele).eq(0);if(obj.is('tr')){curTrTds={};obj.children('th,td').each(function(index){curTrTds[index]={width:$(this).width(),colspan:toInt($(this).attr('colspan')),hidden:$(this).is(':hidden')?true:!1}})}});var sOpts={items:ele,handle:move,axis:'y',start:function(event,ui){if(ui&&ui.item){var obj=$(ui.item[0]);if(obj.is('tr')){obj.children('th,td').each(function(index){var curTrTd=curTrTds[index];if(isObject(curTrTd)){$(this).width(curTrTd.width);if(curTrTd.colspan>0){$(this).attr('colspan',curTrTd.colspan)}
if(curTrTd.hidden){$(this).hide()}}});$('.ui-sortable-placeholder').children('th,td').each(function(index){var curTrTd=curTrTds[index];if(isObject(curTrTd)){$(this).width(curTrTd.width);if(curTrTd.colspan>0){$(this).attr('colspan',curTrTd.colspan)}
if(curTrTd.hidden){$(this).hide()}}})}}}};for(var i in options){sOpts[i]=options[i]}
$(box).sortable(sOpts)}}
function showPanelCollapse(id){$(id).parent().find('a[data-toggle][href="'+id+'"]').attr('aria-expanded',!0).removeClass('collapsed');$(id).addClass('in').attr('aria-expanded',!0).attr('style','')}
function inputSelectCustom(sltObj,iptName,onOptions,customName,changeFunc){customName=customName?customName:'custom';var onChangeFunc=function(curObj,iptEle){var ipt=$(curObj).parents('.input-select-custom').eq(0).find(iptEle);if($(curObj).val()==customName){ipt.show()}else{ipt.hide()}
if(changeFunc&&typeof(changeFunc)=='function'){changeFunc()}};if(sltObj&&iptName){$(sltObj).bind('change',function(){onChangeFunc(this,'[name="'+iptName+'"]')})}else if(onOptions&&typeof(onOptions)=='object'){$(onOptions.box).on('change',onOptions.slt,function(){onChangeFunc(this,onOptions.ipt)})}}
@ -70,8 +74,8 @@ if(!url){url=ulink('admin/backstage/backstageTask?op=collected&tid='+taskId)}
ajaxOpen({type:'get',dataType:'html',async:!0,url:url,success:function(data){$('#win_bk_collected_'+taskId).html(data)},complete:function(){if(!isNull(taskType)&&0==toInt(taskType)){winBackstageTask.collected_set_timeout=window.setTimeout(function(){var isEnd=$('#win_bk_tasks_box_0').find('a[href="#win_bk_collected_'+taskId+'"]').attr('data-is-end');var isVisible=$('#win_bk_tasks_box_0 #win_bk_collected_'+taskId).is(':visible');if(!isEnd&&isVisible){winBackstageTask.collected(taskId,taskType,url)}else{window.clearTimeout(winBackstageTask.collected_set_timeout)}},3000)}}})},init_collected:function(taskStatus,taskId){$('[id^="win_bk_collected_"] .pagination').addClass('pagination-sm');$('[id^="win_bk_collected_"] .pagination a').bind('click',function(){var curTaskId=$(this).parents('[id^="win_bk_collected_"]').eq(0).attr('data-task-id');var curTaskType=$(this).parents('[id^="win_bk_tasks_nav_"]').eq(0).attr('data-task-type');winBackstageTask.collected(curTaskId,curTaskType,$(this).attr('href'));return!1});if(taskStatus&&taskId){winBackstageTask.set_task_end(taskId,taskStatus);winBackstageTask.count();winBackstageTask.status()}},set_task_end:function(taskId,status){if(taskId&&status){$('#win_bk_tasks_box_0').find('a[href="#win_bk_collected_'+taskId+'"]').attr('data-is-end','1').find('.is_loading').html('<small>'+status+'</small>')}},status_set_timeout:null,status:function(isLoop){if(!isLoop){window.clearTimeout(winBackstageTask.status_set_timeout)}
var taskIds=[];$('#win_bk_tasks_box_0').find('[id^="win_bk_collected_"]').each(function(){var taskId=$(this).attr('data-task-id');taskIds.push(taskId)});if(taskIds.length>0){ajaxOpen({type:'post',dataType:'json',async:!0,data:{tids:taskIds},url:ulink('admin/backstage/backstageTask?op=status'),success:function(data){var statusList=data.data;if(isObject(statusList)){for(var tid in statusList){if(statusList[tid]){winBackstageTask.set_task_end(tid,statusList[tid])}}}
var isVisible=$('#win_bk_tasks_box_0').is(':visible');var isEnd=!0;$('#win_bk_tasks_box_0').find('a[href^="#win_bk_collected_"]').each(function(){if(!$(this).attr('data-is-end')){isEnd=!1;return!1}});if(!isEnd&&isVisible){winBackstageTask.status_set_timeout=window.setTimeout(function(){winBackstageTask.status(!0)},3000)}else{window.clearTimeout(winBackstageTask.status_set_timeout)}}})}}};function ajax_check_userpwd(ajaxSet){var oldSuccess=ajaxSet.success;ajaxSet.success=function(data){if(data.data&&data.data._check_pwd_){if(data.msg){toastr.error(data.msg)}
var msg='<div style="text-align:left;"><div style="margin-bottom:8px;">该操作需要验证您的登录密码</div>'+'<input class="form-control" type="password" id="confirm_ipt_check_pwd" placeholder="登录密码" />'+'<div class="checkbox" style="margin-bottom:0;"><label><input type="checkbox" value="1" id="confirm_ipt_check_skip" checked="checked" /> 1小时内不再验证</label></div></div>';confirmRight({closeAfterFunc:!0,yes:'确定',no:'取消',msg:msg},function(){var ajaxSetData=isNull(ajaxSet.data)?{}:ajaxSet.data;var checkPwd=$('#confirm_ipt_check_pwd').val();var checkSkip=$('#confirm_ipt_check_skip').is(':checked')?1:'';if(typeof(ajaxSetData)=='object'){ajaxSetData._check_pwd_=checkPwd;ajaxSetData._check_skip_=checkSkip}else{ajaxSetData=ajaxSetData?(ajaxSetData+'&'):'';ajaxSetData+='_check_pwd_='+encodeURIComponent(checkPwd);ajaxSetData+='&_check_skip_='+encodeURIComponent(checkSkip)}
ajaxSet.data=ajaxSetData;ajaxSet.success=oldSuccess;ajax_check_userpwd(ajaxSet)});$('body').on('keyup','#confirm_ipt_check_pwd',function(event){if(event.keyCode=="13"){$('#confirm_right .cr-btn-yes').trigger("click")}})}else{if(oldSuccess&&typeof(oldSuccess)=='function'){oldSuccess(data)}}};ajaxOpen(ajaxSet)}
var msg='<div style="text-align:left;"><div style="margin-bottom:8px;">该操作需要验证您的登录密码</div>'+'<input class="form-control" type="password" id="confirm_ipt_check_pwd" placeholder="登录密码" />'+'<div class="checkbox" style="margin-bottom:0;"><label><input type="checkbox" value="1" id="confirm_ipt_check_skip" '+(admincpOp.getConfig('check_skip')?' checked="checked" ':'')+' /> 1小时内不再验证</label></div></div>';confirmRight({closeAfterFunc:!0,yes:'确定',no:'取消',msg:msg},function(){var ajaxSetData=isNull(ajaxSet.data)?{}:ajaxSet.data;var checkPwd=$('#confirm_ipt_check_pwd').val();var checkSkip=$('#confirm_ipt_check_skip').is(':checked')?1:'';if(typeof(ajaxSetData)=='object'){ajaxSetData._check_pwd_=checkPwd;ajaxSetData._check_skip_=checkSkip}else{ajaxSetData=ajaxSetData?(ajaxSetData+'&'):'';ajaxSetData+='_check_pwd_='+encodeURIComponent(checkPwd);ajaxSetData+='&_check_skip_='+encodeURIComponent(checkSkip)}
ajaxSet.data=ajaxSetData;ajaxSet.success=oldSuccess;ajax_check_userpwd(ajaxSet)});$('#confirm_ipt_check_skip').bind('click',function(){admincpOp.config('check_skip',$(this).is(':checked')?1:0)});$('body').on('keyup','#confirm_ipt_check_pwd',function(event){if(event.keyCode=="13"){$('#confirm_right .cr-btn-yes').trigger("click")}})}else{if(oldSuccess&&typeof(oldSuccess)=='function'){oldSuccess(data)}}};ajaxOpen(ajaxSet)}
function editorCodeIfr(ifrEle,options){options=isObject(options)?options:{};if(options.set_value!=null&&typeof(options.set_value)!='undefined'){$(document).ready(function(){$(ifrEle).attr('src','');$(ifrEle).attr('src',ulink('develop/editor_code'));$(ifrEle).off('load').bind('load',function(){if(options.set_value&&$(ifrEle)[0].contentWindow.editor_code_op){$(ifrEle)[0].contentWindow.editor_code_op.set(options.set_value)}})})}else if(options.get_value){var ifrEle=$(ifrEle)[0];var val='';if(ifrEle&&ifrEle.contentWindow.editor_code_op){val=ifrEle.contentWindow.editor_code_op.get()}
return val}}
var ruleInsertSign={match:function(toObj,options){if(!options){options={}}

@ -8,7 +8,7 @@
|--------------------------------------------------------------------------
*/
'use strict';function CollectorPattern(){this.formid='#form_coll';this.cpFrontUrl=null;this.cpLevelUrl=null;this.cpRelationUrl=null;this.cpUrlWeb=null;this.cpRenderer=null;this.cpContentSign=null;this.cpPagination=null;this.cpField=null;this.cpProcess=null}
CollectorPattern.prototype={constructor:CollectorPattern,init:function(){var $_o=this;$($_o.formid).bind('submit',function(){$('#coll_tab_content').find('.tab-pane[id^="coll_pattern_"]').each(function(){if($(this).hasClass('active')){$($_o.formid+' [name="tab_link"]').val($(this).attr('id'));return}});var settings=getFormAjaxSettings($(this));settings.data={'_post_data_':settings.data};ajaxOpen(settings);return!1});$_o.cpFrontUrl=new CpFrontUrl($_o);$_o.cpLevelUrl=new CpLevelUrl($_o);$_o.cpRelationUrl=new CpRelationUrl($_o);$_o.cpUrlWeb=new CpUrlWeb($_o);$_o.cpRenderer=new CpRenderer($_o);$_o.cpContentSign=new CpContentSign($_o);$_o.cpPagination=new CpPagination($_o);$_o.cpField=new CpField($_o);$_o.cpProcess=new CpProcess($_o);inputSelectCustom($_o.formid+' select[name="config[charset]"]','config[charset_custom]',null,null,function(){$_o.cpUrlWeb.def_config_charset('')});inputSelectCustom($_o.formid+' select[name="config[encode]"]','config[encode_custom]',null,null,function(){$_o.cpUrlWeb.def_config_encode('')});$($_o.formid+' [name="config[page_render]"]').bind('click',function(){$_o.cpRenderer.def_config_renderer_open('')});$($_o.formid+' [name="config[request_headers][open]"]').bind('click',function(){$_o.cpUrlWeb.def_config_header_global('')});$($_o.formid+' #coll_pattern_request_headers .dm-useragent li a').bind('click',function(){$($_o.formid+' [name="config[request_headers][useragent]"]').val($(this).attr('data-useragent'))});$($_o.formid+' #coll_pattern_request_headers .add-request-header').bind('click',function(){$_o.add_request_header('','')});$($_o.formid+' #coll_pattern_request_headers .add-request-header-img').bind('click',function(){$_o.add_request_header_img('','')});$($_o.formid+' #coll_pattern_request_headers .add-request-header-file').bind('click',function(){$_o.add_request_header_file('','')});$($_o.formid+' .c-p-request-headers').on('click','.delete-request-header',function(){$(this).parents('tr').eq(0).remove()});$($_o.formid+' .c-p-request-headers-img').on('click','.delete-request-header-img',function(){$(this).parents('tr').eq(0).remove()});$($_o.formid+' .c-p-request-headers-file').on('click','.delete-request-header-file',function(){$(this).parents('tr').eq(0).remove()});$_o.init_page_list_op('front_url');$(this.formid+' #coll_pattern_source_url .add-source-url').bind('click',function(){windowModal('添加起始网址',ulink("cpattern/source"),{lg:1})});$(this.formid+' #coll_pattern_source_url .clear-source-url').bind('click',function(){$_o.source_op('clear_all')});$(this.formid+' #coll_pattern_source_url').on('click','.edit-source-url',function(){var parent=$(this).parents('[id^="source_url_"]').eq(0);var objid=parent.attr('id');var sourceUrl=parent.find('[name="config[source_url][]"]').val();sourceUrl=sourceUrl?sourceUrl:'';var url=ulink("cpattern/source");var options={lg:1};if(objid||sourceUrl){options.ajax={type:'post',data:{'source_url':sourceUrl,'objid':objid}}}
CollectorPattern.prototype={constructor:CollectorPattern,init:function(){var $_o=this;$($_o.formid).bind('submit',function(){$('#coll_tab_content').find('.tab-pane[id^="coll_pattern_"]').each(function(){if($(this).hasClass('active')){$($_o.formid+' [name="tab_link"]').val($(this).attr('id'));return}});var settings=getFormAjaxSettings($(this));settings.data={'_post_data_':settings.data};ajaxOpen(settings);return!1});$_o.cpFrontUrl=new CpFrontUrl($_o);$_o.cpLevelUrl=new CpLevelUrl($_o);$_o.cpRelationUrl=new CpRelationUrl($_o);$_o.cpUrlWeb=new CpUrlWeb($_o);$_o.cpRenderer=new CpRenderer($_o);$_o.cpContentSign=new CpContentSign($_o);$_o.cpPagination=new CpPagination($_o);$_o.cpField=new CpField($_o);$_o.cpProcess=new CpProcess($_o);inputSelectCustom($_o.formid+' select[name="config[charset]"]','config[charset_custom]',null,null,function(){$_o.cpUrlWeb.def_config_charset('')});inputSelectCustom($_o.formid+' select[name="config[encode]"]','config[encode_custom]',null,null,function(){$_o.cpUrlWeb.def_config_encode('')});$($_o.formid+' [name="config[page_render]"]').bind('click',function(){$_o.cpRenderer.def_config_renderer_open('')});$($_o.formid+' [name="config[request_headers][open]"]').bind('click',function(){$_o.cpUrlWeb.def_config_header_global('')});$($_o.formid+' #coll_pattern_request_headers .dm-useragent li a').bind('click',function(){$($_o.formid+' [name="config[request_headers][useragent]"]').val($(this).attr('data-useragent'))});$($_o.formid+' #coll_pattern_request_headers .add-request-header').bind('click',function(){$_o.add_request_header('','')});$($_o.formid+' #coll_pattern_request_headers .add-request-header-img').bind('click',function(){$_o.add_request_header_img('','')});$($_o.formid+' #coll_pattern_request_headers .add-request-header-file').bind('click',function(){$_o.add_request_header_file('','')});$($_o.formid+' .c-p-request-headers').on('click','.delete-request-header',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});$($_o.formid+' .c-p-request-headers-img').on('click','.delete-request-header-img',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});$($_o.formid+' .c-p-request-headers-file').on('click','.delete-request-header-file',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});$_o.init_page_list_op('front_url');$(this.formid+' #coll_pattern_source_url .add-source-url').bind('click',function(){windowModal('添加起始网址',ulink("cpattern/source"),{lg:1})});$(this.formid+' #coll_pattern_source_url .clear-source-url').bind('click',function(){$_o.source_op('clear_all')});$(this.formid+' #coll_pattern_source_url').on('click','.edit-source-url',function(){var parent=$(this).parents('[id^="source_url_"]').eq(0);var objid=parent.attr('id');var sourceUrl=parent.find('[name="config[source_url][]"]').val();sourceUrl=sourceUrl?sourceUrl:'';var url=ulink("cpattern/source");var options={lg:1};if(objid||sourceUrl){options.ajax={type:'post',data:{'source_url':sourceUrl,'objid':objid}}}
windowModal('添加起始网址',url,options)});$(this.formid+' #coll_pattern_source_url').on('click','.delete-source-url',function(){var obj=$(this);confirmRight(window.tpl_lang.confirm_delete,function(){obj.parents('[id^="source_url_"]').eq(0).remove()})});eleExchange(this.formid+' #coll_pattern_source_url','.icon-drag-move','[id^="source_url_"]');$(this.formid+' [name="config[source_is_url]"]').bind('click',function(){if($_o.source_is_url()){$('#coll_pattern_source_url').css('margin-bottom','0px');$('#alert_coll_pattern_link').show();$('#panel_coll_pattern_source_url_web').hide();$('#panel_coll_pattern_source_url_renderer').hide();$('#panel_coll_pattern_source_url_content_sign').hide();$('#panel_coll_pattern_source_url_pagination').hide();$('#panel_coll_pattern_level_url').hide();$('#panel_coll_pattern_url_content_sign').siblings('.panel').hide();$('#panel_coll_pattern_url_web').show();$('#panel_coll_pattern_url_renderer').show()}else{$('#coll_pattern_source_url').css('margin-bottom','15px');$('#alert_coll_pattern_link').hide();$('#panel_coll_pattern_source_url_web').show();$('#panel_coll_pattern_source_url_renderer').show();$('#panel_coll_pattern_source_url_content_sign').show();$('#panel_coll_pattern_source_url_pagination').show();$('#panel_coll_pattern_level_url').show();$('#panel_coll_pattern_url_content_sign').siblings('.panel').show()}});$_o.init_page('source_url');$_o.init_page('url');$($_o.formid).on('click','.c-p-url-page-signs .btn-page-signs',function(){$_o.parent_page_signs(this)});$_o.init_page_list_op('level_url');$_o.init_page_list_op('relation_url');$(this.formid+' #coll_pattern_field').on('click','.add-field',function(){$_o.field_editor(null,null)});$(this.formid+' #coll_pattern_field').on('click','.field-name',function(){$_o.field_editor($(this),null)});$(this.formid+' #coll_pattern_field').on('click','.add-field-default',function(){$_o.cpField.add_default()});$(this.formid+' #coll_pattern_field').on('click','.sort-field',function(){var fieldNames=$_o.get_field_names(!0);for(var i in fieldNames){var fieldTr=$($_o.formid+' #coll_pattern_field').find('.field-name[data-val="'+fieldNames[i]+'"]').parents('tr[id^="field_"]').eq(0);if(fieldTr.length>0){$($_o.formid+' #coll_pattern_field .c-p-field-list tbody').append(fieldTr)}}
toastr.success('调整完成')});$(this.formid+' #coll_pattern_field').on('click','.field-del',function(){var obj=$(this);confirmRight(window.tpl_lang.confirm_delete,function(){$_o.field_delete_tr(obj)})});$(this.formid+' #coll_pattern_field').on('click','.field-clone',function(){var tr=$(this).parents('tr[id^="field_"]').eq(0);var field=tr.find('[name="config[field_list][]"]').val();var process=tr.find('[name="config[field_process][]"]').val();confirmRight('确定复制字段?',function(){ajaxOpen({type:'POST',dataType:'json',url:ulink("cpattern/clone_field"),data:{field:field,process:process},success:function(data){if(data.code==1){data=data.data;var hasField=!1;do{data.field.name+='_1';hasField=$('#coll_pattern_field .c-p-field-list').find('.field-name[data-val="'+data.field.name+'"]');if(hasField&&hasField.length>0){hasField=!0}else{hasField=!1}}while(hasField);$_o.cpField.add(null,data.field,data.process);toastr.success('字段复制成功:'+data.field.name)}else{toastr.error(data.msg)}}})})});$(this.formid+' #coll_pattern_field').on('click','.field-process',function(){var process=$(this).parent().find('input[name="config[field_process][]"]').val();var prt=$(this).parents('tr[id^="field_"]').eq(0);var objid=prt.attr('id');var field=prt.find('.field-name').attr('data-val');var url=ulink("cpattern/process?task_id=_tid_&field=_field_",{'_tid_':$_o.get_task_id(),'_field_':field});windowModal('数据处理:'+field+'<small><a href="javascript:;" id="window_process_paste" title="粘贴" class="glyphicon glyphicon-paste" style="margin-left:7px;color:#888;"></a></small>',url,{lg:1,ajax:{type:'post',data:{objid:objid,process:process}}});$_o.process_paste()});$(this.formid+' #coll_pattern_process').on('click','.add-process',function(){var url=ulink("cpattern/process?task_id=_tid_&type=common",{'_tid_':$_o.get_task_id()});windowModal('数据处理(通用)<small><a href="javascript:;" id="window_process_paste" title="粘贴" class="glyphicon glyphicon-paste" style="color:#888;"></a></small>',url,{lg:1});$_o.process_paste()});eleExchange(this.formid+' #coll_pattern_field','.icon-drag-move','tr[id^="field_"]');$(this.formid+' [name="effective"]').val(1)},init_test:function(){var $_o=this;$_o.formid='#win_form_cache';$_o.cpUrlWeb=new CpUrlWeb($_o);$_o.cpRenderer=new CpRenderer($_o);$_o.cpUrlWeb.page_init('test');$_o.cpRenderer.page_init('test')},init_echo_url_msg:function(dataUrlWeb,dataRenderer){this.init_test();if(!isObject(dataUrlWeb)){dataUrlWeb={}}
if(!isObject(dataRenderer)){dataRenderer={}}
@ -123,7 +123,7 @@ ajaxOpen({type:'POST',dataType:'json',url:$($_o.formObj).attr('action'),data:$($
function CpUrlWeb(cpClass){this.$_cp=cpClass}
CpUrlWeb.prototype={constructor:CpUrlWeb,page_init:function(pageType,isPagination){var $_o=this;var pageVars=$_o.$_cp.get_page_vars(pageType,null,isPagination);var boxId=pageVars.boxId;var namePre=pageVars.namePre;if(!boxId||!namePre){return}
var boxUrlWebId=boxId+'_web';$(boxUrlWebId+' [name="'+namePre+'[url_web][open]"]').bind('click',function(){if($(this).val()==1){$(boxUrlWebId+'_open').show()}else{$(boxUrlWebId+'_open').hide()}
$_o.def_config_use_url_web(pageType)});inputSelectCustom(boxUrlWebId+' select[name="'+namePre+'[url_web][charset]"]',namePre+'[url_web][charset_custom]');inputSelectCustom(boxUrlWebId+' select[name="'+namePre+'[url_web][encode]"]',namePre+'[url_web][encode_custom]');$_o.def_config_charset(pageType);$_o.def_config_encode(pageType);$(boxUrlWebId+' select[name="'+namePre+'[url_web][form_method]"]').bind('change',function(){var obj=$(boxUrlWebId+' .c-p-url-web-content-type');if($(this).val()=='post'){obj.show()}else{obj.hide()}});$_o.def_config_header_global(pageType);$(boxUrlWebId+' .add-url-web-form').bind('click',function(){$_o.add_page_url_web(pageType,isPagination,'form','','')});$(boxUrlWebId+' .c-p-url-web-form').on('click','.delete-url-web-form',function(){$(this).parents('tr').eq(0).remove()});$(boxUrlWebId+' .add-url-web-header').bind('click',function(){$_o.add_page_url_web(pageType,isPagination,'header','','')});$(boxUrlWebId+' .c-p-url-web-header').on('click','.delete-url-web-header',function(){$(this).parents('tr').eq(0).remove()})},page_load:function(pageType,urlWebConfig,isPagination){var $_o=this;var pageVars=$_o.$_cp.get_page_vars(pageType,null,isPagination);var formId=pageVars.formId;var boxId=pageVars.boxId;var namePre=pageVars.namePre;if(!formId||!boxId||!namePre){return}
$_o.def_config_use_url_web(pageType)});inputSelectCustom(boxUrlWebId+' select[name="'+namePre+'[url_web][charset]"]',namePre+'[url_web][charset_custom]');inputSelectCustom(boxUrlWebId+' select[name="'+namePre+'[url_web][encode]"]',namePre+'[url_web][encode_custom]');$_o.def_config_charset(pageType);$_o.def_config_encode(pageType);$(boxUrlWebId+' select[name="'+namePre+'[url_web][form_method]"]').bind('change',function(){var obj=$(boxUrlWebId+' .c-p-url-web-content-type');if($(this).val()=='post'){obj.show()}else{obj.hide()}});$_o.def_config_header_global(pageType);$(boxUrlWebId+' .add-url-web-form').bind('click',function(){$_o.add_page_url_web(pageType,isPagination,'form','','')});$(boxUrlWebId+' .c-p-url-web-form').on('click','.delete-url-web-form',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});$(boxUrlWebId+' .add-url-web-header').bind('click',function(){$_o.add_page_url_web(pageType,isPagination,'header','','')});$(boxUrlWebId+' .c-p-url-web-header').on('click','.delete-url-web-header',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})})},page_load:function(pageType,urlWebConfig,isPagination){var $_o=this;var pageVars=$_o.$_cp.get_page_vars(pageType,null,isPagination);var formId=pageVars.formId;var boxId=pageVars.boxId;var namePre=pageVars.namePre;if(!formId||!boxId||!namePre){return}
if(!isObject(urlWebConfig)){urlWebConfig={}}
var urlWebNamePre=namePre+'[url_web]';urlWebConfig.open=toInt(urlWebConfig.open);$(formId+' [name="'+urlWebNamePre+'[open]"][value="'+urlWebConfig.open+'"]').trigger('click');if(urlWebConfig.open>0){showPanelCollapse(boxId+'_web')}
if(urlWebConfig.charset){$(formId+' select[name="'+urlWebNamePre+'[charset]"]').val(urlWebConfig.charset).trigger('change')}
@ -149,7 +149,7 @@ CpRenderer.prototype={constructor:CpRenderer,page_init:function(pageType,isPagin
$_o.def_config_renderer_open(pageType);var rdBoxId=boxId+'_renderer';$(rdBoxId+' .add-url-renderer').bind('click',function(){$_o.add(pageType,isPagination)});$(rdBoxId+' [name="'+namePre+'[renderer][open]"]').bind('click',function(){$_o.def_config_use_renderer(pageType)});if(isPagination){$(rdBoxId+' [name="'+namePre+'[renderer][open_pn]"]').bind('click',function(){if($(this).val()==1){$(rdBoxId+'_open_pn').show()}else{$(rdBoxId+'_open_pn').hide()}})}
$(rdBoxId+' .c-p-url-renderer-list').on('change','select[name="'+namePre+'[renderer][types][]"]',function(){var type=$(this).val();var tr=$(this).parents('tr').eq(0);var types={'wait_time':{content:1,content_tips:'输入数字'},'scroll_top':{content:1,content_tips:'输入数字'},'click':{element:1},'val':{element:1,content:1,content_tips:'输入值'}};var tdTypeCols=3;tr.find('.td-renderer-element,.td-renderer-content').hide();tr.find('input[name="'+namePre+'[renderer][contents][]"]').attr('placeholder','');var curType=types[type];if(isObject(curType)){if(curType.element){tr.find('.td-renderer-element').show();tdTypeCols-=1}
if(curType.content){tr.find('.td-renderer-content').show();tdTypeCols-=1;if(curType.content_tips){tr.find('input[name="'+namePre+'[renderer][contents][]"]').attr('placeholder',curType.content_tips)}}}
tr.find('.td-renderer-type').attr('colspan',tdTypeCols)});$(rdBoxId+' .c-p-url-renderer-list').on('click','.delete-url-renderer',function(){$(this).parents('tr').eq(0).remove()});eleExchange(rdBoxId+' .c-p-url-renderer-list','.icon-drag-move','tr')},page_load:function(pageType,rdConfig,isPagination){var $_o=this;var pageVars=$_o.$_cp.get_page_vars(pageType,null,isPagination);var boxId=pageVars.boxId;var namePre=pageVars.namePre;if(!boxId||!namePre){return}
tr.find('.td-renderer-type').attr('colspan',tdTypeCols)});$(rdBoxId+' .c-p-url-renderer-list').on('click','.delete-url-renderer',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});eleExchange(rdBoxId+' .c-p-url-renderer-list','.icon-drag-move','tr')},page_load:function(pageType,rdConfig,isPagination){var $_o=this;var pageVars=$_o.$_cp.get_page_vars(pageType,null,isPagination);var boxId=pageVars.boxId;var namePre=pageVars.namePre;if(!boxId||!namePre){return}
var rdBoxId=boxId+'_renderer';if(isObject(rdConfig)){$(rdBoxId).find('[name="'+namePre+'[renderer][open]"][value="'+rdConfig.open+'"]').prop('checked',!0).trigger('click');var rdTypes=isObject(rdConfig.types)?rdConfig.types:[];var rdElements=isObject(rdConfig.elements)?rdConfig.elements:[];var rdContents=isObject(rdConfig.contents)?rdConfig.contents:[];var showPanel=!1;var openVal=rdConfig.open=='y'?true:!1;var openDef=$($_o.$_cp.formid+' [name="config[page_render]"]:checked').val();openDef=toInt(openDef);openDef=openDef>0?true:!1;if(rdTypes&&rdTypes.length>0){for(var i in rdTypes){$_o.add(pageType,isPagination,rdTypes[i],rdElements[i],rdContents[i])}
if((!rdConfig.open&&openDef)||openVal){showPanel=!0}}else{if(rdConfig.open){if(openVal!=openDef){showPanel=!0}}}
if(isPagination){$(rdBoxId+' [name="'+namePre+'[renderer][open_pn]"][value="'+rdConfig.open_pn+'"]').prop('checked',!0).trigger('click');if(rdConfig.open_pn){showPanel=!0}else{showPanel=!1}}
@ -186,12 +186,13 @@ $($_o.formObj+' #c_p_field_time_format_list').on('click','a[data-val]',function(
if(!fieldData.hasOwnProperty('source')){$($_o.formObj+' [name="field[source]"]').trigger("change")}
$($_o.formObj+' [name="field[num_start]"]').val(toInt(fieldData.num_start));$($_o.formObj+' [name="field[num_end]"]').val(toInt(fieldData.num_end));$($_o.formObj+' [name="field[auto]"][value="'+fieldData.auto+'"]').prop('checked',!0);if(fieldData.time_stamp){$($_o.formObj+' [name="field[time_stamp]"]').prop('checked',!0)}
cpRuleModuleLoad($_o.formObj,'field','',fieldData);cpRuleModuleLoad($_o.formObj,'field','extract_',fieldData)}},add:function(objid,fieldData,processData){var $_o=this;var fieldSource='内容页';if(fieldData.source){var fsource=fieldData.source.split(':');fieldSource=$_o.$_cp.get_page_vars(fsource[0],'title');if(fsource[1]){fieldSource+=''+fsource[1]}}
var isLoop='';if(fieldData.module=='rule'){if(fieldData.rule_multi&&fieldData.rule_multi_type=='loop'){isLoop=' - 循环入库'}}else if(fieldData.module=='xpath'){if(fieldData.xpath_multi&&fieldData.xpath_multi_type=='loop'){isLoop=' - 循环入库'}}else if(fieldData.module=='json'){if(fieldData.json_loop){isLoop=' - 循环入库'}}else if(fieldData.module=='extract'||fieldData.module=='merge'){$($_o.$_cp.formid+' #coll_pattern_field').find('.sort-field').show()}
if(isLoop){$('#c_p_field_loop_tips').show()}
if(objid){var eleObj=$($_o.$_cp.formid+' #'+objid);eleObj.find('.field-name').attr('data-val',fieldData.name).text(fieldData.name);eleObj.find('.field-source').attr('data-val',fieldData.source).text(fieldSource);eleObj.find('.field-module').attr('data-val',fieldData.module).text(window.tpl_lang['field_module_'+fieldData.module]+isLoop);if(isLoop){eleObj.find('.field-module').attr('data-is-loop',1)}else{eleObj.find('.field-module').removeAttr('data-is-loop')}
var fieldModule=window.tpl_lang['field_module_'+fieldData.module];var isLoop=!1;if(fieldData.module=='rule'){if(fieldData.rule_multi&&fieldData.rule_multi_type=='loop'){isLoop=!0}}else if(fieldData.module=='xpath'){if(fieldData.xpath_multi&&fieldData.xpath_multi_type=='loop'){isLoop=!0}}else if(fieldData.module=='json'){if(fieldData.json_loop){isLoop=!0}}else if(fieldData.module=='extract'||fieldData.module=='merge'){$($_o.$_cp.formid+' #coll_pattern_field').find('.sort-field').show();if(fieldData.module=='extract'){if(fieldData.extract_module=='rule'){if(fieldData.extract_rule_multi&&fieldData.extract_rule_multi_type=='loop'){isLoop=!0}}else if(fieldData.extract_module=='xpath'){if(fieldData.extract_xpath_multi&&fieldData.extract_xpath_multi_type=='loop'){isLoop=!0}}else if(fieldData.extract_module=='json'){if(fieldData.extract_json_loop){isLoop=!0}}
fieldModule+=' » '+(fieldData.extract?fieldData.extract:'')}}
if(isLoop){$('#c_p_field_loop_tips').show();fieldModule+='(循环入库)'}
if(objid){var eleObj=$($_o.$_cp.formid+' #'+objid);eleObj.find('.field-name').attr('data-val',fieldData.name).text(fieldData.name);eleObj.find('.field-source').attr('data-val',fieldData.source).text(fieldSource);eleObj.find('.field-module').attr('data-val',fieldData.module).text(fieldModule);if(isLoop){eleObj.find('.field-module').attr('data-is-loop',1)}else{eleObj.find('.field-module').removeAttr('data-is-loop')}
eleObj.find('input[name="config[field_list][]"]').val(encode_json2urlbase(fieldData))}else{var ptitle='';if(processData){ptitle=[];for(var i in processData){ptitle.push(window.tpl_lang['process_module_'+processData[i].module]+(processData[i].title?(''+processData[i].title):''))}
ptitle=ptitle.join(' / ')}
var html=$_o.$_cp.clone_tpl('#coll_tpl_field');html.attr('id','field_'+generateUUID());html.find('.field-name').attr('data-val',fieldData.name).text(fieldData.name);html.find('.field-source').attr('data-val',fieldData.source).text(fieldSource);html.find('.field-module').attr('data-val',fieldData.module).text(window.tpl_lang['field_module_'+fieldData.module]+isLoop);if(isLoop){html.find('.field-module').attr('data-is-loop',1)}else{html.find('.field-module').removeAttr('data-is-loop')}
var html=$_o.$_cp.clone_tpl('#coll_tpl_field');html.attr('id','field_'+generateUUID());html.find('.field-name').attr('data-val',fieldData.name).text(fieldData.name);html.find('.field-source').attr('data-val',fieldData.source).text(fieldSource);html.find('.field-module').attr('data-val',fieldData.module).text(fieldModule);if(isLoop){html.find('.field-module').attr('data-is-loop',1)}else{html.find('.field-module').removeAttr('data-is-loop')}
html.find('[name="config[field_list][]"]').val(encode_json2urlbase(fieldData));html.find('[name="config[field_process][]"]').val(processData?encode_json2urlbase(processData):'');if(processData&&ptitle){html.find('.field-process').addClass('exist-process')}
html.find('.field-process').attr('title',ptitle);html.find('[name="config[field_title]"]').val(fieldData.name);html.find('[name="config[field_content][]"]').val(fieldData.name);$($_o.$_cp.formid+' #coll_pattern_field .c-p-field-list tbody').append(html)}},add_sub:function(){var $_o=this;var objid=$($_o.formObj+' input[name="objid"]').val();var checkName=!0;if(objid){var fname=$($_o.$_cp.formid+' #'+objid).find('.field-name').attr('data-val');if(fname==$($_o.formObj+' input[name="field[name]"]').val()){checkName=!1}}
if(checkName){var hasName=!1;var fieldNames=$_o.$_cp.get_field_names();for(var i in fieldNames){if($($_o.formObj+' input[name="field[name]"]').val()==fieldNames[i]){hasName=!0;break}}
@ -202,7 +203,7 @@ function CpProcess(cpClass){this.$_cp=cpClass;this.processForm='';this.processBo
CpProcess.prototype={constructor:CpProcess,init:function(processData,isCommon,isCommonLoad){var $_o=this;$_o.processForm=isCommon?$_o.processFormCommon:$_o.processFormField;if(isCommon&&isCommonLoad){$_o.processBox=$_o.processBoxCommon}else{$_o.processBox=$_o.processBoxField}
if($($_o.processForm).is('form')){$($_o.processForm).bind('submit',function(){$_o.add_sub();return!1})}
$($_o.processBox+' .process-add').bind('click',function(){var module=$($_o.processBox+' select[name="process[module]"]').val();$_o.add({'add_new':1,'module':module})});if($($_o.processForm).prop('inited')==1){return!0}
$($_o.processForm).on('click','.p-m-html-tags a[data-val]',function(){var tag=$(this).attr('data-val');var moduleHtml=$(this).parents('.p-m-html-tags').eq(0).attr('module-html');var tagsObj=$(this).parents('section').eq(0).find('input[data-process="html:'+moduleHtml+'"]');var tags=tagsObj.val()+','+tag;tags=tags.replace(/(^,+)|(,+$)/,'');tagsObj.val(tags)});$($_o.processForm).on('change','[data-process="insert:insert_loc"]',function(){var helpEle=$(this).siblings('.help-block');if($(this).val()=='rand'){helpEle.show()}else{helpEle.hide()}});inputSelectCustom(null,null,{box:$_o.processForm,slt:'[data-process="translate:translate_from"]',ipt:'[data-process="translate:translate_from_custom"]'});inputSelectCustom(null,null,{box:$_o.processForm,slt:'[data-process="translate:translate_to"]',ipt:'[data-process="translate:translate_to_custom"]'});$_o.txt_insert_field($_o.processForm,'.p-m-func-field',function(sltObj){return $(sltObj).parents('section').eq(0).find('[data-process="func:func_param"]')});$($_o.processForm).on('click','.p-m-if-add',function(){var ifTable=$(this).parents('section').eq(0).find('.p-m-if-table');ifTable.append('<tr>'+ifTable.attr('data-tpl')+'</tr>')});$($_o.processForm).on('click','.p-m-if-del',function(){var tr=$(this).parents('tr').eq(0);confirmRight('确定删除?',function(){tr.remove()})});$($_o.processForm).on('change','[data-process="if:if_cond:"]',function(){var ifCond=$(this).val();var ifTr=$(this).parents('tr').eq(0);var ifTd=ifTr.find('.p-m-if-val').eq(0);var ifVal=ifTd.find('[data-process="if:if_val:"]').eq(0);var ifValInfo={name:ifVal.attr('name'),val:ifVal.val(),process:ifVal.attr('data-process')};var ifValType='def';if(ifCond=='func'){ifValType='func'}else if(ifCond.indexOf('time_')>-1){ifValType='time'}
$($_o.processForm).on('click','.p-m-html-tags a[data-val]',function(){var tag=$(this).attr('data-val');var moduleHtml=$(this).parents('.p-m-html-tags').eq(0).attr('module-html');var tagsObj=$(this).parents('section').eq(0).find('input[data-process="html:'+moduleHtml+'"]');var tags=tagsObj.val()+','+tag;tags=tags.replace(/(^,+)|(,+$)/,'');tagsObj.val(tags)});$($_o.processForm).on('change','[data-process="insert:insert_loc"]',function(){var helpEle=$(this).siblings('.help-block');if($(this).val()=='rand'){helpEle.show()}else{helpEle.hide()}});$_o.txt_insert_field($_o.processForm,'.p-m-insert-field',function(sltObj){return $(sltObj).parents('section').eq(0).find('[data-process="insert:insert_txt"]')});inputSelectCustom(null,null,{box:$_o.processForm,slt:'[data-process="translate:translate_from"]',ipt:'[data-process="translate:translate_from_custom"]'});inputSelectCustom(null,null,{box:$_o.processForm,slt:'[data-process="translate:translate_to"]',ipt:'[data-process="translate:translate_to_custom"]'});$_o.txt_insert_field($_o.processForm,'.p-m-func-field',function(sltObj){return $(sltObj).parents('section').eq(0).find('[data-process="func:func_param"]')});$($_o.processForm).on('click','.p-m-if-add',function(){var ifTable=$(this).parents('section').eq(0).find('.p-m-if-table');ifTable.append('<tr>'+ifTable.attr('data-tpl')+'</tr>')});$($_o.processForm).on('click','.p-m-if-del',function(){var tr=$(this).parents('tr').eq(0);confirmRight('确定删除?',function(){tr.remove()})});$($_o.processForm).on('change','[data-process="if:if_cond:"]',function(){var ifCond=$(this).val();var ifTr=$(this).parents('tr').eq(0);var ifTd=ifTr.find('.p-m-if-val').eq(0);var ifVal=ifTd.find('[data-process="if:if_val:"]').eq(0);var ifValInfo={name:ifVal.attr('name'),val:ifVal.val(),process:ifVal.attr('data-process')};var ifValType='def';if(ifCond=='func'){ifValType='func'}else if(ifCond.indexOf('time_')>-1){ifValType='time'}
ifTd.find('.p-m-if-val-def,.p-m-if-val-time,.p-m-if-val-func').hide();ifTd.find('[data-process="if:if_val:"]').removeAttr('name').removeAttr('data-process');var ifValBox=ifTd.find('.p-m-if-val-'+ifValType);var ifValEle=ifValBox.find('.p-m-if-val-ele');ifValEle.attr('name',ifValInfo.name).attr('data-process',ifValInfo.process).val(ifValInfo.val);ifValBox.show();if(ifValType=='func'){$_o.load_if_func(ifTd,null)}});$($_o.processForm).on('change','.p-m-if-val-time-date select',function(){$(this).parents('tr').eq(0).find('[data-process="if:if_val:"]').val($(this).val())});$($_o.processForm).on('click','.p-m-if-val-func-info',function(){pluginFuncOp.tips('processIf')});$_o.txt_insert_field($_o.processForm,'.p-m-if-val-func-field select',function(sltObj){return $(sltObj).parents('td').eq(0).find('[data-process="if:if_val:"]')});$($_o.processForm).on('click','.p-m-if-info',function(){var tips='<p>执行顺序:从上至下判断,逻辑符“并且”的优先级高于“或者”</p>'+'<p>例如(字母表示条件):</p>'+'<p>a &amp;&amp; b || c &amp;&amp; d &amp;&amp; e || f || g &amp;&amp; h &amp;&amp; i &amp;&amp; j 等同于</p>'+'<p>(a &amp;&amp; b) || (c &amp;&amp; d &amp;&amp; e) || f || (g &amp;&amp; h &amp;&amp; i &amp;&amp; j)</p>'+'<p>括号中的条件都为真时才是真否则为假,整条语句中任意一个括号的结果为真最终结果为真,都为假最终结果为假</p>';confirmRight({msg:tips,yes:'确定',width:500,textAlign:'left'})});$_o.txt_insert_field($_o.processForm,'.p-m-api-url-field select',function(sltObj){return $(sltObj).parents('section').eq(0).find('[data-process="api:api_url"]')});$($_o.processForm).on('click','.p-m-api-add',function(){var apiTable=$(this).parents('section').eq(0).find('.p-m-api-table table');apiTable.find('tbody').append('<tr>'+apiTable.attr('data-tpl')+'</tr>')});$($_o.processForm).on('click','.p-m-api-del',function(){var tr=$(this).parents('tr').eq(0);tr.remove()});inputSelectCustom(null,null,{box:$_o.processForm,slt:'[data-process="api:api_charset"]',ipt:'[data-process="api:api_charset_custom"]'});inputSelectCustom(null,null,{box:$_o.processForm,slt:'[data-process="api:api_encode"]',ipt:'[data-process="api:api_encode_custom"]'});$($_o.processForm).on('change','[data-process="api:api_params:val:"],[data-process="api:api_headers:val:"]',function(){var isHeader=!1;if($(this).attr('data-process')=='api:api_headers:val:'){isHeader=!0}
var val=$(this).val();var tdObj=$(this).parents('td').eq(0);var iptObj=tdObj.find('[data-process="api:'+(isHeader?'api_headers':'api_params')+':addon:"]');var sltObj=tdObj.find('.p-m-api-'+(isHeader?'header':'val')+'-field');iptObj.hide();sltObj.hide();if(val=='time'||val=='custom'){if(val=='time'){iptObj.attr('placeholder','默认格式Y-m-d H:i:s')}else if(val=='custom'){iptObj.attr('placeholder','输入任何内容');sltObj.css('display','table-cell')}
iptObj.show()}});$_o.txt_insert_field($_o.processForm,'.p-m-api-val-field select',function(sltObj){return $(sltObj).parents('td').eq(0).find('[data-process="api:api_params:addon:"]')});$_o.txt_insert_field($_o.processForm,'.p-m-api-header-field select',function(sltObj){return $(sltObj).parents('td').eq(0).find('[data-process="api:api_headers:addon:"]')});$($_o.processForm).on('click','.p-m-api-header-add',function(){var apiHdTable=$(this).parents('section').eq(0).find('.p-m-api-header-table table');apiHdTable.find('tbody').append('<tr>'+apiHdTable.attr('data-tpl')+'</tr>')});$($_o.processForm).on('click','.p-m-api-header-del',function(){var tr=$(this).parents('tr').eq(0);tr.remove()});$($_o.processForm).on('change','[data-process="api:api_type"]',function(){var obj=$(this).parents('section').eq(0).find('.p-m-api-content-type');if($(this).val()=='post'){obj.show()}else{obj.hide()}});$($_o.processForm).on('change','[data-process="api:api_rule_module"]',function(){var ruleModule=$(this).val();ruleModule=ruleModule?ruleModule:'';var obj=$(this).parents('section').eq(0);obj.find('.p-m-api-rule-module').hide();obj.find('.p-m-api-rule-module[data-rule-module="'+ruleModule+'"]').show()});cpRuleModuleInit($_o.processForm,'data-process','api:api_');$($_o.processForm).on('change','[data-process="download:download_op"]',function(){var obj=$(this).parents('section').eq(0);var val=$(this).val();obj.find('.p-m-download-op').hide();obj.find('.p-m-download-op[data-op="'+val+'"]').show()});$($_o.processForm).on('click','.p-m-download-file-tag .dropdown-menu a[data-val]',function(){var prt=$(this).parents('.p-m-download-file-tag').eq(0);var obj=prt.find('[data-process="download:download_file_tag"]');var val=obj.val();if(val){val=val.split(',')}else{val=new Array()}

@ -0,0 +1,21 @@
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
'use strict';function DataapiClass(){this.formid='#form_dataapi'}
DataapiClass.prototype={constructor:DataapiClass,init_list:function(search){$('#dataapi_list .delete').bind('click',function(){var curTr=$(this).parents('tr[data-da-id]').eq(0);confirmRight('删除后将无法请求该接口!确定删除?',function(){ajaxOpen({type:'post',url:ulink('dataapi/op?op=delete'),data:{'id':curTr.attr('data-da-id')},success:function(data){ajaxDataMsg(data);if(data.code==1){curTr.remove()}}})})});$('#dataapi_list .status').bind('click',function(){var curTr=$(this).parents('tr[data-da-id]').eq(0);var curObj=$(this);ajaxOpen({type:'post',url:ulink('dataapi/op?op=status'),data:{'id':curTr.attr('data-da-id'),'status':(curObj.hasClass('status-close')?0:1)},success:function(data){ajaxDataMsg(data);data=data.data;if(data.status){curObj.removeClass('status-close').html('开启')}else{curObj.addClass('status-close').html('关闭')}}})});if(isObject(search)){for(var i in search){$('#form_search').find('[name="'+i+'"]').val(search[i])}}},init:function(dataapi){var $_o=this;$('#btn_dataset').bind('click',function(){windowModal('数据集',ulink('dataset/select?from=dataapi'))});$('#tips_config_cond').bind('click',function(){confirmRight({msg:'<b>传入参数名:</b>请求接口时url中传入或post提交数据中的参数名称',yes:'确定',textAlign:'left'})});$('#add_config_cond').bind('click',function(){$_o.add_cond(null)});$('#config_conds').on('click','.config-cond-add',function(){$_o.add_cond({sub:1},this)});$('#config_conds').on('change','[name="conds[field][]"]',function(){var curTr=$(this).parents('tr[id^="cond_"]').eq(0);var fname=$(this).val();fname=fname?('默认:'+fname):'';curTr.find('[name="conds[name][]"]').attr('placeholder',fname)});$('#config_conds').on('click','.config-cond-dlt',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr[id^="cond_"]').remove();$_o.first_cond()})});eleExchange('#config_conds','.config-cond-move','tr[id^="cond_"]',{stop:function(event,ui){$_o.first_cond()}});if(isObject(dataapi)){$($_o.formid).find('[name="name"]').val(dataapi.name?dataapi.name:'');$($_o.formid).find('[name="route"]').val(dataapi.route?dataapi.route:'');$($_o.formid).find('[name="desc"]').val(dataapi.desc?dataapi.desc:'');$($_o.formid).find('[name="sort"]').val(dataapi.sort?toInt(dataapi.sort):0);$($_o.formid).find('[name="status"][value="'+toInt(dataapi.status)+'"]').prop('checked',!0);var config=dataapi.config;$_o.dataset_load({'dataset_id':dataapi.ds_id},dataapi.config)}},first_cond:function(){var firstObj=$('#config_conds').find('tr[id^="cond_"]:first').eq(0);if(firstObj.hasClass('config-cond-sub')){firstObj.removeClass('config-cond-sub');firstObj.find('[name="conds[sub][]"]').val('')}},add_cond:function(cond,curObj){cond=isObject(cond)?cond:null;var trId='cond_'+generateUUID();var tr=$('#tpl_config_cond').clone();tr.attr('id',trId);trId='#'+trId;var isSub=!1;if(cond){for(var i in cond){tr.find('[name="conds['+i+'][]"]').val(cond[i]?cond[i]:'')}
if(cond.sub){isSub=!0}}
if(isSub&&curObj){var endTr=null;var curTr=$(curObj).parents('tr[id^="cond_"]').eq(0);curTr.nextAll().each(function(){if(!$(this).hasClass('config-cond-sub')){return!1}
endTr=$(this)});if(!endTr){endTr=curTr}
endTr.after(tr)}else{$('#config_conds tbody').append(tr)}
if(cond){$(trId).find('[name="conds[field][]"]').trigger('change')}
if(isSub){$(trId).addClass('config-cond-sub')}},dataset_load:function(dsConfig,daConfig){var $_o=this;dsConfig=isObject(dsConfig)?dsConfig:{};daConfig=isObject(daConfig)?daConfig:null;var dsId=toInt(dsConfig.dataset_id);if(dsId>0){ajaxOpen({url:ulink('dataapi/dataset?ds_id='+dsId),success:function(data){var dsData=data.data;if(isObject(dsData)){var fields=isObject(dsData.fields)?dsData.fields:{};$('#config_conds_box').show();$($_o.formid).find('[name="ds_id"]').val(dsData.id);$('#btn_dataset').html('数据集:'+dsData.name);var opts='<option value="">无</option>';var chks='';for(var i in fields){opts+='<option value="'+i+'">'+htmlspecialchars(fields[i])+'</option>';chks+='<label class="checkbox-inline"><input type="checkbox" name="config[hide_fields][]" value="'+i+'"> '+htmlspecialchars(fields[i])+'</label>'}
$('#tpl_config_cond').find('[name="conds[field][]"]').html(opts);$($_o.formid+' [name="config[order_field]"]').html(opts);$('#config_hide_fields').html(chks);$('#config_conds').find('[name="conds[field][]"]').each(function(){var curVal=$(this).val();$(this).html(opts).val(curVal)});if(daConfig){var conds=daConfig.conds;if(isObject(conds)){for(var i in conds.logic){$_o.add_cond({sub:conds.sub[i],logic:conds.logic[i],field:conds.field[i],op:conds.op[i],name:conds.name[i]})}}
delete daConfig.conds}}
$('#myModal').modal('hide');if(daConfig){for(var i in daConfig){var curObj=$($_o.formid).find('[name="config['+i+']"]').eq(0);if(curObj.length>0&&!curObj.is('input:radio')&&!curObj.is('input:checkbox')){curObj.val(daConfig[i])}}
$($_o.formid).find('[name="config[order_sort]"][value="'+daConfig.order_sort+'"]').prop('checked',!0);if(isObject(daConfig.hide_fields)){for(var i in daConfig.hide_fields){$($_o.formid).find('[name="config[hide_fields][]"][value="'+daConfig.hide_fields[i]+'"]').prop('checked',!0)}}}}})}},};var dataapiClass=new DataapiClass()

@ -0,0 +1,27 @@
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
'use strict';function DatasetClass(){this.formid='#form_dataset'}
DatasetClass.prototype={constructor:DatasetClass,init_list:function(search){$('#dataset_list .delete').bind('click',function(){var curTr=$(this).parents('tr[data-ds-id]').eq(0);confirmRight('将清空该数据集的所有数据,确定删除?',function(){ajax_check_userpwd({type:'post',url:ulink('dataset/op?op=delete'),data:{'id':curTr.attr('data-ds-id')},success:function(data){ajaxDataMsg(data);if(data.code==1){curTr.remove()}}})})});var dsIds=[];$('tr[data-ds-id]').each(function(){dsIds.push($(this).attr('data-ds-id'))});ajaxOpen({type:'post',url:ulink('dataset/dbCount'),data:{ids:dsIds},success:function(data){if(data.code==1){var ids=data.data;if(isObject(ids)){for(var i in ids){$('tr[data-ds-id="'+i+'"]').find('.db-count').text(ids[i])}}}}});if(isObject(search)){for(var i in search){$('#form_search').find('[name="'+i+'"]').val(search[i])}}},init:function(dataset){var $_o=this;$('#form_dataset').bind('submit',function(){var formObj=$(this);var settings=getFormAjaxSettings(formObj);settings.complete=function(){formObj.find('button[type="submit"]').removeAttr('disabled')};ajax_check_userpwd(settings);return!1});$('#add_dataset_field').bind('click',function(){windowModal('添加字段',ulink('dataset/field'))});$('#set_dataset_indexes').bind('click',function(){windowModal('合理设置索引可提升数据查询速度',ulink('dataset/indexes?ds_id='+$('#form_dataset').find('[name="id"]').val()),{lg:1})});$('#dataset_fields').on('click','.field-name',function(){var tr=$_o.field_tr(this);var objid=tr.attr('id');var field=tr.find('[name="fields[]"]').val();var options={};options.ajax={type:'post',data:{objid:objid,field:field}};windowModal('编辑字段',ulink('dataset/field'),options)});$('#dataset_fields').on('click','.field-dlt',function(){var tr=$_o.field_tr(this);confirmRight('会清空该字段的所有数据,确定删除?',function(){tr.remove()})});eleExchange('#dataset_fields','.field-move','[id^="field_"]');if(isObject(dataset)){$($_o.formid).find('[name="name"]').val(dataset.name?dataset.name:'');$($_o.formid).find('[name="desc"]').val(dataset.desc?dataset.desc:'');var config=dataset.config;if(isObject(config)){var fields=config.fields;if(isObject(fields)){for(var i in fields){var field=fields[i];if(isObject(field)){field.name_original=field.name;$_o.field_add(field,null)}}}}}},db_init:function(list,search){var $_o=this;$('#dataset_db_list').on('change','input[type="text"],input[type="number"],textarea',function(){$(this).parents('tr').eq(0).find('input[name="ids[]"]').prop('checked',!0)});$('#dataset_db_list').on('focus','textarea',function(){$(this).addClass('txt-big')});$('#dataset_db_list').on('blur','textarea',function(){$(this).removeClass('txt-big')});$.datetimepicker.setLocale('zh');$('#addnew').bind('click',function(){var minId=0;$('[name="ids[]"]').each(function(){var val=toInt($(this).val());if(minId>val){minId=val}});minId=minId-1;$_o.db_add([{id:minId}])});$('#deleteall').bind('click',function(){confirmRight('确定删除选中的数据?',function(){var ids=[];$('input[name="ids[]"]:checked').each(function(){ids.push($(this).val())});$_o.db_delete(ids)})});$('#dataset_db_list').on('click','.db-delete',function(){var tr=$(this).parents('tr').eq(0);var id=tr.find('[name="ids[]"]').val();confirmRight('确定删除数据?',function(){$_o.db_delete(id)})});$_o.db_add(list);if(isObject(search)){for(var i in search){$('#form_search').find('[name="'+i+'"]').val(search[i])}}},db_add:function(list){if(!isObject(list)){list=[]}
var tr=$('#tpl_db').clone();tr.removeAttr('id');var trHtmls='';for(var i in list){var item=list[i];if(!isObject(item)){item={}}
var id=item.id?item.id:'';trHtmls+='<tr data-db-id="'+id+'">'+tr.html().replace(/\[_id_\]/g,'['+id+']')+'</tr>'}
$('#dataset_db_list tbody').append(trHtmls);$('#dataset_db_list').find('.db-time').datetimepicker({format:'Y-m-d H:i:s'});for(var i in list){var item=list[i];if(!isObject(item)){item={}}
var id=item.id?item.id:'';var trObj=$('#dataset_db_list').find('[data-db-id="'+id+'"]');trObj.find('[data-field="id"]').html(id>0?id:'&nbsp;&nbsp;');trObj.find('[name="ids[]"]').val(id);trObj.find('input[data-field],textarea[data-field]').each(function(){var name=$(this).attr('data-field');$(this).val(item[name]?item[name]:'')})}
$('#form_list').find('.overlay').hide()},db_delete:function(ids){if(!isObject(ids)){ids=isNull(ids)?[]:[ids]}
if(ids.length>0){var ids1=[];for(var i in ids){if(ids[i]<0){$('tr[data-db-id="'+ids[i]+'"]').remove()}else{ids1.push(ids[i])}}
ids=ids1}
if(ids.length>0){ajaxOpen({type:'post',url:ulink('dataset/dbDelete?ds_id='+$('#form_list').find('[name="ds_id"]').val()),data:{ids:ids},success:function(data){ajaxDataMsg(data);if(data.code==1){var ids=data.data;if(isObject(ids)){for(var i in ids){$('tr[data-db-id="'+ids[i]+'"]').remove()}}}}})}},field_add:function(field,objid){var tr=null;if(objid){tr=$('#'+objid)}else{tr=$('#tpl_field').clone();tr.attr('id','field_'+generateUUID())}
var fname=field.name;if(field.type=='varchar'&&field.len>0){fname+=' ('+field.len+')'}
tr.find('.field-name').text(fname).attr('data-dbname',field.name_dbname);tr.find('.field-type').text(window.tpl_lang['ds_f_type_'+field.type]);tr.find('.field-desc').text(field.desc);tr.find('[name="fields[]"]').val(encode_json2urlbase(field));if(!objid){$('#dataset_fields tbody').append(tr)}},field_init:function(objid,fieldData){var $_o=this;inputSelectCustom('#form_field [name="type"]','len',null,'varchar');$('#form_field').bind('submit',function(){ajaxOpen({type:'POST',dataType:'json',url:$('#form_field').attr('action'),data:$('#form_field').serialize(),success:function(data){if(data.code==1){data=data.data;if(isObject(data)){var objid=data.objid;var field=data.field;if(isObject(field)){var hasField=!1;var totalLen=0;if(field.type=='varchar'){field.len=toInt(field.len);field.len=field.len>0?field.len:500;totalLen+=field.len}
$('#dataset_fields tr[id^="field_"]').each(function(){var curId=$(this).attr('id');var dbname=$(this).find('.field-name').attr('data-dbname');if(dbname==field.name_dbname){if(objid&&objid==curId){hasField=!1}else{hasField=!0}}
if(!objid||objid!=curId){var fData=$(this).find('[name="fields[]"]').val();fData=decode_urlbase2json(fData);if(fData.type=='varchar'){fData.len=toInt(fData.len);fData.len=fData.len>0?fData.len:500;totalLen+=fData.len}}});if(hasField){toastr.error('字段名称已存在!')}else if(totalLen>16383){toastr.error('所有字符串字段的总长度不能超过16383')}else{$_o.field_add(field,objid);$('#myModal').modal('hide')}}}}else{toastr.error(data.msg)}}});return!1});if(objid&&isObject(fieldData)){$('#form_field [name="objid"]').val(objid);$('#form_field [name="name"]').val(fieldData.name?fieldData.name:'');$('#form_field [name="name_original"]').val(fieldData.name_original?fieldData.name_original:'');$('#form_field [name="desc"]').val(fieldData.desc?fieldData.desc:'');$('#form_field [name="type"]').val(fieldData.type?fieldData.type:'').trigger('change');fieldData.len=toInt(fieldData.len);$('#form_field [name="len"]').val(fieldData.len>0?fieldData.len:'')}},field_tr:function(curObj){return $(curObj).parents('tr[id^="field_"]').eq(0)},indexes_init:function(indexes){var $_o=this;var tplIndex='#win_dataset_indexes .index-tpl [data-tpl="index"]';var tplFields='#win_dataset_indexes .index-tpl [data-tpl="fields"]';var tableEle='#win_dataset_indexes form table.index-list';$('#win_dataset_indexes .index-add-index').bind('click',function(){$_o.indexes_add(tplIndex,tplFields,tableEle,null)});$('#win_dataset_indexes').on('change','.index-field',function(){var curTr=$(this).parents('tr[id^="index_"]').eq(0);if($(this).val()=='-1'){if(curTr.find('.index-field').length<=1){toastr.error('最少保留一个字段!');$(this).val('')}else{$(this).parents('td').eq(0).remove()}}
var ixSlt=curTr.find('.index-type');var ixVal=ixSlt.val();ixSlt.find('option').prop('disabled',!1).show();var allowIxs={};curTr.find('.index-field').each(function(){var type=$(this).find('option[value="'+$(this).val()+'"]').attr('data-type');var allowTypes={bigint:['index','unique'],double:['index','unique'],mediumtext:['fulltext'],datetime:['index','unique']};if(isObject(allowTypes[type])){ixSlt.find('option').each(function(){if(!$(this).is(':disabled')){var optVal=$(this).attr('value');if(optVal&&allowTypes[type].indexOf(optVal)<0){$(this).prop('disabled',!0).hide()}}})}});if(ixSlt.find('option[value="'+ixVal+'"]').is(':disabled')){var showVal='';ixSlt.find('option').each(function(){var optVal=$(this).attr('value');if(optVal&&!$(this).is(':disabled')){showVal=optVal;return!1}});ixSlt.val(showVal)}});$(tableEle).on('click','.index-add-field',function(){var curTr=$(this).parents('tr[id^="index_"]').eq(0);var indexId=curTr.attr('id');var fieldsObj=$(tplFields).clone();fieldsObj.find('.index-field').attr('name','indexes['+indexId+'][fields][]');curTr.find('.index-fields').append(fieldsObj)});$(tableEle).on('click','.index-delete-index',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr[id^="index_"]').eq(0).remove()})});if(!isObject(indexes)){indexes={}}
for(var i in indexes){var index=indexes[i];if(isObject(index)){$_o.indexes_add(tplIndex,tplFields,tableEle,index)}}},indexes_add:function(tplIndex,tplFields,tableEle,indexData){if(!isObject(indexData)){indexData={}}
var trObj=$(tplIndex).clone();var indexId='index_'+generateUUID();trObj.attr('id',indexId);trObj.find('.index-type').attr('name','indexes['+indexId+'][type]').val(indexData.type?indexData.type:'');if(isObject(indexData.fields)){for(var fi in indexData.fields){var fieldsObj=$(tplFields).clone();fieldsObj.find('.index-field').attr('name','indexes['+indexId+'][fields][]').val(fi);trObj.find('.index-fields').append(fieldsObj)}}else{var fieldsObj=$(tplFields).clone();fieldsObj.find('.index-field').attr('name','indexes['+indexId+'][fields][]');trObj.find('.index-fields').append(fieldsObj)}
$(tableEle).append(trObj)}};var datasetClass=new DatasetClass()

@ -9,21 +9,21 @@
*/
'use strict';function ReleaseClass(formid,releid){this.formid='#'+formid;this.releid=releid;this.curFocusResIpt=''}
ReleaseClass.prototype={constructor:ReleaseClass,init:function(){var $_o=this;$($_o.formid).bind('submit',function(){var module=$($_o.formid+' select[name="module"]').val();if(module=='diy'&&$_o.has_diy_editor()){var diyCode=editorCodeIfr('#diy_editor_ifr',{'get_value':1});if(diyCode){$($_o.formid+' [name="diy[code]"]').val(diyCode)}}
var settings=getFormAjaxSettings($(this));settings.data={'_post_data_':settings.data};ajaxOpen(settings);return!1});$($_o.formid+' select[name="module"]').bind('change',function(){var module=$(this).val();$($_o.formid+' .rele-module').hide();$($_o.formid+' .rele-module[module="'+module+'"]').show()});$('#rele_module_cms .btn-cms-detect').bind('click',function(){$_o.cms_detect()});$('#rele_module_cms .btn-cms-bind').bind('click',function(){$_o.cms_bind()});$('#rele_module_cms').on('change','select[name="cms[app]"]',function(){var cmsApp=$(this).val();$_o.cms_bind({cms:{app:cmsApp}})});$('#cms_list').on('click','li a',function(){var path=$(this).attr('path');if(path){$($_o.formid+' [name="cms[path]"]').val(path);$('#cms_tab a[href="#cms_tab_bind"]').tab('show');$_o.cms_bind()}});inputSelectCustom(null,null,{box:'#rele_module_cms',slt:'select[name^="cms_app[param]"]',ipt:'input[name^="cms_app[custom]"]'},'custom:');$('#db_tab_config .dm-db-charset li span').bind('click',function(){var charset=$(this).attr('data-val');charset=charset?charset:'';$('#db_tab_config [name="db[charset]"]').val(charset)});$('#db_tab_config .btn-db-names').bind('click',function(){$_o.db_connect('db_names')});$('#db_tab_config .btn-db-connect').bind('click',function(){$_o.db_connect()});$('#rele_module_file').on('click','.btn-file-rand-path',function(){var randStr=$_o.rand_str(10);$($_o.formid+' [name="file[path]"]').val(randStr)});$('#rele_module_api').on('click','.btn-api-rand-url',function(){var randStr=$_o.rand_str(10);$($_o.formid+' [name="api[key]"]').val(randStr)});$('#diy_tab').on('click','[data-type]',function(){var type=$(this).attr('data-type');$($_o.formid+' [name="diy[type]"]').val(type);if(type=='code'&&$_o.has_diy_editor()){var diyCode=$($_o.formid+' [name="diy[code]"]').val();diyCode=diyCode?diyCode:'';editorCodeIfr('#diy_editor_ifr',{'set_value':diyCode})}});$('#toapi_tab').on('click','[data-module]',function(){var module=$(this).attr('data-module');$($_o.formid+' [name="toapi[module]"]').val(module)});$('#rele_module_toapi').on('change','[name="toapi[type]"]',function(){if($(this).val()=='post'){$('#rele_module_toapi .toapi-content-type').show()}else{$('#rele_module_toapi .toapi-content-type').hide()}});$('#rele_module_toapi').on('click','.toapi-add-param',function(){$_o.toapi_add_param(null,null)});$('#rele_module_toapi').on('click','.toapi-del-param',function(){$(this).parents('tr').eq(0).remove()});$('#rele_module_toapi').on('click','.toapi-field-txt a[data-val]',function(){insertAtCaret($(this).parents('.toapi-field-txt').eq(0).find('input:text,textarea').eq(0),$(this).attr('data-val'))});inputSelectCustom('#rele_module_toapi [name="toapi[charset]"]','toapi[charset_custom]');inputSelectCustom('#rele_module_toapi [name="toapi[encode]"]','toapi[encode_custom]');$('#rele_module_toapi').on('click','.toapi-add-header',function(){$_o.toapi_add_header(null,null)});$('#rele_module_toapi').on('click','.toapi-del-header',function(){$(this).parents('tr').eq(0).remove()});$('#toapi_url_field').bind('change',function(){var val=$(this).val();$(this).val('');insertAtCaret($('#rele_module_toapi [name="toapi[url]"]'),val)});$('#toapi_app_url_field').bind('change',function(){var val=$(this).val();$(this).val('');insertAtCaret($('#rele_module_toapi [name="toapi[app_url]"]'),val)});$($_o.formid).find('[name="toapi[response][module]"]').bind('change',function(){var module=$(this).val();var resNames=['id','target','desc','error'];for(var i in resNames){var obj=$($_o.formid).find('[name="toapi[response]['+resNames[i]+']"]');var objPh=obj.attr('data-placeholder');if(!module){objPh+=',默认:'+resNames[i]}
var settings=getFormAjaxSettings($(this));settings.data={'_post_data_':settings.data};ajaxOpen(settings);return!1});$($_o.formid+' select[name="module"]').bind('change',function(){var module=$(this).val();$($_o.formid+' .rele-module').hide();$($_o.formid+' .rele-module[module="'+module+'"]').show()});$('#rele_module_dataset #btn_dataset_list').bind('click',function(){windowModal('数据集',ulink('dataset/select?from=release'))});$('#rele_module_dataset #btn_dataset_create').bind('click',function(){confirmRight('确定自动创建数据集?',function(){$($_o.formid+' [name="dataset[auto_create]"]').val(1);$($_o.formid).trigger('submit')})});$('#rele_module_cms .btn-cms-detect').bind('click',function(){$_o.cms_detect()});$('#rele_module_cms .btn-cms-bind').bind('click',function(){$_o.cms_bind()});$('#rele_module_cms').on('change','select[name="cms[app]"]',function(){var cmsApp=$(this).val();$_o.cms_bind({cms:{app:cmsApp}})});$('#cms_list').on('click','li a',function(){var path=$(this).attr('path');if(path){$($_o.formid+' [name="cms[path]"]').val(path);$('#cms_tab a[href="#cms_tab_bind"]').tab('show');$_o.cms_bind()}});inputSelectCustom(null,null,{box:'#rele_module_cms',slt:'select[name^="cms_app[param]"]',ipt:'input[name^="cms_app[custom]"]'},'custom:');$('#db_tab_config .dm-db-charset li span').bind('click',function(){var charset=$(this).attr('data-val');charset=charset?charset:'';$('#db_tab_config [name="db[charset]"]').val(charset)});$('#db_tab_config .btn-db-names').bind('click',function(){$_o.db_connect('db_names')});$('#db_tab_config .btn-db-connect').bind('click',function(){$_o.db_connect()});$('#rele_module_file').on('click','.btn-file-rand-path',function(){var randStr=$_o.rand_str(10);$($_o.formid+' [name="file[path]"]').val(randStr)});$('#rele_module_api').on('click','.btn-api-rand-url',function(){var randStr=$_o.rand_str(10);$($_o.formid+' [name="api[key]"]').val(randStr)});$('#diy_tab').on('click','[data-type]',function(){var type=$(this).attr('data-type');$($_o.formid+' [name="diy[type]"]').val(type);if(type=='code'&&$_o.has_diy_editor()){var diyCode=$($_o.formid+' [name="diy[code]"]').val();diyCode=diyCode?diyCode:'';editorCodeIfr('#diy_editor_ifr',{'set_value':diyCode})}});$('#toapi_tab').on('click','[data-module]',function(){var module=$(this).attr('data-module');$($_o.formid+' [name="toapi[module]"]').val(module)});$('#rele_module_toapi').on('change','[name="toapi[type]"]',function(){if($(this).val()=='post'){$('#rele_module_toapi .toapi-content-type').show()}else{$('#rele_module_toapi .toapi-content-type').hide()}});$('#rele_module_toapi').on('click','.toapi-add-param',function(){$_o.toapi_add_param(null,null)});$('#rele_module_toapi').on('click','.toapi-del-param',function(){$(this).parents('tr').eq(0).remove()});$('#rele_module_toapi').on('click','.toapi-field-txt a[data-val]',function(){insertAtCaret($(this).parents('.toapi-field-txt').eq(0).find('input:text,textarea').eq(0),$(this).attr('data-val'))});inputSelectCustom('#rele_module_toapi [name="toapi[charset]"]','toapi[charset_custom]');inputSelectCustom('#rele_module_toapi [name="toapi[encode]"]','toapi[encode_custom]');$('#rele_module_toapi').on('click','.toapi-add-header',function(){$_o.toapi_add_header(null,null)});$('#rele_module_toapi').on('click','.toapi-del-header',function(){$(this).parents('tr').eq(0).remove()});$('#toapi_url_field').bind('change',function(){var val=$(this).val();$(this).val('');insertAtCaret($('#rele_module_toapi [name="toapi[url]"]'),val)});$('#toapi_app_url_field').bind('change',function(){var val=$(this).val();$(this).val('');insertAtCaret($('#rele_module_toapi [name="toapi[app_url]"]'),val)});$($_o.formid).find('[name="toapi[response][module]"]').bind('change',function(){var module=$(this).val();var resNames=['id','target','desc','error'];for(var i in resNames){var obj=$($_o.formid).find('[name="toapi[response]['+resNames[i]+']"]');var objPh=obj.attr('data-placeholder');if(!module){objPh+=',默认:'+resNames[i]}
obj.attr('placeholder',objPh);$('#toapi_resp_module_help').find('[data-module]').hide();$('#toapi_resp_module_help').find('[data-module="'+module+'"]').show()}});$($_o.formid).find('input[name^="toapi[response]"]').bind('focus',function(){$_o.curFocusResIpt=$(this).attr('name')});$('#toapi_resp_module_help').find('[data-rule-sign]').bind('click',function(){var curName=$_o.curFocusResIpt?$_o.curFocusResIpt:'toapi[response][id]';var ruleSign=$(this).attr('data-rule-sign');if(ruleSign=='sign_wildcard'){ruleInsertSign.wildcard('[name="'+curName+'"]')}else if(ruleSign=='sign_match'){ruleInsertSign.match('[name="'+curName+'"]')}else if(ruleSign=='sign_group'){ruleInsertSign.match('[name="'+curName+'"]',{group:1})}});$('#btn_toapi_app').bind('click',function(){$('#toapi_app_params').html('<div class="loading" style="margin-bottom:20px;"></div>');ajaxOpen({type:'post',url:ulink("release/toapiApp"),data:{'task_id':$($_o.formid+' [name="task_id"]').val(),'app_url':$('#rele_module_toapi [name="toapi[app_url]"]').val()},success:function(data){$('#toapi_app_params').html('');if(dataIsJson(data)){var html=data.data?data.data.html:'';if(html){modal('<b>'+data.msg+'<b>',html)}else{ajaxDataMsg(data)}}else{$('#toapi_app_params').html(data)}},error:function(){$('#toapi_app_params').html('')}})});$('#toapi_tab a[href="#toapi_tab_app"]').bind('click',function(){ajaxOpen({type:'get',url:ulink("release/toapiApp?task_id=_id_",{'_id_':$($_o.formid+' [name="task_id"]').val()}),success:function(data){if(dataIsJson(data)){ajaxDataMsg(data)}else{$('#toapi_app_params').html(data)}}})});$('#btn_rele_test').bind('click',function(){collectorWindow('测试','admin/release/test?id='+$_o.releid,null,{lg:1})})},load:function(data){var $_o=this;if(data.module){$($_o.formid+' select[name="module"]').val(data.module).trigger('change')}
if(data.config){if('cms'==data.module){$_o.cms_bind(data.config);$(document).ready(function(){$('#cms_tab a[href="#cms_tab_bind"]').tab('show')})}else if('db'==data.module){$_o.db_bind(data.config)}else if('file'==data.module){if(data.config.file){$($_o.formid+' [name="file[path]"]').val(data.config.file.path);$($_o.formid+' [name="file[type]"]').each(function(){if($(this).val()==data.config.file.type){$(this).prop('checked',!0)}});$($_o.formid+' [name="file[txt_implode]"]').val(data.config.file.txt_implode);$($_o.formid+' [name="file[max_line]"]').val(toInt(data.config.file.max_line));if(data.config.file.hide_fields){for(var fi in data.config.file.hide_fields){$($_o.formid+' [name="file[hide_fields][]"][value="'+data.config.file.hide_fields[fi]+'"]').prop('checked',!0)}}}}else if('api'==data.module){if(data.config.api){$($_o.formid+' [name="api[key]"]').val(data.config.api.key);$($_o.formid+' [name="api[cache_time]"]').val(data.config.api.cache_time);if(data.config.api.hide_fields){for(var fi in data.config.api.hide_fields){$($_o.formid+' [name="api[hide_fields][]"][value="'+data.config.api.hide_fields[fi]+'"]').prop('checked',!0)}}}}else if('diy'==data.module){if(data.config.diy){$(document).ready(function(){$('#diy_tab a[href="#diy_tab_'+data.config.diy.type+'"]').tab('show').trigger('click');for(var i in data.config.diy){$($_o.formid+' [name="diy['+i+']"]').val(data.config.diy[i])}
if(data.config){if('dataset'==data.module){$_o.dataset_load(data.config.dataset)}else if('cms'==data.module){$_o.cms_bind(data.config);$(document).ready(function(){$('#cms_tab a[href="#cms_tab_bind"]').tab('show')})}else if('db'==data.module){$_o.db_bind(data.config)}else if('file'==data.module){if(data.config.file){$($_o.formid+' [name="file[path]"]').val(data.config.file.path);$($_o.formid+' [name="file[type]"]').each(function(){if($(this).val()==data.config.file.type){$(this).prop('checked',!0)}});$($_o.formid+' [name="file[txt_implode]"]').val(data.config.file.txt_implode);$($_o.formid+' [name="file[max_line]"]').val(toInt(data.config.file.max_line));if(data.config.file.hide_fields){for(var fi in data.config.file.hide_fields){$($_o.formid+' [name="file[hide_fields][]"][value="'+data.config.file.hide_fields[fi]+'"]').prop('checked',!0)}}}}else if('api'==data.module){if(data.config.api){$($_o.formid+' [name="api[key]"]').val(data.config.api.key);$($_o.formid+' [name="api[cache_time]"]').val(data.config.api.cache_time);if(data.config.api.hide_fields){for(var fi in data.config.api.hide_fields){$($_o.formid+' [name="api[hide_fields][]"][value="'+data.config.api.hide_fields[fi]+'"]').prop('checked',!0)}}}}else if('diy'==data.module){if(data.config.diy){$(document).ready(function(){$('#diy_tab a[href="#diy_tab_'+data.config.diy.type+'"]').tab('show').trigger('click');for(var i in data.config.diy){$($_o.formid+' [name="diy['+i+']"]').val(data.config.diy[i])}
if(data.config.diy.app){var appName=data.config.diy.app;if(appName.length>1){appName=appName.substr(0,1).toUpperCase()+appName.substr(1).toLowerCase()}else{appName=appName.toUpperCase()}
$($_o.formid+' [name="diy[app]"]').parent().find('.diy-app-name').text(appName+'.php');$($_o.formid+' [name="diy[app]"]').parent().find('.diy-app-editor').show().find('.btn_diy_editor').attr('href',ulink('develop/editor?type=release&module=diy&app=_app_',{'_app_':appName}))}
if($_o.has_diy_editor()&&data.config.diy.code){editorCodeIfr('#diy_editor_ifr',{'set_value':data.config.diy.code})}})}}else if('toapi'==data.module){var config=data.config.toapi;if(config){$($_o.formid+' [name="toapi[module]"]').val(config.module);$($_o.formid+' [name="toapi[url]"]').val(config.url);$($_o.formid+' [name="toapi[type]"]').val(config.type).trigger('change');$($_o.formid+' [name="toapi[content_type]"]').val(config.content_type);$($_o.formid+' [name="toapi[charset_custom]"]').val(config.charset_custom);$($_o.formid+' [name="toapi[charset]"]').val(config.charset).trigger('change');$($_o.formid+' [name="toapi[encode_custom]"]').val(config.encode_custom);$($_o.formid+' [name="toapi[encode]"]').val(config.encode).trigger('change');if(config.response){for(var i in config.response){$($_o.formid+' [name="toapi[response]['+i+']"]').val(config.response[i])}}
$($_o.formid+' [name="toapi[response][module]"]').trigger('change');if(config.param_name){config.param_val=config.param_val?config.param_val:{};for(var i in config.param_name){var pname=config.param_name[i]?config.param_name[i]:'';var pval=config.param_val[i]?config.param_val[i]:'';$_o.toapi_add_param({name:pname,val:pval},i)}}
if(config.header_name){config.header_val=config.header_val?config.header_val:{};for(var i in config.header_name){var hname=config.header_name[i]?config.header_name[i]:'';var hval=config.header_val[i]?config.header_val[i]:'';$_o.toapi_add_header({name:hname,val:hval},i)}}
$($_o.formid+' [name="toapi[app_url]"]').val(config.app_url);config.interval=toInt(config.interval);config.wait=toInt(config.wait);config.retry=toInt(config.retry);$($_o.formid+' [name="toapi[interval]"]').val(config.interval);$($_o.formid+' [name="toapi[wait]"]').val(config.wait);$($_o.formid+' [name="toapi[retry]"]').val(config.retry);$(document).ready(function(){$('#toapi_tab a[href="#toapi_tab_'+config.module+'"]').tab('show').trigger('click');if(config.interval>0||config.wait>0||config.retry>0){showPanelCollapse('#panel_toapi')}})}}}},cms_detect:function(){var $_o=this;$('#cms_list').html('').addClass('loading');ajaxOpen({type:'get',url:ulink("release/cmsDetect"),dataType:'json',success:function(data){$('#cms_list').removeClass('loading');if(data.code==1){var html='<p>点击选择CMS</p>';for(var x in data.data){var list=data.data[x];html+='<label>'+x+'</label><ul>';for(var y in list){html+='<li><a href="javascript:;" path="'+list[y]+'">'+list[y]+'</a></li>'}
$($_o.formid+' [name="toapi[app_url]"]').val(config.app_url);config.interval=toInt(config.interval);config.wait=toInt(config.wait);config.retry=toInt(config.retry);$($_o.formid+' [name="toapi[interval]"]').val(config.interval);$($_o.formid+' [name="toapi[wait]"]').val(config.wait);$($_o.formid+' [name="toapi[retry]"]').val(config.retry);$(document).ready(function(){$('#toapi_tab a[href="#toapi_tab_'+config.module+'"]').tab('show').trigger('click');if(config.interval>0||config.wait>0||config.retry>0){showPanelCollapse('#panel_toapi')}})}}}},dataset_load:function(dsConfig){var $_o=this;dsConfig=isObject(dsConfig)?dsConfig:{};var dsId=toInt(dsConfig.dataset_id);if(dsId>0){ajaxOpen({url:ulink('release/dataset?ds_id='+dsId+'&task_id='+$($_o.formid+' [name="task_id"]').val()),dataType:'html',success:function(html){$('#dataset_config').show();$('#myModal').modal('hide');$('#dataset_config').html(html);$('#dataset_config .dataset-field-txt a[data-val]').bind('click',function(){insertAtCaret($(this).parents('.dataset-field-txt').eq(0).find('input[name^="dataset[fields]"]'),$(this).attr('data-val'))});if(isObject(dsConfig.fields)){for(var i in dsConfig.fields){$('#dataset_config').find('[name="dataset[fields]['+i+']"]').val(dsConfig.fields[i]?dsConfig.fields[i]:'')}}}})}},cms_detect:function(){var $_o=this;$('#cms_list').html('').addClass('loading');ajaxOpen({type:'get',url:ulink("release/cmsDetect"),dataType:'json',success:function(data){$('#cms_list').removeClass('loading');if(data.code==1){var html='<p>点击选择CMS</p>';for(var x in data.data){var list=data.data[x];html+='<label>'+x+'</label><ul>';for(var y in list){html+='<li><a href="javascript:;" path="'+list[y]+'">'+list[y]+'</a></li>'}
html+='</ul>'}
$('#cms_list').html(html)}else{$('#cms_list').html(data.msg)}}})},cms_bind:function(config){var $_o=this;$('#cms_bind').html('').addClass('loading');var postData=$($_o.formid).serialize();if(config&&config.cms&&config.cms.app){postData='cms[app]='+encodeURIComponent(config.cms.app)+'&'+postData}
ajaxOpen({type:'post',url:ulink("release/cmsBind"),dataType:'html',data:postData,success:function(data,textStatus,request){$('#cms_bind').removeClass('loading').show();if((/application\/json/i).test(request.getResponseHeader('Content-Type'))){data=jQuery.parseJSON(data);$('#cms_bind').html('<b style="color:red;">'+data.msg+'</b>')}else{$('#cms_bind').html(data);if(config&&config.cms_app){if(config.cms_app.param){for(var f in config.cms_app.param){var paramEle=$('#cms_bind').find('[name="cms_app[param]['+f+']"]');if(paramEle.is('select')){paramEle.val(config.cms_app.param[f]).trigger('change')}else if(paramEle.is('input:radio')){$('#cms_bind').find('[name="cms_app[param]['+f+']"][value="'+config.cms_app.param[f]+'"]').prop('checked','checked')}else{paramEle.val(config.cms_app.param[f])}}
if(config.cms_app.custom){for(var f in config.cms_app.custom){$('#cms_bind').find('[name="cms_app[custom]['+f+']"]').val(config.cms_app.custom[f])}}}}}},error:function(XMLHttpRequest,textStatus,errorThrown){$('#cms_bind').removeClass('loading').show();$('#cms_bind').html(XMLHttpRequest.responseText)}})},db_bind:function(config){var $_o=this;$($_o.formid+' select[name="db[type]"]').val(config.db.type);$(document).ready(function(){$('#db_tab a[href="#db_tab_table"]').tab('show');$('#db_tab_table .db-table-list').html('').addClass('loading');ajaxOpen({type:'get',url:ulink("release/dbTables?id=_id_",{_id_:$_o.releid}),timeout:10000,dataType:'json',success:function(data){if(data.code==1){$('#db_tab_table .db-table-list').html(data.msg)}else{$('#db_tab_table .db-table-list').css('color','red').html(data.msg)}},complete:function(XMLHttpRequest,status){$('#db_tab_table .db-table-list').removeClass('loading');if(status=='timeout'){$('#db_tab_table .db-table-list').css('color','red').html('数据库连接超时')}}});$('#db_tab_table .db-table-list').on('click','.btn-db-table-bind',function(){var curTable=$(this).parents('.db-table-list').eq(0).find('.db-table-select').val();$_o.db_table_bind(curTable)});eleExchange('#db_table_bind_list','.db-table-bind-move','[id^="db_table_t_"]');$('#db_table_bind_list').on('click','.db-table-bind-del',function(){var obj=$(this);confirmRight(window.tpl_lang.confirm_delete,function(){obj.parents('[id^="db_table_t_"]').eq(0).remove()})});$('#db_tab_table').on('click','.icon-db-table-bind-tips',function(){confirmRight({msg:'<p><b>采集字段:</b>在“任务»采集器设置»获取内容”中添加</p><p><b>查询:</b>在表的查询操作中可添加查询内容</p><p><b>自增主键:</b>在当前表之前有新增表时会自动显示</p>',yes:'确定',width:400,textAlign:'left'})});$('#db_table_bind_list').on('change','.db-table-bind-op',function(){var prtObj=$(this).parents('[id^="db_table_t_"]').eq(0);prtObj.find('.db-table-bind-where').hide();prtObj.find('.db-table-bind-query').hide();prtObj.find('.db-table-bind-data').hide();prtObj.find('.db-table-bind-data-seq').hide();var val=$(this).val();var showData=!1;if(!val){showData=!0;prtObj.find('.db-table-bind-data').show()}else if(val=='update'){showData=!0;prtObj.find('.db-table-bind-where').show();prtObj.find('.db-table-bind-data').show()}else if(val=='query'){prtObj.find('.db-table-bind-where').show();prtObj.find('.db-table-bind-query').show()}
if(showData){var seqObj=prtObj.find('.db-table-bind-data-seq');if(seqObj.length>0){seqObj.show()}}});$('#db_table_bind_list').on('click','.db-table-bind-signs .btn-db-table-bind-signs',function(){var boxObj=$(this).parents('.db-table-bind-signs').eq(0);if(!boxObj||boxObj.length<=0){return}
var dropdownMenu=boxObj.find('.dropdown-menu');if(dropdownMenu.length>0){dropdownMenu.html('');var key=$(this).parents('[id^="db_table_t_"]').eq(0).attr('data-key');ajaxOpen({type:'POST',dataType:'html',url:ulink('release/dbTableBindSings?table_key=_key_',{'_key_':key}),data:$($_o.formid).serialize(),success:function(html){dropdownMenu.html(html);dropdownMenu.find('a[data-val]').bind('click',function(){insertAtCaret($(this).parents('.db-table-bind-signs').eq(0).find('input[name^="db_tables"]').eq(0),$(this).attr('data-val'))})}})}});$('#db_table_bind_list').on('click','.db-table-bind-where-add',function(){$_o.db_table_bind_where_add(this)});$('#db_table_bind_list').on('click','.db-table-bind-where-del',function(){$(this).parents('tr').eq(0).remove()});$('#db_table_bind_list').on('click','.db-table-bind-query-add',function(){$_o.db_table_bind_query_add(this)});$('#db_table_bind_list').on('click','.db-table-bind-query-del',function(){$(this).parents('tr').eq(0).remove()});if(isObject(config.db_tables)&&config.db_tables.length>0){$('#db_tab_table .db-table-binding').addClass('loading');$_o.db_table_bind(null,1)}})},db_table_bind:function(curTable,isDbTables){var $_o=this;curTable=curTable?curTable:'';isDbTables=isDbTables?isDbTables:'';var bindUrl=ulink('release/dbTableBind?id=_id_&table=_tb_&is_db_tables=_dbtb_',{'_id_':$_o.releid,'_tb_':curTable,'_dbtb_':isDbTables});ajaxOpen({type:'get',url:bindUrl,dataType:'html',success:function(data){if(dataIsJson(data)){ajaxDataMsg(data)}else{$('#db_table_bind_list').append(data)}},complete:function(){$('#db_tab_table .db-table-binding').removeClass('loading').hide()}})},db_table_bind_load:function(dbTables){var $_o=this;if(isObject(dbTables)){for(var key in dbTables){var tBoxId='#db_table_t_'+key;var namePre='db_tables['+key+']';var dbTable=dbTables[key];if(isObject(dbTable)){$(tBoxId).find('[name="'+namePre+'[op]').val(dbTable.op).trigger('change');var opTypes=['where','query'];for(var opi in opTypes){var opType=opTypes[opi];if(isObject(dbTable[opType])){for(var i in dbTable[opType]){if(!isObject(dbTable[opType])){dbTable[opType][i]=[]}}
var dropdownMenu=boxObj.find('.dropdown-menu');if(dropdownMenu.length>0){dropdownMenu.html('');var key=$(this).parents('[id^="db_table_t_"]').eq(0).attr('data-key');ajaxOpen({type:'POST',dataType:'html',url:ulink('release/dbTableBindSings?table_key=_key_',{'_key_':key}),data:$($_o.formid).serialize(),success:function(html){dropdownMenu.html(html);dropdownMenu.find('a[data-val]').bind('click',function(){insertAtCaret($(this).parents('.db-table-bind-signs').eq(0).find('input[name^="db_tables"]').eq(0),$(this).attr('data-val'))})}})}});$('#db_table_bind_list').on('click','.db-table-bind-where-add',function(){$_o.db_table_bind_where_add(this)});$('#db_table_bind_list').on('click','.db-table-bind-where-del',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});$('#db_table_bind_list').on('click','.db-table-bind-query-add',function(){$_o.db_table_bind_query_add(this)});$('#db_table_bind_list').on('click','.db-table-bind-query-del',function(){var curObj=$(this);confirmRight('确定删除?',function(){curObj.parents('tr').eq(0).remove()})});if(isObject(config.db_tables)&&config.db_tables.length>0){$('#db_tab_table .db-table-binding').addClass('loading');$_o.db_table_bind(null,1)}})},db_table_bind:function(curTable,isDbTables){var $_o=this;curTable=curTable?curTable:'';isDbTables=isDbTables?isDbTables:'';var bindUrl=ulink('release/dbTableBind?id=_id_&table=_tb_&is_db_tables=_dbtb_',{'_id_':$_o.releid,'_tb_':curTable,'_dbtb_':isDbTables});ajaxOpen({type:'get',url:bindUrl,dataType:'html',success:function(data){if(dataIsJson(data)){ajaxDataMsg(data)}else{$('#db_table_bind_list').append(data)}},complete:function(){$('#db_tab_table .db-table-binding').removeClass('loading').hide()}})},db_table_bind_load:function(dbTables){var $_o=this;if(isObject(dbTables)){for(var key in dbTables){var tBoxId='#db_table_t_'+key;var namePre='db_tables['+key+']';var dbTable=dbTables[key];if(isObject(dbTable)){$(tBoxId).find('[name="'+namePre+'[op]').val(dbTable.op).trigger('change');var opTypes=['where','query'];for(var opi in opTypes){var opType=opTypes[opi];if(isObject(dbTable[opType])){for(var i in dbTable[opType]){if(!isObject(dbTable[opType])){dbTable[opType][i]=[]}}
for(var i in dbTable[opType].field){var opData={};for(var ii in dbTable[opType]){opData[ii]=dbTable[opType][ii][i]}
$_o.db_table_bind_op_add(opType,key,opData)}}}
if(isObject(dbTable.query)){for(var qk in dbTable.query){$(tBoxId).find('[name="'+namePre+'[field]['+qk+']"]').val(dbTable.query[qk])}}

@ -8,13 +8,13 @@
|--------------------------------------------------------------------------
*/
'use strict';var tasksOpClass={get_task_id:function(obj){var taskId=$(obj).parents('tr[data-task-id]').eq(0).attr('data-task-id');taskId=taskId?taskId:0;return taskId},init_common:function(){$('table.datatable').on('click','.delete',function(){var obj=$(this);var url=ulink('task/op?op=delete&id=_id_',{'_id_':tasksOpClass.get_task_id(obj)});confirmRight(window.tpl_lang.confirm_delete,function(){ajaxOpen({type:"GET",url:url,dataType:"json",success:function(data){data.code==1?toastr.success(data.msg):toastr.error(data.msg);if(data.code==1){obj.parents('tr').eq(0).remove()}}})})});$('table.datatable').on('click','.auto',function(){var auto=1;var tips=[window.tpl_lang.task_auto_1,'green'];var val=$(this).attr('data-val');val=toInt(val);if(val!=0){auto=0;tips=[window.tpl_lang.task_auto_0,'red']}
var taskid=tasksOpClass.get_task_id(this);if(taskid>0){var $_o=$(this);var url=ulink('task/op?op=auto&auto=_auto_&id=_id_',{'_auto_':auto,'_id_':taskid});ajaxOpen({type:'GET',url:url,success:function(data){if(data.code==1){$_o.attr('data-val',auto);$_o.prop('title','');$_o.html(tips[0]);$_o.css('color',tips[1])}},dataType:'json'})}});var loadedFunc=function(){$('#myModal .modal-footer .close').html('关闭采集').prop('title','关闭并结束任务').addClass('btn btn-primary').removeClass('close');var btnBackstage=$('<button type="button" class="btn btn-default btn-backstage" data-dismiss="modal" title="关闭并在后台继续运行">后台运行</button>');btnBackstage.bind('click',function(){collectorEchoMsg.close_non_stop=!0});$('#myModal .modal-footer').prepend(btnBackstage)};$('table.datatable').on('click','.caiji',function(){var taskid=tasksOpClass.get_task_id(this);collectorWindow('任务采集','admin/task/collect?id=_id_',{'_id_':taskid},{loaded_func:loadedFunc,lg:1})});$('table.datatable').on('click','.caiji-batch',function(){var taskids=[];$('input[name="batch[]"]:checked').each(function(){taskids.push($(this).val())});collectorWindow('批量采集','admin/task/collectBatch?ids=_ids_',{'_ids_':taskids.join(',')},{loaded_func:loadedFunc,lg:1})});$('table.datatable').on('click','.houtai',function(){var taskid=tasksOpClass.get_task_id(this);tasksOpClass.backstage_collect(taskid)});$('table.datatable').on('click','.houtai-batch',function(){var taskids=[];$('input[name="batch[]"]:checked').each(function(){taskids.push($(this).val())});tasksOpClass.backstage_collect(taskids)});$('table.datatable thead th[data-order]').bind('click',function(){var order=$(this).attr('data-order');if(!order){return!1}
var taskid=tasksOpClass.get_task_id(this);if(taskid>0){var curObj=$(this);var url=ulink('task/op?op=auto&auto=_auto_&id=_id_',{'_auto_':auto,'_id_':taskid});ajaxOpen({type:'GET',url:url,success:function(data){if(data.code==1){curObj.attr('data-val',auto);curObj.prop('title','');curObj.html(tips[0]);curObj.css('color',tips[1])}},dataType:'json'})}});var loadedFunc=function(){$('#myModal .modal-footer .close').html('关闭采集').prop('title','关闭并结束任务').addClass('btn btn-primary').removeClass('close');var btnBackstage=$('<button type="button" class="btn btn-default btn-backstage" data-dismiss="modal" title="关闭并在后台继续运行">后台运行</button>');btnBackstage.bind('click',function(){collectorEchoMsg.close_non_stop=!0});$('#myModal .modal-footer').prepend(btnBackstage)};$('table.datatable').on('click','.caiji',function(){var taskid=tasksOpClass.get_task_id(this);collectorWindow('任务采集','admin/task/collect?id=_id_',{'_id_':taskid},{loaded_func:loadedFunc,lg:1})});$('table.datatable').on('click','.caiji-batch',function(){var taskids=[];$('input[name="batch[]"]:checked').each(function(){taskids.push($(this).val())});collectorWindow('批量采集','admin/task/collectBatch?ids=_ids_',{'_ids_':taskids.join(',')},{loaded_func:loadedFunc,lg:1})});$('table.datatable').on('click','.houtai',function(){var taskid=tasksOpClass.get_task_id(this);tasksOpClass.backstage_collect(taskid)});$('table.datatable').on('click','.houtai-batch',function(){var taskids=[];$('input[name="batch[]"]:checked').each(function(){taskids.push($(this).val())});tasksOpClass.backstage_collect(taskids)});$('table.datatable thead th[data-order]').bind('click',function(){var order=$(this).attr('data-order');if(!order){return!1}
var className=$(this).prop('class');var sort='desc';if(className=='sorting_desc'){sort='asc'}
window.location.href=ulink('task/list?show=list&order='+order+'&sort='+sort);return!1})},init_folder:function(openedTgIds){tasksOpClass.init_common();$('#task_list_folder').on('click','.taskgroup',function(){tasksOpClass.open_folder($(this).parents('tr').eq(0).attr('data-tgid'))});tasksOpClass.open_folder('0',function(){if(isObject(openedTgIds)){for(var i in openedTgIds){tasksOpClass.open_folder(openedTgIds[i])}}})},open_folder:function(tgid,successFunc){var trBox=$('#task_list_folder').find('tr[data-tgid="'+tgid+'"]').eq(0);var tgObj=trBox.find('.taskgroup');var tgLevel=trBox.attr('data-level');var loadingImg='<div class="'+(tgLevel>0?'loading-sm':'loading')+'"></div>';var opened=tgObj.hasClass('taskgroup-opened')?true:!1;var childs=$('#task_list_folder tr[data-parent-tgid="'+tgid+'"]');childs.css('display',(opened?'none':'table-row'));childs.each(function(){var cTgid=$(this).attr('data-tgid');var cOpened=$(this).hasClass('taskgroup-opened')?true:!1;if(cTgid){if(opened){$('#task_list_folder tr[data-parent-tgid="'+cTgid+'"]').css('display','none')}else{$('#task_list_folder tr[data-parent-tgid="'+cTgid+'"]').css('display',cOpened?'table-row':'none')}}});if(opened){tgObj.removeClass('taskgroup-opened');ajaxOpen({type:"GET",url:ulink('task/tgClose?tg_id=_tgid_',{'_tgid_':tgid}),dataType:"json",success:function(data){}})}else{tgObj.addClass('taskgroup-opened');if(trBox.attr('data-setted')!=1){tgObj.parents('td').eq(0).append(loadingImg);ajaxOpen({type:"GET",url:ulink('task/tgOpen?tg_id=_tgid_',{'_tgid_':tgid}),dataType:"json",success:function(data){if(tgLevel>0){tgObj.siblings('.loading-sm').remove()}else{trBox.hide()}
window.location.href=ulink('task/list?show=list&order='+order+'&sort='+sort);return!1});this.task_collected_num()},task_collected_num:function(){var taskIds=[];$('tr[data-task-id]').each(function(){taskIds.push($(this).attr('data-task-id'))});if(taskIds.length>0){ajaxOpen({type:'POST',url:ulink('task/taskCollectedNum'),data:{'task_ids':taskIds},success:function(data){if(data.code==1){data=data.data;if(isObject(data)){for(var i in data){var num=data[i];if(isObject(num)){var trObj=$('tr[data-task-id="'+i+'"]');trObj.find('.today-num').text(num.today);trObj.find('.total-num').text(num.total)}}}}}})}},init_folder:function(openedTgIds){tasksOpClass.init_common();$('#task_list_folder').on('click','.taskgroup',function(){tasksOpClass.open_folder($(this).parents('tr').eq(0).attr('data-tgid'))});tasksOpClass.open_folder('0',function(){if(isObject(openedTgIds)){for(var i in openedTgIds){tasksOpClass.open_folder(openedTgIds[i])}}})},open_folder:function(tgid,successFunc){var $_o=this;var trBox=$('#task_list_folder').find('tr[data-tgid="'+tgid+'"]').eq(0);var tgObj=trBox.find('.taskgroup');var tgLevel=trBox.attr('data-level');var loadingImg='<div class="'+(tgLevel>0?'loading-sm':'loading')+'"></div>';var opened=tgObj.hasClass('taskgroup-opened')?true:!1;var childs=$('#task_list_folder tr[data-parent-tgid="'+tgid+'"]');childs.css('display',(opened?'none':'table-row'));childs.each(function(){var cTgid=$(this).attr('data-tgid');var cOpened=$(this).hasClass('taskgroup-opened')?true:!1;if(cTgid){if(opened){$('#task_list_folder tr[data-parent-tgid="'+cTgid+'"]').css('display','none')}else{$('#task_list_folder tr[data-parent-tgid="'+cTgid+'"]').css('display',cOpened?'table-row':'none')}}});if(opened){tgObj.removeClass('taskgroup-opened');ajaxOpen({type:"GET",url:ulink('task/tgClose?tg_id=_tgid_',{'_tgid_':tgid}),dataType:"json",success:function(data){}})}else{tgObj.addClass('taskgroup-opened');if(trBox.attr('data-setted')!=1){tgObj.parents('td').eq(0).append(loadingImg);ajaxOpen({type:"GET",url:ulink('task/tgOpen?tg_id=_tgid_',{'_tgid_':tgid}),dataType:"json",success:function(data){if(tgLevel>0){tgObj.siblings('.loading-sm').remove()}else{trBox.hide()}
tgLevel=parseInt(tgLevel);var leftSpace=tgLevel>0?('padding-left:'+tgLevel*25+'px;'):'';var html='';if(data.code==1){if(isNull(data.data)){html=null}else{var html='';if(data.data.tgList){var datalist=data.data.tgList;for(var i in datalist){html+='<tr data-level="'+(tgLevel+1)+'" data-parent-tgid="'+tgid+'" data-tgid="'+datalist[i].id+'"><td style="'+leftSpace+'"><a href="javascript:;" class="taskgroup"> <span class="glyphicon icon-folder-pre"></span> <span class="glyphicon icon-folder"></span> '+datalist[i].name+' </a></td><td colspan="6"></td></tr>'}}
if(data.data.taskList){var todayDate=new Date();todayDate=todayDate.getFullYear()+'-'+(todayDate.getMonth()+1)+'-'+todayDate.getDate();var datalist=data.data.taskList;for(var i in datalist){var item=datalist[i];var auto=toInt(item.auto);if(!isObject(item._collected_info)){item._collected_info={}}
html+='<tr data-parent-tgid="'+tgid+'" data-task-id="'+item.id+'"></td><td style="'+leftSpace+'">'+'<a href="'+ulink('task/set?id='+item.id)+'" class="edit">'+item.name+'</a></td><td class="sort"><input type="text" name="newsort['+item.id+']" class="form-control" value="'+item.sort+'" autocomplete="off" /></td>'+'<td><a href="javascript:;" class="auto" data-val="'+auto+'" style="color:'+(auto>0?'green':'red')+';" title="'+(item._timer_info?item._timer_info:'')+'">'+(window.tpl_lang['task_auto_'+auto])+'</a></td>'+'<td>'+item.addtime+'</td><td><label class="checkbox-inline chk-inline"><input type="checkbox" name="batch[]" value="'+item.id+'" /> '+item.caijitime+'</label>'+'&nbsp;<ul class="in-line"><li><a href="javascript:;" class="caiji">'+window.tpl_lang.caiji+'</a></li>'+' <li class="sep">|</li> <li><a href="javascript:;" class="houtai">后台</a></li></ul>'+'</td><td><ul class="in-line"><li>今日<a href="'+ulink('collected/list?task_id='+item.id+'&begin='+todayDate)+'" target="_blank">'+toInt(item._collected_info.today)+'</a>条</li>'+' <li class="sep">|</li> <li>总共<a href="'+ulink('collected/list?task_id='+item.id)+'" target="_blank">'+toInt(item._collected_info.total)+'</a>条</li></ul>'+'</td><td><ul class="in-line"><li><a href="'+ulink('collector/set?task_id='+item.id)+'">规则</a></li>'+' <li class="sep">|</li> <li><a href="'+ulink('release/set?task_id='+item.id)+'" title="'+(item._rele_module?item._rele_module:'')+'">发布</a></li>'+' <li class="sep">|</li> <li><a href="javascript:;" class="delete">'+window.tpl_lang.delete+'</a></li></ul></td></tr>'}}}}else{html=null}
html=isNull(html)?('<tr data-parent-tgid="'+tgid+'"><td style="'+leftSpace+'">'+window.tpl_lang.task_none_data+'</td><td colspan="6"></td></tr>'):html;trBox.attr('data-setted',1);trBox.after(html);if(successFunc&&typeof(successFunc)=='function'){successFunc()}}})}}},click_backstage_time:{},backstage_collect:function(ids){var isBatch=!1;if(isObject(ids)){isBatch=!0;ids=ids.join(',')}
if(data.data.taskList){var todayDate=new Date();todayDate=todayDate.getFullYear()+'-'+(todayDate.getMonth()+1)+'-'+todayDate.getDate();var datalist=data.data.taskList;for(var i in datalist){var item=datalist[i];var auto=toInt(item.auto);html+='<tr data-parent-tgid="'+tgid+'" data-task-id="'+item.id+'"></td><td style="'+leftSpace+'">'+'<a href="'+ulink('task/set?id='+item.id)+'" class="edit">'+item.name+'</a></td><td class="sort"><input type="text" name="newsort['+item.id+']" class="form-control" value="'+item.sort+'" autocomplete="off" /></td>'+'<td><a href="javascript:;" class="auto" data-val="'+auto+'" style="color:'+(auto>0?'green':'red')+';" title="'+(item._timer_info?item._timer_info:'')+'">'+(window.tpl_lang['task_auto_'+auto])+'</a></td>'+'<td>'+item.addtime+'</td><td><label class="checkbox-inline chk-inline"><input type="checkbox" name="batch[]" value="'+item.id+'" /> '+item.caijitime+'</label>'+'&nbsp;<ul class="in-line"><li><a href="javascript:;" class="caiji">'+window.tpl_lang.caiji+'</a></li>'+' <li class="sep">|</li> <li><a href="javascript:;" class="houtai">后台</a></li></ul>'+'</td><td><ul class="in-line"><li>今日<a href="'+ulink('collected/list?task_id='+item.id+'&begin='+todayDate)+'" class="today-num" target="_blank">0</a>条</li>'+' <li class="sep">|</li> <li>总共<a href="'+ulink('collected/list?task_id='+item.id)+'" class="total-num" target="_blank">0</a>条</li></ul>'+'</td><td><ul class="in-line"><li><a href="'+ulink('collector/set?task_id='+item.id)+'">规则</a></li>'+' <li class="sep">|</li> <li><a href="'+ulink('release/set?task_id='+item.id)+'" title="'+(item._rele_module?item._rele_module:'')+'">发布</a></li>'+' <li class="sep">|</li> <li><a href="javascript:;" class="delete">'+window.tpl_lang.delete+'</a></li></ul></td></tr>'}}}}else{html=null}
html=isNull(html)?('<tr data-parent-tgid="'+tgid+'"><td style="'+leftSpace+'">'+window.tpl_lang.task_none_data+'</td><td colspan="6"></td></tr>'):html;trBox.attr('data-setted',1);trBox.after(html);if(successFunc&&typeof(successFunc)=='function'){successFunc()}
$_o.task_collected_num()}})}}},click_backstage_time:{},backstage_collect:function(ids){var isBatch=!1;if(isObject(ids)){isBatch=!0;ids=ids.join(',')}
if(!tasksOpClass.click_backstage_time[ids]){tasksOpClass.click_backstage_time[ids]=(new Date()).getTime()}else{if((new Date()).getTime()-tasksOpClass.click_backstage_time[ids]<=3000){return!1}else{tasksOpClass.click_backstage_time[ids]=(new Date()).getTime()}}
var url='';if(isBatch){url=ulink('admin/task/collectBatch?ids=_ids_&backstage_run=1',{'_ids_':ids})}else{url=ulink('admin/task/collect?id=_id_&backstage_run=1',{'_id_':ids})}
ajaxOpen({type:'GET',url:url,async:!0,timeout:3000,dataType:'html'});toastr.success('已添加到后台运行');winBackstageTask.count(1000)},}

@ -7,7 +7,7 @@
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
'use strict';$(document).ready(function(){toastr.options={"closeButton":!1,"debug":!1,"newestOnTop":!1,"progressBar":!1,"positionClass":"toast-top-center","preventDuplicates":!1,"onclick":null,"showDuration":"300","hideDuration":"1000","timeOut":"3000","extendedTimeOut":"1000","showEasing":"swing","hideEasing":"linear","showMethod":"fadeIn","hideMethod":"fadeOut"};$('body').on('submit','form[ajax-submit="true"]',function(){var settings=getFormAjaxSettings($(this));ajaxOpen(settings);return!1})});function getFormAjaxSettings(formObj){var settings={type:'POST',dataType:'json',url:formObj.attr('action'),beforeSend:function(){formObj.find('button[type="submit"]').attr('disabled',!0)},success:function(data){if(data.url){window.setTimeout("window.location.href='"+data.url+"';",2000)}else{formObj.find('button[type="submit"]').removeAttr('disabled')}
'use strict';$(document).ready(function(){toastr.options={"closeButton":!1,"debug":!1,"newestOnTop":!1,"progressBar":!1,"positionClass":"toast-top-center","preventDuplicates":!1,"onclick":null,'tapToDismiss':!1,"showDuration":"300","hideDuration":"1000","timeOut":"3000","extendedTimeOut":"1000","showEasing":"swing","hideEasing":"linear","showMethod":"fadeIn","hideMethod":"fadeOut"};$('body').on('submit','form[ajax-submit="true"]',function(){var settings=getFormAjaxSettings($(this));ajaxOpen(settings);return!1})});function getFormAjaxSettings(formObj){var settings={type:'POST',dataType:'json',url:formObj.attr('action'),beforeSend:function(){formObj.find('button[type="submit"]').attr('disabled',!0)},success:function(data){if(data.url){window.setTimeout("window.location.href='"+data.url+"';",2000)}else{formObj.find('button[type="submit"]').removeAttr('disabled')}
if(data.code==1){if(data.msg){toastr.success(data.msg)}
formObj.find('.verify-img').trigger('click')}else{if(data.msg){toastr.error(data.msg)}}
var dataData=isNull(data.data)?{}:data.data;if(dataData.js){eval(dataData.js)}},error:function(data){formObj.find('button[type="submit"]').removeAttr('disabled');toastr.error(data)}};if(formObj.attr('enctype')&&formObj.attr('enctype').toLowerCase()=='multipart/form-data'){var formData=new FormData(formObj[0]);settings.data=formData;settings.contentType=!1;settings.processData=!1}else{settings.data=formObj.serialize()}

File diff suppressed because one or more lines are too long

@ -46,8 +46,9 @@ class Api extends CollectController{
if(!$keyIsOk){
if($keyIsUrl){
json(array('error'=>'密钥错误'))->send();
exit();
}else{
$this->_json('密钥错误');
$this->jsonSend('密钥错误');
}
}
\util\Param::set_task_api_response();
@ -74,32 +75,32 @@ class Api extends CollectController{
$mrele=model('Release');
$taskData=$mtask->getById($taskId);
if(empty($taskData)){
$this->_json(lang('task_error_empty_task'));
$this->jsonSend(lang('task_error_empty_task'));
}
$singleConfig=$taskData['config']['single'];
init_array($singleConfig);
if(empty($singleConfig['open'])){
$this->_json('未开启单页采集模式');
$this->jsonSend('未开启单页采集模式');
}
if($singleConfig['key']){
if($key!=md5($singleConfig['key'])){
$this->_json('接口密钥错误');
$this->jsonSend('接口密钥错误');
}
}
$taskTips='任务:'.$taskData['name'].' » ';
if(empty($taskData['module'])){
$this->_json($taskTips.lang('task_error_null_module'));
$this->jsonSend($taskTips.lang('task_error_null_module'));
}
if(!in_array($taskData['module'],config('allow_coll_modules'))){
$this->_json($taskTips.lang('coll_error_invalid_module'));
$this->jsonSend($taskTips.lang('coll_error_invalid_module'));
}
$collData=$mcoll->where(array('task_id'=>$taskData['id'],'module'=>$taskData['module']))->find();
if(empty($collData)){
$this->_json($taskTips.lang('coll_error_empty_coll'));
$this->jsonSend($taskTips.lang('coll_error_empty_coll'));
}
$collData=$collData->toArray();
$mtask->loadConfig($taskData);
@ -128,9 +129,9 @@ class Api extends CollectController{
if(empty($fieldData['data'])){
$msg=g_sc('collect_echo_msg_txt');
$msg=strip_tags($msg);
$this->_json($msg);
$this->jsonSend($msg);
}else{
$this->_json('',1,$fieldData['data']);
$this->jsonSend('',$fieldData['data'],1);
}
}
@ -274,13 +275,6 @@ class Api extends CollectController{
}
$updateResult['code']=1;
}
return json($updateResult);
}
private function _json($msg='',$code=0,$data=array()){
init_array($data);
$result=array('code'=>$code,'msg'=>$msg,'data'=>$data);
json($result)->send();
}
}

@ -250,10 +250,10 @@ class Backstage extends BaseController{
$mcollected=model('Collected');
$todayTime=strtotime(date('Y-m-d',time()));
$tongji['today_success']=$mcollected->where(array('addtime'=>array('GT',$todayTime),'target'=>array('<>','')))->count();
$tongji['today_error']=$mcollected->where(array('addtime'=>array('GT',$todayTime),'error'=>array('<>','')))->count();
$tongji['total_success']=$mcollected->where("`target` <> ''")->count();
$tongji['total_error']=$mcollected->where("`error` <> ''")->count();
$tongji['today_success']=$mcollected->where(array('addtime'=>array('GT',$todayTime),'status'=>1))->count();
$tongji['today_error']=$mcollected->where(array('addtime'=>array('GT',$todayTime),'status'=>0))->count();
$tongji['total_success']=$mcollected->where('status',1)->count();
$tongji['total_error']=$mcollected->where('status',0)->count();
$cacheTongji=array('time'=>time(),'data'=>$tongji);
cache('admin_check_up_tongji',$cacheTongji);
}else{
@ -483,6 +483,7 @@ class Backstage extends BaseController{
$list=model('Collected')->where($cond)->order('addtime desc')->paginate(10,false,paginate_auto_config());
$pagenav=$list->render();
$list=$list->all();
$list=model('Collected')->getInfoDatas($list);
$this->assign('list',$list);
$this->assign('pagenav',$pagenav);
@ -577,7 +578,7 @@ class Backstage extends BaseController{
$mconfig=model('Config');
$config=$mconfig->getConfig('admincp','data');
init_array($config);
if($op=='mini'||$op=='narrow'){
if($op=='mini'||$op=='narrow'||$op=='check_skip'){
$config[$op]=intval($val);
}elseif($op=='skin'){
if(preg_match('/^[\w\-\_]+$/', $val)){
@ -585,7 +586,7 @@ class Backstage extends BaseController{
}
}
$allowConfig=array('skin'=>'','mini'=>'','narrow'=>'');
$allowConfig=array('skin'=>'','mini'=>'','narrow'=>'','check_skip'=>'');
foreach ($allowConfig as $k=>$v){
$allowConfig[$k]=isset($config[$k])?$config[$k]:'';
}

@ -227,6 +227,8 @@ class CollectController extends \skycaiji\admin\controller\BaseController{
set_g_sc(['c','caiji','real_time'],0);
if(\util\Param::is_task_api_response()){
$cacheApiData=$arele->get_cache_fields();
if($cacheApiData!==false){
@ -235,6 +237,7 @@ class CollectController extends \skycaiji\admin\controller\BaseController{
}
}
}
}
$curTime=time();
@ -360,7 +363,7 @@ class CollectController extends \skycaiji\admin\controller\BaseController{
if(!is_empty(g_sc('api_task_key_is_url'))){
json(array('error'=>$msg))->send();
}else{
json(array('code'=>0,'msg'=>$msg,'data'=>[]))->send();
$this->jsonSend($msg);
}
}
}else{

@ -76,27 +76,37 @@ class Collected extends BaseController {
$cond['release']=$search['release'];
}
$search['status']=input('status');
if(!empty($search['status'])){
if($search['status']==1){
$cond['target']=array('<>','');
}elseif($search['status']==2){
$cond['error']=array('<>','');
}
if(!is_empty($search['status'],true)){
$cond['status']=intval($search['status']);
}
$dataList=array();
$taskList=array();
if(!$null_task){
$condJoin=array();
if($cond['url']){
foreach ($cond as $k=>$v){
$k=($k=='url'?'i.':'c.').$k;
$condJoin[$k]=$v;
}
}
if($condJoin){
$count=$mcollected->alias('c')->join($mcollected->collected_info_tname().' i','c.id=i.id')->where($condJoin)->count();
}else{
$count=$mcollected->where($cond)->count();
}
$limit=$search['num'];
if($count>0){
if($condJoin){
$dataList=$mcollected->alias('c')->join($mcollected->collected_info_tname().' i','c.id=i.id')->where($condJoin)->order('c.id desc')->paginate($limit,false,paginate_auto_config());
}else{
$dataList=$mcollected->where($cond)->order('id desc')->paginate($limit,false,paginate_auto_config());
}
$pagenav=$dataList->render();
$this->assign('pagenav',$pagenav);
$dataList=$dataList->all();
$dataList=empty($dataList)?array():$dataList;
$dataList=$mcollected->getInfoDatas($dataList);
$taskIds=array();
foreach ($dataList as $itemK=>$item){
@ -113,7 +123,7 @@ class Collected extends BaseController {
$this->set_html_tags(
lang('collected_list'),
lang('collected_list'),
lang('collected_list').' <small><a href="'.url('collected/chart').'">统计图表</a></small>',
breadcrumb(array(array('url'=>url('collected/list'),'title'=>'已采集数据'),array('url'=>url('collected/list'),'title'=>$navTips?$navTips:'数据列表')))
);
}
@ -129,10 +139,10 @@ class Collected extends BaseController {
init_array($release);
if(in_array('all', $release)){
model('Collected')->where("`error` is not null and `error`<>''")->delete();
model('Collected')->deleteByCond(array('status'=>0));
}else{
model('Collected')->where('release','in',$release)->where("`error` is not null and `error`<>''")->delete();
model('Collected')->deleteByCond(array('release'=>array('in',$release),'status'=>0));
}
$this->success('清理完成','admin/collected/list');
}else{
@ -161,13 +171,13 @@ class Collected extends BaseController {
}
if($op=='delete'){
$mcollected->where(array('id'=>$id))->delete();
$mcollected->deleteByCond(array('id'=>$id));
$this->success(lang('delete_success'));
}elseif($op=='deleteall'){
$ids=input('ids/a',array(),'intval');
if(is_array($ids)&&count($ids)>0){
$mcollected->where(array('id'=>array('in',$ids)))->delete();
$mcollected->deleteByCond(array('id'=>array('in',$ids)));
}
$this->success(lang('op_success'),'list');
}
@ -176,7 +186,7 @@ class Collected extends BaseController {
public function chartAction(){
$this->set_html_tags(
'已采集数据:统计图表',
'已采集数据:统计图表',
'已采集数据:统计图表 <small><a href="'.url('collected/list').'">数据列表</a></small>',
breadcrumb(array(array('url'=>url('collected/list'),'title'=>'已采集数据'),array('url'=>url('collected/chart'),'title'=>'统计图表')))
);
return $this->fetch();
@ -239,13 +249,13 @@ class Collected extends BaseController {
$dataList['success'][$k]=$mcollected->where(array(
'addtime'=>array('between',array($v['start'],$v['end'])),
'target'=>array('<>','')
'status'=>1
))->count();
$dataList['failed'][$k]=$mcollected->where(array(
'addtime'=>array('between',array($v['start'],$v['end'])),
'error'=>array('<>','')
'status'=>0
))->count();
}
@ -267,13 +277,13 @@ class Collected extends BaseController {
$dataList['success'][$module]=$mcollected->where(array(
'release'=>$module,
'target'=>array('<>','')
'status'=>1
))->count();
$dataList['failed'][$module]=$mcollected->where(array(
'release'=>$module,
'error'=>array('<>','')
'status'=>0
))->count();
}
$this->success('',null,$dataList);

@ -196,7 +196,7 @@ class Cpattern extends BaseController {
'num' => array('num_start','num_end'),
'time' => array ('time_format','time_start','time_end','time_stamp'),
'list' => array('list','list_type'),
'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'),
'extract' =>array('extract','extract_module','extract_rule','extract_rule_merge','extract_rule_multi','extract_rule_multi_type','extract_rule_multi_str','extract_xpath','extract_xpath_attr','extract_xpath_attr_custom','extract_xpath_multi','extract_xpath_multi_type','extract_xpath_multi_str','extract_json','extract_json_arr','extract_json_arr_implode','extract_json_loop'),
'merge' => 'merge',
'sign' => 'sign'
);

@ -0,0 +1,222 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\admin\controller;
class Dataapi extends BaseController {
public function listAction(){
$page=input('p/d',1);
$page=max(1,$page);
$search=array(
'id'=>input('id/d',0),
'name'=>input('name','','trim')
);
if($search['id']<=0){
unset($search['id']);
}
$mda=model('Dataapi');
$cond=array();
if($search['id']){
$cond['id']=$search['id'];
}
if($search['name']){
$cond['name']=array('like','%'.$search['name'].'%');
}
$daList=array();
$limit=50;
$daList=$mda->where($cond)->order('sort desc')->paginate($limit,false,paginate_auto_config());
$pagenav=$daList->render();
$daList=$daList->all();
$dsNames=array();
foreach ($daList as $k=>$v){
$dsNames[$v['ds_id']]=$v['ds_id'];
}
if($dsNames){
$dsNames=model('Dataset')->where('id','in',$dsNames)->column('name','id');
}
$this->set_html_tags(
'数据接口',
'数据接口',
breadcrumb(array(array('url'=>url('dataapi/list'),'title'=>'数据接口'),array('url'=>url('dataapi/list'),'title'=>'列表')))
);
$this->assign('dsNames',$dsNames);
$this->assign('search',$search);
$this->assign('daList',$daList);
$this->assign('pagenav',$pagenav);
return $this->fetch();
}
public function opAction(){
$op=input('op','');
$mda=model('Dataapi');
if($this->request->isPost()){
if(empty($op)){
$newsort=input('newsort/a',array(),'intval');
foreach ($newsort as $id=>$sort){
$mda->where('id',$id)->update(array('sort'=>$sort));
}
$this->success('操作成功','dataapi/list');
}elseif($op=='delete'){
$id=input('id/d',0);
$mda->where('id',$id)->delete();
$this->success('已删除','');
}elseif($op=='status'){
$id=input('id/d',0);
$status=input('status/d',0);
$status=$status?0:1;
$mda->where('id',$id)->update(array('status'=>$status));
$this->success($status?'已开启':'已关闭','',array('status'=>$status));
}
}else{
$this->error('无效操作','');
}
}
public function setAction(){
$id=input('id/d');
$daData=array();
$mda=model('Dataapi');
$mds=model('Dataset');
if($id){
$daData=$mda->getById($id);
}
if($this->request->isPost()){
$newData=array(
'name'=>input('name'),
'route'=>input('route','','trim'),
'desc'=>input('desc'),
'sort'=>input('sort/d',0),
'status'=>input('status/d',0),
'ds_id'=>input('ds_id/d',0)
);
if(empty($newData['name'])){
$this->error('请输入名称');
}
if(empty($daData)||$newData['name']!=$daData['name']){
if($mda->where('name',$newData['name'])->count()>0){
$this->error('名称已存在');
}
}
if(!empty($newData['route'])){
if(!preg_match('/^[\w\-]+$/',$newData['route'])){
$this->error('网址别名只能由字母、数字、横线和下划线组成!');
}
if(empty($daData)||$newData['route']!=$daData['route']){
if($mda->where('route',$newData['route'])->count()>0){
$this->error('网址别名已存在');
}
}
}
$config=trim_input_array('config');
init_array($config);
$config['page_per']=$config['page_per']?:'';
$config['page_max']=$config['page_max']?:'';
if(!empty($config['page_name'])){
$checkRst=$mda->check_url_param_name($config['page_name']);
if(!$checkRst['success']){
$this->error('分页'.$checkRst['msg']);
}
}
if($newData['ds_id']<=0){
$this->error('请绑定数据集');
}
$dsData=$mds->getById($newData['ds_id']);
$conds=trim_input_array('conds');
$conds=$mda->filter_conds($conds);
foreach ($conds['name'] as $k=>$v){
if(!empty($v)){
$checkRst=$mda->check_url_param_name($v);
if(!$checkRst['success']){
$dsField=$mds->get_config_field($dsData,$conds['field'][$k]);
$this->error('数据集字段“'.$dsField['name'].'”'.$checkRst['msg']);
}
}
}
$config['conds']=$conds;
$newData['config']=serialize($config);
if(empty($daData)){
$id=$mda->strict(false)->insert($newData,false,true);
}else{
$mda->strict(false)->where(array('id'=>$id))->update($newData);
}
$this->success('操作成功','dataapi/set?id='.$id);
}else{
$title=$daData?'编辑':'添加';
$this->set_html_tags(
$title.'数据接口'.($daData?(':'.$daData['name']):''),
$title.'数据接口'.($daData?(''.$daData['name'].'id:'.$id.''):''),
breadcrumb(array(array('url'=>url('dataapi/list'),'title'=>'数据接口'),array('url'=>url('dataapi/set?id='.($daData?$daData['id']:'')),'title'=>($daData?$daData['name']:$title))))
);
$config=array();
$apiUrl='';
$isSafeMode=false;
$groupConds=array();
$fieldNames=array();
if($daData){
$daData['name']=htmlspecialchars_decode($daData['name'],ENT_QUOTES);
$daData['desc']=htmlspecialchars_decode($daData['desc'],ENT_QUOTES);
$config=$daData['config'];
$apiUrl=url('api/data/'.($daData['route']?$daData['route']:$daData['id']),'',false,true);
if(!empty($config['api_key'])){
$apiUrl.=(strpos($apiUrl,'?')===false?'?':'&').'k=';
if(empty($config['api_mode'])){
$apiUrl.=md5($config['api_key']);
}else{
$isSafeMode=true;
}
}
$apiUrl=htmlspecialchars($apiUrl);
$dsData=$daData['ds_id']?$mds->getById($daData['ds_id']):array();
if($config['conds']&&$config['conds']['field']){
foreach($config['conds']['field'] as $k=>$v){
$dsField=$mds->get_config_field($dsData,$v);
$fieldNames[$v]=$dsField['name'];
}
}
$groupConds=$mda->get_group_conds($config['conds']);
}
$fieldNames['id']='id';
$this->assign('daData',$daData);
$this->assign('config',$config);
$this->assign('apiUrl',$apiUrl);
$this->assign('isSafeMode',$isSafeMode);
$this->assign('groupConds',$groupConds);
$this->assign('fieldNames',$fieldNames);
$this->assign('condOps',$mda->get_cond_op(null));
return $this->fetch();
}
}
public function datasetAction(){
$dsId=input('ds_id/d',0);
$mds=model('Dataset');
$dsData=$mds->getById($dsId);
$fields=$dsData['config']['fields'];
init_array($fields);
foreach ($fields as $k=>$v){
$fields[$k]=$v['name'];
}
$fields=array_merge(array('id'=>'id'),$fields);
$this->success('','',array('fields'=>$fields,'name'=>$dsData['name'],'id'=>$dsData['id']));
}
}

@ -0,0 +1,680 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\admin\controller;
use skycaiji\common\model\DatasetTable;
class Dataset extends BaseController {
public function listAction(){
$page=input('p/d',1);
$page=max(1,$page);
$search=array(
'id'=>input('id/d',0),
'name'=>input('name','','trim')
);
if($search['id']<=0){
unset($search['id']);
}
$mds=model('Dataset');
$cond=array();
if($search['id']){
$cond['id']=$search['id'];
}
if($search['name']){
$cond['name']=array('like','%'.$search['name'].'%');
}
$dsList=array();
$limit=50;
$dsList=$mds->where($cond)->order('sort desc')->paginate($limit,false,paginate_auto_config());
$pagenav=$dsList->render();
$dsList=$dsList->all();
$dsFields=array();
if($dsList){
foreach ($dsList as $v){
$v=$mds->get_ds_data($v);
if($v['config']&&$v['config']['fields']){
foreach ($v['config']['fields'] as $vf){
$dsFields[$v['id']][$vf['name']]=$vf['name'];
}
$dsFields[$v['id']]=implode(', ', $dsFields[$v['id']]);
}
}
}
$this->set_html_tags(
'数据集',
'数据集',
breadcrumb(array(array('url'=>url('dataset/list'),'title'=>'数据集'),array('url'=>url('dataset/list'),'title'=>'列表')))
);
$this->assign('search',$search);
$this->assign('dsList',$dsList);
$this->assign('dsFields',$dsFields);
$this->assign('pagenav',$pagenav);
return $this->fetch();
}
public function selectAction(){
$page=input('p/d',1);
$page=max(1,$page);
$search=array(
'id'=>input('id/d',0),
'name'=>input('name','','trim')
);
if($search['id']<=0){
unset($search['id']);
}
$mds=model('Dataset');
$cond=array();
if($search['id']){
$cond['id']=$search['id'];
}
if($search['name']){
$cond['name']=array('like','%'.$search['name'].'%');
}
$dsList=array();
$limit=20;
$dsList=$mds->where($cond)->order('sort desc')->paginate($limit,false,paginate_auto_config());
$pagenav=$dsList->render();
$dsList=$dsList->all();
$this->assign('search',$search);
$this->assign('dsList',$dsList);
$this->assign('pagenav',$pagenav);
$this->assign('from',input('from',''));
return $this->fetch();
}
public function opAction(){
$op=input('op','');
$mds=model('Dataset');
if($this->request->isPost()){
if(empty($op)){
$newsort=input('newsort/a',array(),'intval');
foreach ($newsort as $id=>$sort){
$mds->where('id',$id)->update(array('sort'=>$sort));
}
$this->success('操作成功','dataset/list');
}elseif($op=='delete'){
$this->ajax_check_userpwd();
$id=input('id/d',0);
$mds->where('id',$id)->delete();
DatasetTable::getInstance($id)->drop_table();
$this->success('已删除','');
}
}else{
$this->error('无效操作','');
}
}
public function dbCountAction(){
$counts=array();
if($this->request->isPost()){
$ids=input('ids/a',array(),'intval');
init_array($ids);
foreach ($ids as $id){
try{
$dst=DatasetTable::getInstance($id);
$counts[$id]=$dst->db()->count();
}catch(\Exception $ex){}
}
}
$this->success('','',$counts);
}
public function setAction(){
$id=input('id/d');
$dsData=array();
$mds=model('Dataset');
if($id){
$dsData=$mds->getById($id);
}
if($this->request->isPost()){
$newData=array(
'name'=>input('name'),
'desc'=>input('desc'),
'sort'=>input('sort/d',0)
);
if(empty($newData['name'])){
$this->error('请输入名称');
}
$checkName=true;
if(!empty($dsData)&&$newData['name']==$dsData['name']){
$checkName=false;
}
if($checkName){
if($mds->where('name',$newData['name'])->count()>0){
$this->error('名称已存在');
}
}
$fields=input('fields/a',array(),'url_b64decode');
if($fields){
foreach ($fields as $k=>$v){
$fields[$k]=json_decode($v,true);
}
$fields=$mds->filter_fields($fields);
}
init_array($fields);
if(empty($fields)){
$this->error('请添加字段');
}
$newData['config']=array(
'fields'=>$fields
);
$newData['config']=serialize($newData['config']);
if(empty($dsData)){
$id=$mds->strict(false)->insert($newData,false,true);
}else{
$dsFields=$dsData['config']['fields'];
init_array($dsFields);
$newFields=$fields;
init_array($newFields);
$upFields=false;
foreach ($newFields as $k=>$v){
$dsField=$dsFields[$k];
if(empty($dsField)){
$upFields=true;
break;
}
if($v['name']!=$dsField['name']||$v['type']!=$dsField['type']||$v['len']!=$dsField['len']){
$upFields=true;
break;
}
}
foreach ($dsFields as $k=>$v){
if(empty($newFields[$k])){
$upFields=true;
break;
}
}
if($upFields){
$this->ajax_check_userpwd();
}
$mds->strict(false)->where(array('id'=>$id))->update($newData);
}
$dsTable=DatasetTable::getInstance($id);
$dsTable->db();
$error='';
try{
$dsTable->alertTableFields($fields,$dsData);
}catch(\Exception $ex){
$error=$ex->getMessage();
$error=$dsTable->convertErrorColumn($error,$fields);
}
$dsData=$mds->getById($id);
if($dsData){
$fields=$dsData['config']['fields'];
init_array($fields);
if($fields){
$dbColumns=$dsTable->dbColumns();
foreach ($fields as $fk=>$fv){
if(empty($dbColumns[$fk])){
$fv=null;
}else{
$dbType=$dbColumns[$fk]['type'];
$dbLen='';
if(preg_match('/^(.+)\((\d+)\)\s*$/',$dbType,$mtype)){
$dbType=trim($mtype[1]);
$dbLen=intval($mtype[2]);
}
$dbType=strtolower($dbType);
$checkType=$mds->check_field_type($dbType);
if(!$checkType['success']){
$fv=null;
}else{
$fv['len']='';
if($dbType!=$fv['type']){
$fv['type']=$dbType;
}elseif($dbType=='varchar'){
$fv['len']=$dbLen;
}
}
}
if(is_null($fv)){
unset($fields[$fk]);
}else{
unset($fv['name_original']);
unset($fv['name_dbname']);
$fields[$fk]=$fv;
}
}
$dsData['config']['fields']=$fields;
$dsData['config']=serialize($dsData['config']);
$mds->strict(false)->where(array('id'=>$id))->update(array('config'=>$dsData['config']));
}
}
if($error){
$this->error($error,'');
}else{
$this->success('操作成功','dataset/set?id='.$id);
}
}else{
$title=$dsData?'编辑':'添加';
$this->set_html_tags(
$title.'数据集'.($dsData?(':'.$dsData['name']):''),
$title.'数据集'.($dsData?(''.$dsData['name'].'id:'.$id.''):''),
breadcrumb(array(array('url'=>url('dataset/list'),'title'=>'数据集'),array('url'=>url('dataset/set?id='.($dsData?$dsData['id']:'')),'title'=>($dsData?$dsData['name']:$title))))
);
$indexes=array();
if($dsData){
$dsData['name']=htmlspecialchars_decode($dsData['name'],ENT_QUOTES);
$dsData['desc']=htmlspecialchars_decode($dsData['desc'],ENT_QUOTES);
$fields=$dsData['config']['fields'];
init_array($fields);
foreach ($fields as $k=>$v){
$v['name_dbname']=$mds->field_db_name($v['name']);
$fields[$k]=$v;
}
$dsData['config']['fields']=$fields;
$dsTable=DatasetTable::getInstance($id);
$dbIndexes=db()->query('SHOW INDEX FROM `'.$dsTable->fullTableName().'`');
foreach ($dbIndexes as $dbIndex){
$dbIndex=\util\Funcs::array_keys_to_lower($dbIndex);
$dbIxKey=$dbIndex['key_name'];
if($dbIxKey=='PRIMARY'){
continue;
}
if(!isset($indexes[$dbIxKey])){
$indexes[$dbIxKey]=array('fields'=>array());
if(empty($dbIndex['non_unique'])){
$indexes[$dbIxKey]['type']='唯一索引';
}else{
$indexes[$dbIxKey]['type']=strtolower($dbIndex['index_type'])=='fulltext'?'全文索引':'普通索引';
}
}
$indexes[$dbIxKey]['fields'][$dbIndex['column_name']]=($fields[$dbIndex['column_name']]?$fields[$dbIndex['column_name']]['name']:$dbIndex['column_name']).($dbIndex['sub_part']?('('.$dbIndex['sub_part'].')'):'');
}
}
$this->assign('indexes',$indexes);
$this->assign('dsData',$dsData);
return $this->fetch();
}
}
public function fieldAction(){
if($this->request->isPost()&&input('is_submit')){
$objid=input('objid','');
$field=array(
'name'=>input('name'),
'desc'=>input('desc','',null),
'type'=>input('type'),
'len'=>input('len/d',0),
'name_original'=>input('name_original'),
);
$field['len']=max(0,$field['len']);
$mds=model('Dataset');
$result=$mds->check_field_name($field['name']);
if(!$result['success']){
$this->error($result['msg']);
}
$result=$mds->check_field_type($field['type']);
if(!$result['success']){
$this->error($result['msg']);
}
if($field['type']=='varchar'){
$field['len']=min($field['len'],16383);
if($field['len']<=0){
$field['len']=500;
}
}
$field['name_dbname']=$mds->field_db_name($field['name']);
$this->success('','',array('field'=>$field,'objid'=>$objid));
}else{
$field=input('field','','url_b64decode');
$objid=input('objid','');
$field=$field?json_decode($field,true):array();
$this->assign('field',$field);
$this->assign('objid',$objid);
return $this->fetch();
}
}
public function indexesAction(){
$dsId=input('ds_id/d',0);
$mds=model('Dataset');
$dsData=$dsId>0?$mds->getById($dsId):null;
if(empty($dsData)){
$this->error('数据集不存在');
}
$fields=$dsData['config']['fields'];
init_array($fields);
$dsTable=DatasetTable::getInstance($dsId);
$dbColumns=$dsTable->dbColumns();
$dbIndexes1=db()->query('SHOW INDEX FROM `'.$dsTable->fullTableName().'`');
$dbIndexes=array();
foreach ($dbIndexes1 as $dbIndex){
$dbIndex=\util\Funcs::array_keys_to_lower($dbIndex);
$dbIxKey=$dbIndex['key_name'];
if(strcasecmp($dbIxKey,'PRIMARY')===0){
continue;
}
if(!isset($dbIndexes[$dbIxKey])){
$dbIndexes[$dbIxKey]=array('name'=>$dbIxKey,'fields'=>array());
if(empty($dbIndex['non_unique'])){
$dbIndexes[$dbIxKey]['type']='unique';
}else{
$dbIndexes[$dbIxKey]['type']=strtolower($dbIndex['index_type'])=='fulltext'?'fulltext':'index';
}
}
$dbIndexes[$dbIxKey]['fields'][$dbIndex['column_name']]=$dbIndex['column_name'];
}
if($this->request->isPost()){
$postIndexes=trim_input_array('indexes');
$indexes=array();
foreach ($postIndexes as $k=>$v){
init_array($v['fields']);
foreach ($v['fields'] as $fk=>$fv){
if(empty($fv)||$fv=='-1'){
unset($v['fields'][$fk]);
}
}
$v['fields']=array_unique($v['fields']);
$v['fields']=array_filter($v['fields']);
$v['fields']=array_values($v['fields']);
$vFields=array();
foreach ($v['fields'] as $fv){
$vFields[$fv]=$fv;
}
$v['fields']=$vFields;
$indexes[md5(serialize($vFields))]=$v;
}
$dbIndexes1=array();
foreach ($dbIndexes as $k=>$v){
init_array($v['fields']);
$dbIndexes1[md5(serialize($v['fields']))]=$v;
}
$dbIndexes=$dbIndexes1;
foreach ($indexes as $k=>$v){
if($dbIndexes[$k]){
if($v['type']==$dbIndexes[$k]['type']){
unset($indexes[$k]);
unset($dbIndexes[$k]);
continue;
}
}
}
if($dbIndexes){
foreach ($dbIndexes as $k=>$v){
if($v['name']){
db()->execute('ALTER TABLE `'.$dsTable->fullTableName().'` DROP INDEX `'.$v['name'].'`');
}
}
}
$error='';
if($indexes){
$allowTypes=array('bigint'=>array('index','unique'),'double'=>array('index','unique'),'mediumtext'=>array('fulltext'),'datetime'=>array('index','unique'));
foreach ($indexes as $k=>$v){
if(!in_array($v['type'], array('index','unique','fulltext'))){
continue;
}
init_array($v['fields']);
if(empty($v['fields'])){
continue;
}
$ixType=$v['type'];
$ixName=array();
$ixFields=array();
$varcharLens=array();
$errorType=array();
foreach ($v['fields'] as $fname){
$ixName[]=$fname;
$ixLen='';
if($dbColumns[$fname]&&preg_match('/\bvarchar\s*\((\d+)\)/',$dbColumns[$fname]['type'],$mlen)){
$ixLen=intval($mlen[1]);
$ixLen=$ixLen>250?250:$ixLen;
}
if($ixLen){
$varcharLens[$fname]=$ixLen;
$ixFields[$fname]=$fname.'('.$ixLen.')';
}else{
$ixFields[$fname]=$fname;
}
$allowType=$allowTypes[$fields[$fname]['type']];
if($allowType&&!in_array($ixType,$allowType)){
$errorType[]=$fields[$fname]['name'].' '.lang('ds_ix_type_'.$ixType);
}
}
if($errorType){
$errorType=implode(',', $errorType);
$error.='错误的索引:'.$errorType.'<br>';
continue;
}
$ixName=count($ixName)>1?('i'.substr(md5(serialize($ixName)),8,16)):$ixName[0];
$lenElse=250-count($ixFields)*2+count($varcharLens)*2;
if(array_sum($varcharLens)>$lenElse){
asort($varcharLens);
foreach ($varcharLens as $vlf=>$vlv){
$varcharLen=intval($lenElse/(count($varcharLens)));
if($vlv>$varcharLen){
$vlv=$varcharLen;
}
$ixFields[$vlf]=$vlf.'('.$vlv.')';
$lenElse=$lenElse-$vlv;
unset($varcharLens[$vlf]);
}
}
$ixFields=implode(',',$ixFields);
try{
db()->execute('ALTER TABLE `'.$dsTable->fullTableName().'` ADD '.$ixType.' `'.$ixName.'`('.$ixFields.')');
}catch(\Exception $ex){
$exMsg=$ex->getMessage();
$exMsg=$dsTable->convertErrorColumn($exMsg,$fields);
$error.=$exMsg.'<br>';
};
}
}
if($error){
$this->error($error,'');
}else{
$this->success('操作成功','dataset/set?id='.$dsId);
}
}else{
$this->assign('fields',$fields);
$this->assign('dbIndexes',$dbIndexes);
$this->assign('dsData',$dsData);
return $this->fetch();
}
}
public function dbAction(){
$dsId=input('ds_id/d',0);
$mds=model('Dataset');
$dsData=$dsId>0?$mds->getById($dsId):null;
if(empty($dsData)){
$this->error('数据集不存在');
}
$fields=$dsData['config']['fields'];
init_array($fields);
$dst=DatasetTable::getInstance($dsId);
$mcache=\skycaiji\admin\model\CacheModel::getInstance();
$cond=array();
$search=array('id'=>input('id/d',0));
if($search['id']<=0){
unset($search['id']);
}else{
$cond['id']=$search['id'];
}
foreach ($fields as $k=>$v){
$searchK=input($k,'');
if(!is_empty($searchK,true)){
$cond[$k]=array('like','%'.addslashes($searchK).'%');
$search[$k]=$searchK;
}
}
$search['num']=input('num/d',0);
if($search['num']<=0){
$search['num']=$mcache->getCache('dataset_db_list_num','data');
}
$search['num']=max(30,intval($search['num']));
$mcache->setCache('dataset_db_list_num',$search['num']);
$list=$dst->db()->where($cond)->order('id desc')->paginate($search['num'],false,paginate_auto_config());
$pagenav=$list->render();
$list=$list->all();
foreach ($list as $k=>$v){
init_array($v);
foreach ($v as $vk=>$vv){
if($fields[$vk]&&$fields[$vk]['type']=='datetime'){
$vv=$dst->convertDate($vv);
$v[$vk]=$vv;
}
}
$list[$k]=$v;
}
$this->set_html_tags(
'数据集:'.$dsData['name'],
'数据集:'.$dsData['name'],
breadcrumb(array(array('url'=>url('dataset/set?id='.$dsId),'title'=>'数据集:'.$dsData['name']),array('url'=>url('dataset/db?ds_id='.$dsId),'title'=>'数据')))
);
$this->assign('search',$search);
$this->assign('dsData',$dsData);
$this->assign('list',$list);
$this->assign('fields',$fields);
$this->assign('pagenav',$pagenav);
return $this->fetch();
}
public function dbSetAction(){
$dsId=input('ds_id/d',0);
$mds=model('Dataset');
$dsData=$dsId>0?$mds->getById($dsId):null;
if(empty($dsData)){
$this->error('数据集不存在');
}
$fields=$dsData['config']['fields'];
init_array($fields);
$dst=DatasetTable::getInstance($dsId);
if($this->request->isPost()){
$ids=input('ids/a',array(),'intval');
$postData=array();
foreach ($fields as $k=>$v){
$fieldData=input($k.'/a',array(),null);
if($v&&$v['type']=='datetime'){
foreach ($fieldData as $fk=>$fv){
$fieldData[$fk]=$dst->convertDate($fv);
}
}
$postData[$k]=$fieldData;
}
$upData=array();
$newData=array();
foreach ($ids as $ik=>$iv){
if($iv>0){
$upData[$iv]=array('id'=>$iv);
foreach ($fields as $fk=>$fv){
$upData[$iv][$fk]=$postData[$fk][$iv];
}
}else{
foreach ($fields as $fk=>$fv){
$newData[$iv][$fk]=$postData[$fk][$iv];
}
}
}
$error='';
try{
if($upData){
$dst->db()->strict(false)->insertAll($upData,true);
}
if($newData){
foreach ($newData as $k=>$v){
if(is_array($v)){
$isNull=true;
foreach ($v as $vk=>$vv){
if(!is_empty($vv,true)){
$isNull=false;
}
}
if($isNull){
unset($newData[$k]);
}
}
}
if($newData){
$dst->db()->strict(false)->insertAll($newData);
}
}
}catch(\Exception $ex){
$error=$ex->getMessage();
$error=$dst->convertErrorColumn($error,$fields);
}
if($error){
$this->error($error,'');
}else{
$this->success('操作成功',$newData?('dataset/db?ds_id='.$dsId):'');
}
}else{
$this->error('操作失败','');
}
}
public function dbDeleteAction(){
$dsId=input('ds_id/d',0);
$mds=model('Dataset');
$dsData=$dsId>0?$mds->getById($dsId):null;
if(empty($dsData)){
$this->error('数据集不存在');
}
$dst=DatasetTable::getInstance($dsId);
if($this->request->isPost()){
$ids=input('ids/a',array(),'intval');
init_array($ids);
if(!empty($ids)){
$dst->db()->where('id','in',$ids)->delete();
}
$this->success('删除成功','',$ids);
}else{
$this->error('删除失败','');
}
}
}

@ -395,7 +395,7 @@ EOF;
/*开发应用*/
public function appAction(){
$app=input('app');
$app=input('app','');
$app=strtolower($app);
$mapp=model('App');
$appData=null;

@ -218,8 +218,27 @@ class Release extends CollectController{
return $this->fetch();
}
}
public function datasetAction(){
$mds=model('Dataset');
$taskId=input('task_id/d',0);
$dsId=input('ds_id/d',0);
$dsData=$mds->getById($dsId);
$fields=$dsData['config']['fields'];
init_array($fields);
$collFields=array();
if($taskId>0){
$taskData=model('Task')->getById($taskId);
if(!empty($taskData)){
$collFields=controller('admin/Rdb','event')->get_coll_fields($taskData['id'], $taskData['module']);
}
init_array($collFields);
}
$this->assign('dsData',$dsData);
$this->assign('fields',$fields);
$this->assign('collFields',$collFields);
return $this->fetch();
}
/*检测cms信息*/
public function cmsDetectAction(){
$acms=controller('admin/Rcms','event');

@ -204,6 +204,24 @@ class Task extends CollectController {
$this->success('','');
}
public function taskCollectedNumAction(){
$taskIds=input('task_ids/a',array(),'intval');
init_array($taskIds);
$list=array();
if($taskIds){
$mcollected=model('Collected');
$todayTime=strtotime(date('Y-m-d',time()));
foreach ($taskIds as $taskId){
$list[$taskId]=array(
'today'=>$mcollected->where(array('task_id'=>array('=',$taskId),'addtime'=>array('>',$todayTime)))->count(),
'total'=>$mcollected->where('task_id',$taskId)->count(),
);
}
}
$this->success('','',$list);
}
private function _set_tasks($taskList){
if($taskList){
@ -233,20 +251,6 @@ class Task extends CollectController {
}
}
$mcollected=model('Collected');
$todayTime=strtotime(date('Y-m-d',time()));
foreach ($taskList as $k=>$v){
$taskId=$v['id'];
if(empty($taskId)){
continue;
}
$collected=array();
$collected['today']=$mcollected->where(array('task_id'=>array('=',$taskId),'addtime'=>array('>',$todayTime)))->count();
$collected['total']=$mcollected->where('task_id',$taskId)->count();
$v['_collected_info']=$collected;
$taskList[$k]=$v;
}
$mrele=model('Release');
if($tids){
$releModules=$mrele->where('task_id','in',$tids)->column('module','task_id');

@ -188,7 +188,7 @@ class Taskgroup extends BaseController {
$id=input('id/d',0);
$op=input('op');
$ops=array('item'=>array('delete','move'),'list'=>array('deleteall','saveall'));
$ops=array('item'=>array('delete','move'),'list'=>array('saveall'));
if(!in_array($op,$ops['item'])&&!in_array($op,$ops['list'])){
$this->error(lang('invalid_op'));
@ -239,44 +239,13 @@ class Taskgroup extends BaseController {
$this->assign('parentTgList',$parentTgList);
return $this->fetch();
}
}elseif($op=='deleteall'){
$ids=input('ids/a',array());
if(is_array($ids)&&count($ids)>0){
$list=$mtaskgroup->where(array('id'=>array('in',$ids)))->column('*');
$deleteIds=array();
foreach ($list as $item){
$subCount=$mtaskgroup->where(array('parent_id'=>$item['id']))->count();
if($subCount==0){
$deleteIds[$item['id']]=$item['id'];
}else{
$hasSub=true;
}
}
if($deleteIds){
$mtaskgroup->where(array('id'=>array('in',$deleteIds)))->delete();
$mtask->strict(false)->where(array('tg_id'=>array('in',$deleteIds)))->update(array('tg_id'=>0));
}
}
$this->success(lang($hasSub?'tg_deleteall_has_sub':'op_success'));
}elseif($op=='saveall'){
$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){
$newsort[$tgid]=min(intval($newsort[$tgid]),999999);
$updateSql.= sprintf(" WHEN %d THEN '%s' ", $tgid, $newsort[$tgid]);
}
$updateSql.='END WHERE `id` IN ('. implode(',',$ids).')';
try{
$mtaskgroup->execute($updateSql);
}catch (\Exception $ex){
$this->error(lang('op_failed'));
if(is_array($newsort)&&count($newsort)>0){
foreach ($newsort as $key=>$val){
$val=min(intval($val),999999);
$mtaskgroup->strict(false)->where('id',intval($key))->update(array('sort'=>$val));
}
}
$this->success(lang('op_success'),'list');

@ -367,7 +367,7 @@ class Tool extends BaseController {
$createSql.='PRIMARY KEY ('.implode(',', $primarys).')';
}
$createSql.=' ) ENGINE=MyISAM DEFAULT CHARSET=utf8';
$createSql.=' ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4';
db()->execute($createSql);
}else{

@ -126,25 +126,28 @@ class CpatternEvent extends CpatternColl{
break;
case 'rule':
$val = $this->field_module_rule(array(
'reg_rule'=>$field_params['reg_extract_rule'],
'reg_rule_merge'=>$field_params['reg_extract_rule_merge'],
'rule_multi'=>$field_params['extract_rule_multi'],
'rule_multi_str'=>$field_params['extract_rule_multi_str'],
), $field_html);
$field_params['reg_rule']=$field_params['reg_extract_rule'];
$field_params['reg_rule_merge']=$field_params['reg_extract_rule_merge'];
$field_params['rule_multi']=$field_params['extract_rule_multi'];
$field_params['rule_multi_str']=$field_params['extract_rule_multi_str'];
$field_params['rule_multi_type']=$field_params['extract_rule_multi_type'];
$val = $this->field_module_rule($field_params, $field_html);
break;
case 'xpath':
$val = $this->field_module_xpath(array(
'xpath' => $field_params['extract_xpath'],
'xpath_attr' => $field_params['extract_xpath_attr'],
'xpath_attr_custom' => $field_params['extract_xpath_attr_custom'],
'xpath_multi' => $field_params['extract_xpath_multi'],
'xpath_multi_str' => $field_params['extract_xpath_multi_str'],
), $field_html);
$field_params['xpath']=$field_params['extract_xpath'];
$field_params['xpath_attr']=$field_params['extract_xpath_attr'];
$field_params['xpath_attr_custom']=$field_params['extract_xpath_attr_custom'];
$field_params['xpath_multi']=$field_params['extract_xpath_multi'];
$field_params['xpath_multi_str']=$field_params['extract_xpath_multi_str'];
$field_params['xpath_multi_type']=$field_params['extract_xpath_multi_type'];
$val = $this->field_module_xpath($field_params, $field_html);
break;
case 'json':
$val=$this->field_module_json(array('json'=>$field_params['extract_json'],'json_arr'=>$field_params['extract_json_arr'],'json_arr_implode'=>$field_params['extract_json_arr_implode']), $field_html);
$field_params['json']=$field_params['extract_json'];
$field_params['json_loop']=$field_params['extract_json_loop'];
$field_params['json_arr']=$field_params['extract_json_arr'];
$field_params['json_arr_implode']=$field_params['extract_json_arr_implode'];
$val = $this->field_module_json($field_params, $field_html);
break;
}
return $val;
@ -357,8 +360,10 @@ class CpatternEvent extends CpatternColl{
}
return $fieldVal;
}
public function process_f_insert($fieldVal,$params){
public function process_f_insert($fieldVal,$params,$curUrlMd5,$loopIndex,$contUrlMd5,$fieldName=''){
$txt=$params['insert_txt'];
$txt=$this->_replace_insert_fields($txt,$fieldVal,$curUrlMd5,$loopIndex);
if(empty($params['insert_loc'])){
$fieldVal.=$txt;
}elseif($params['insert_loc']=='head'){
@ -457,6 +462,11 @@ class CpatternEvent extends CpatternColl{
return $murl;
},$fieldVal);
}
if(in_array('img_tag', $params['tool_list'])){
$fieldVal=preg_replace_callback('/(?<![\'\"])(\bhttp[s]{0,1}\:\/\/[^\s\'\"\<\>]+)(?![\'\"])/i',function($match){
return '<img src="'.$match[1].'" />';
},$fieldVal);
}
return $fieldVal;
}
@ -1069,7 +1079,7 @@ class CpatternEvent extends CpatternColl{
if(empty($process)){
return $fieldVal;
}
static $conds=array('filter','if','func','api','download');
static $conds=array('filter','if','func','api','download','insert');
static $fnConds=array('translate','tool');
foreach ($process as $params){

@ -26,7 +26,7 @@ class CpatternSingle extends Cpattern{
if(\util\Param::is_collector_single()){
$txt=strip_tags($txt);
json(array('code'=>0,'msg'=>$txt,'data'=>[]))->send();
$this->jsonSend($txt);
}else{
parent::error($txt,$url,$data,$wait,$header);
}

@ -87,7 +87,7 @@ class Rapi extends Release{
if(!is_empty(g_sc('api_task_key_is_url'))){
json($collFieldsList)->send();
}else{
json(array('code'=>1,'msg'=>'','data'=>$collFieldsList))->send();
$this->jsonSend('',$collFieldsList,1);
}
}else{
$html='<form id="win_form_preview" method="post" target="_blank" action="'.url('tool/preview_data').'">'.html_usertoken()

@ -133,7 +133,7 @@ class Rcms extends Release{
}
/*获取cms名字列表*/
public function cms_name_list($cmsPath,$return=false){
$cmsPath=realpath($cmsPath);
$cmsPath=$cmsPath?realpath($cmsPath):'';
static $list=array();
if($return){

@ -0,0 +1,130 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\admin\event;
use skycaiji\admin\model\CacheModel;
use skycaiji\common\model\DatasetTable;
class Rdataset extends Release{
protected $dataset_db=array();
/**
* 设置页面post过来的config
* @param unknown $config
*/
public function setConfig($config){
$dataset=\util\UnmaxPost::val('dataset/a',array(),null);
$dataset['dataset_id']=intval($dataset['dataset_id']);
if($dataset['auto_create']){
$mtask=model('Task');
$mds=model('Dataset');
$taskId=\util\UnmaxPost::val('task_id/d');
$taskData=$mtask->getById($taskId);
if(empty($taskData)){
$this->error('任务不存在');
}
$dsFields=array();
$dsName=$taskData['name'];
do{
$hasName=$mds->where('name',$dsName)->count()>0?true:false;
if($hasName){
$dsName.='_1';
}
}while($hasName);
$collFields=$this->get_coll_fields($taskData['id'],$taskData['module']);
$md5Fields=array();
foreach ($collFields as $collField){
$checkResult=$mds->check_field_name($collField);
if(!$checkResult['success']){
$md5Fields[md5($collField)]=$collField;
$collField=md5($collField);
}
$dsFields[$collField]=array('name'=>$collField,'type'=>'mediumtext');
}
$dsFields=$mds->filter_fields($dsFields);
$dsData=array('name'=>$dsName,'desc'=>'','sort'=>0,'config'=>serialize(array('fields'=>$dsFields)));
$dataset['dataset_id']=$mds->strict(false)->insert($dsData,false,true);
if($dataset['dataset_id']>0){
$dataset['fields']=array();
foreach ($dsFields as $k=>$v){
$dataset['fields'][$k]='[采集字段:'.($md5Fields[$v['name']]?:$v['name']).']';
}
}
}
if($dataset['dataset_id']<=0){
$this->error('请设置数据集');
}
$config['dataset']=$dataset;
return $config;
}
/*导出数据*/
public function export($collFieldsList,$options=null){
$addedNum=0;
$dsConfig=$this->config['dataset'];
init_array($dsConfig['fields']);
$dsId=intval($dsConfig['dataset_id']);
if(empty($this->dataset_db[$dsId])){
$dsData=model('Dataset')->getById($dsId);
if(empty($dsData)){
$this->echo_msg('数据集id'.$dsId.'不存在');
return $addedNum;
}
$this->dataset_db[$dsId]=DatasetTable::getInstance($dsId)->db();
}
$db=&$this->dataset_db[$dsId];
foreach ($collFieldsList as $collFieldsKey=>$collFields){
$contTitle=$collFields['title'];
$contContent=$collFields['content'];
$contUrl=$collFields['url'];
$collFields=$collFields['fields'];
$this->init_download_config($this->task,$collFields);
$db->startTrans();
$returnData=array('id'=>'','target'=>'','desc'=>'','error'=>'');
try{
$dbData=$this->_replace_fields($dsConfig['fields'],$collFields);
$returnData['id']=$db->strict(false)->insert($dbData,false,true);
if($returnData['id']>0){
$addedNum++;
$returnData['target']=sprintf('@%d:%d',$dsId,$returnData['id']);
}
}catch (\Exception $ex){
$returnData['error']=$ex->getMessage();
}
if(empty($returnData['error'])){
$db->commit();
}else{
$db->rollback();
}
$this->record_collected($contUrl,$returnData,$this->release,array('title'=>$contTitle,'content'=>$contContent));
unset($collFieldsList[$collFieldsKey]['fields']);
}
return $addedNum;
}
private function _replace_fields($data,$collFields){
if(is_array($data)){
foreach ($data as $k=>$v){
$data[$k]=$this->_replace_fields($v,$collFields);
}
}else{
$data=preg_replace_callback('/\[\x{91c7}\x{96c6}\x{5b57}\x{6bb5}\:(.+?)\]/u',function($match)use($collFields){
$match=$match[1];
return $this->get_field_val($collFields[$match]);
},$data);
}
return $data;
}
}
?>

@ -19,6 +19,7 @@ class ReleaseBase extends CollectBase{
$returnData['desc']=isset($returnData['desc'])?$returnData['desc']:'';
$returnData['error']=isset($returnData['error'])?$returnData['error']:'';
$mcollected=model('Collected');
if($returnData['id']>0){
$title='';
@ -30,28 +31,40 @@ class ReleaseBase extends CollectBase{
$title=$insertData;
}
model('Collected')->insert(array(
'url' => $url,
$collectedId=$mcollected->insert(array(
'urlMd5' => md5 ( $url ),
'titleMd5'=>empty($title)?'':md5($title),
'contentMd5'=>empty($content)?'':md5($content),
'task_id' => $release['task_id'],
'release' => $release['module'],
'addtime'=>time(),
'status'=>1
),false,true);
if($collectedId>0){
$mcollected->addInfo(array(
'id' => $collectedId,
'url' => $url,
'target' => $returnData['target'],
'desc' => $returnData['desc']?$returnData['desc']:'',
'error'=>'',
'task_id' => $release ['task_id'],
'release' => $release['module'],
'addtime'=>time()
));
}
if(!empty($returnData['target'])){
$target=$returnData['target'];
$echoData=array('成功将<a href="%s" target="_blank">内容</a>发布至:',$url);
$echoData=array('成功将<a href="%s" target="_blank">内容</a>发布至'.lang('collected_rele_'.$release['module']).'',$url);
if(preg_match('/^http(s){0,1}\:\/\//i',$target)){
$echoData[0].='<a href="%s" target="_blank">%s</a>';
$echoData[]=$target;
$echoData[]=$target;
}else{
$target=$mcollected->convertTarget($release['module'],$returnData['target']);
if($target==$returnData['target']){
$echoData[0].='%s';
$echoData[]=$target;
}else{
$echoData[0].=$target;
}
}
$this->echo_msg($echoData,'green',$echo);
}else{
@ -61,21 +74,27 @@ class ReleaseBase extends CollectBase{
if(!empty($returnData['error'])){
if(model('Collected')->collGetNumByUrl($url)<=0){
if($mcollected->collGetNumByUrl($url)<=0){
model('Collected')->insert(array(
'url' => $url,
$collectedId=$mcollected->insert(array(
'urlMd5' => md5 ( $url ),
'titleMd5'=>'',
'contentMd5'=>'',
'task_id' => $release['task_id'],
'release' => $release['module'],
'addtime'=>time(),
'status'=>0
),false,true);
if($collectedId>0){
$mcollected->addInfo(array(
'id' => $collectedId,
'url' => $url,
'target' => '',
'desc'=>'',
'error' => $returnData['error'],
'task_id' => $release['task_id'],
'release' => $release['module'],
'addtime'=>time()
));
}
}
$this->echo_msg(array('发布失败:%s',$returnData['error']),'red',$echo);
}
}

@ -132,7 +132,7 @@ return array(
'taskgroup_add'=>'添加分组',
'taskgroup_edit'=>'编辑分组',
'taskgroup'=>'任务分组',
'taskgroup_list'=>'分组列表',
'taskgroup_list'=>'任务分组列表',
'taskgroup_name'=>'分组名称',
'taskgroup_sort'=>'排序',
'taskgroup_sort_help'=>'数字越大越靠前',
@ -230,6 +230,7 @@ return array(
'rele_error_no_table'=>'该数据库没有表',
'rele_success_db_ok'=>'数据库连接成功',
'rele_module'=>'发布方式',
'rele_module_dataset'=>'数据集',
'rele_module_cms'=>'本地CMS程序',
'rele_module_db'=>'数据库',
'rele_module_api'=>'生成API',
@ -258,6 +259,7 @@ return array(
'collected_list'=>'已采集数据列表',
'COLLECTED_RELE_'=>'无',
'collected_rele_dataset'=>'数据集',
'collected_rele_cms'=>'CMS',
'collected_rele_db'=>'数据库',
'collected_rele_file'=>'文件',
@ -356,6 +358,17 @@ return array(
'tips_match_url'=>'示例:&lt;a href=&quot;http://demo.com/[内容123]/[内容abc]&quot;&gt;(*)&lt;/a&gt;',
'tips_matchn_url'=>'示例http://www.demo.com/[内容123]-[内容abc].html',
'ds_f_type_bigint'=>'数字',
'ds_f_type_double'=>'小数',
'ds_f_type_varchar'=>'字符串',
'ds_f_type_mediumtext'=>'文本',
'ds_f_type_datetime'=>'时间',
'ds_ix_type_index'=>'普通索引',
'ds_ix_type_unique'=>'唯一索引',
'ds_ix_type_fulltext'=>'全文索引',
'release_upgrade'=>'插件版本过低,请升级插件 <a href="https://www.skycaiji.com/manual/doc/release_upgrade" target="_blank">升级教程</a>',
);
?>

@ -134,7 +134,7 @@ CREATE TABLE `{$tname}` (
`dateline` int(10) unsigned NOT NULL,
`data` mediumblob NOT NULL,
PRIMARY KEY (`cname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
EOT;
db()->execute($table);
}

@ -22,7 +22,57 @@ class Collected extends \skycaiji\common\model\BaseModel{
parent::__construct($data);
}
}
public function collected_info_tname(){
return config('database.prefix').'collected_info';
}
public function getInfoDatas($collectedList){
init_array($collectedList);
$ids=array();
foreach ($collectedList as $k=>$v){
$ids[$v['id']]=$v['id'];
if($v&&!is_array($v)){
$v=$v->toArray();
$collectedList[$k]=$v;
}
}
if($ids){
$infoList=db()->table($this->collected_info_tname())->where('id','in',$ids)->column('*','id');
foreach ($collectedList as $k=>$v){
$info=$infoList[$v['id']];
if(is_array($info)&&$info){
$v=array_merge($v,$info);
$v['target']=$this->convertTarget($v['release'],$v['target']);
$collectedList[$k]=$v;
}
}
}
return $collectedList;
}
public function convertTarget($release,$target){
if($target&&$release=='dataset'){
if(preg_match('/\@(\d+)\:(\d+)/',$target,$mid)){
$target=sprintf('<a href="%s" target="_blank">%s</a>',url('dataset/db?ds_id='.$mid[1].'&id='.$mid[2]),$target);
}
}
return $target;
}
public function addInfo($infoData){
init_array($infoData);
if($infoData){
db()->table($this->collected_info_tname())->insert($infoData);
}
}
public function deleteByCond($cond){
init_array($cond);
if($cond){
$idSql=$this->db()->fetchSql(true)->field('id')->where($cond)->select();
db()->execute('delete from '.$this->collected_info_tname().' where id in ('.$idSql.')');
$this->where($cond)->delete();
}
}
/*采集时获取的数据*/
public function collGetNumByUrl($urls){
$cond=array();
@ -62,18 +112,35 @@ class Collected extends \skycaiji\common\model\BaseModel{
return $this->where($cond)->count();
}
public function collGetUrlByUrl($urls){
if(!is_array($urls)){
$urls=array($urls);
}
init_array($urls);
$urls=array_filter($urls);
$urls=array_map('md5', $urls);
$cond=array('urlMd5'=>array('in',$urls));
$dbUrls=array();
if($urls){
$urls1=array();
foreach ($urls as $k=>$v){
$urls1[md5($v)]=$v;
unset($urls[$k]);
}
$urls=$urls1;
unset($urls1);
$cond=array('urlMd5'=>array('in',array_keys($urls)));
if(g_sc_c('caiji','same_url')){
$cond=$this->_coll_cond_set_tid($cond);
}
return $this->field('`id`,`url`')->where($cond)->column('url','id');
$dbUrls=$this->field('`id`,`urlMd5`')->where($cond)->column('urlMd5','id');
if(!empty($dbUrls)){
foreach ($dbUrls as $k=>$v){
$v=$urls[$v];
if($v){
$dbUrls[$k]=$v;
}else{
unset($dbUrls[$k]);
}
}
}
}
return $dbUrls;
}
private function _coll_cond_set_tid($cond){
$cond=is_array($cond)?$cond:array();
@ -90,29 +157,43 @@ class Collected extends \skycaiji\common\model\BaseModel{
public function create_table(){
$tname=$this->get_table_name();
$exists=db()->query("show tables like '{$tname}'");
if(empty($exists)){
$table=<<<EOT
CREATE TABLE `{$tname}` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(1000) NOT NULL DEFAULT '',
`urlMd5` varchar(32) NOT NULL DEFAULT '',
`release` varchar(10) NOT NULL DEFAULT '',
`task_id` int(11) NOT NULL DEFAULT '0',
`target` varchar(1000) NOT NULL DEFAULT '',
`desc` varchar(1000) NOT NULL DEFAULT '',
`error` varchar(1000) NOT NULL DEFAULT '',
`addtime` int(11) NOT NULL DEFAULT '0',
`titleMd5` varchar(32) NOT NULL DEFAULT '',
`contentMd5` varchar(32) NOT NULL DEFAULT '',
`status` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `ix_urlmd5` (`urlMd5`),
KEY `ix_taskid` (`task_id`),
KEY `ix_addtime` (`addtime`),
KEY `ix_titlemd5` (`titleMd5`),
KEY `ix_contentmd5` (`contentMd5`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
KEY `ix_contentmd5` (`contentMd5`),
KEY `ix_status` (`status`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
EOT;
db()->execute($table);
}
$tname=$this->collected_info_tname();
$exists=db()->query("show tables like '{$tname}'");
if(empty($exists)){
$table=<<<EOT
CREATE TABLE `{$tname}` (
`id` int(11) NOT NULL DEFAULT '0',
`url` text,
`target` text,
`desc` text,
`error` text,
KEY `ix_id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
EOT;
db()->execute($table);
}

@ -303,10 +303,7 @@ class Config extends \skycaiji\common\model\Config {
$result['msg']='未检测到PHP可执行文件请手动输入';
}else{
$info=\util\Tools::cli_command_exec('collect cli --url_params '.base64_encode(json_encode(array('op'=>'php'))),$phpFile,array('showInfo'=>'all','closeProc'=>true));
init_array($info);
if(empty($info)){
$result['msg']='执行失败请检查web服务器是否拥有执行命令的权限';
}else{
$output=trim($info['output']);
$info['error']=trim($info['error']);
$info['output']=array();
@ -326,7 +323,6 @@ class Config extends \skycaiji\common\model\Config {
}
}
}
}
return $result;
}

@ -258,7 +258,7 @@ class Task extends \skycaiji\common\model\BaseModel{
if($taskLastTime>0&&(abs($timeNow-$taskLastTime)>$failedInterval)){
$taskFailedNum=$mcollected->where(array('task_id'=>$taskId,'addtime'=>array('GT',$taskLastTime),'error'=>array('<>','')))->count();
$taskFailedNum=$mcollected->where(array('task_id'=>$taskId,'addtime'=>array('GT',$taskLastTime),'status'=>0))->count();
if($taskFailedNum>0&&$taskFailedNum>$caijiConfig['failed_num']){
$mcacheEmail->setCache($taskKey,$timeNow);
@ -287,15 +287,15 @@ class Task extends \skycaiji\common\model\BaseModel{
$mcacheEmail->setCache($reportKey,$timeNow);
$report=array(
'today_success'=>0,'today_error'=>0,'today_tasks'=>array(),
'total_success'=>$mcollected->where("`target` <> ''")->count(),
'total_error'=>$mcollected->where("`error` <> ''")->count(),
'total_success'=>$mcollected->where('status',1)->count(),
'total_error'=>$mcollected->where('status',0)->count(),
'task_auto'=>$mtask->where('`auto`>0')->count(),
'task_other'=>$mtask->where('`auto`=0')->count(),
'caijitime'=>$mtask->where('`auto`>0')->max('caijitime'),
'autotime'=>CacheModel::getInstance()->getCache('collect_backstage_time','data'),
);
$todaySuccess=$mcollected->field('task_id,count(task_id)')->where(array('addtime'=>array('GT',$todayTime),'target'=>array('<>','')))->group('task_id')->column('count(task_id)','task_id');
$todayError=$mcollected->field('task_id,count(task_id)')->where(array('addtime'=>array('GT',$todayTime),'error'=>array('<>','')))->group('task_id')->column('count(task_id)','task_id');
$todaySuccess=$mcollected->field('task_id,count(task_id)')->where(array('addtime'=>array('GT',$todayTime),'status'=>1))->group('task_id')->column('count(task_id)','task_id');
$todayError=$mcollected->field('task_id,count(task_id)')->where(array('addtime'=>array('GT',$todayTime),'status'=>0))->group('task_id')->column('count(task_id)','task_id');
if($todaySuccess){
$report['today_success']=array_sum($todaySuccess);

@ -19,7 +19,7 @@
<tr>
<td>{php}$curIx++;{/php}{$curIx}</td>
<td class="desc">
{if condition="!empty($item['error'])"}
{if empty($item['status'])}
失败:{$item['error']}
{else /}
{$item['target']} {$item['desc']?$item['desc']:''}

@ -7,7 +7,7 @@
{block name="content"}
<div class="box">
<div class="box-body">
<div class="alert alert-warning alert-dismissible" style="padding-top:7px;padding-bottom:7px;line-height:20px;">
<div class="alert alert-warning alert-dismissible" style="padding-top:7px;padding-bottom:7px;line-height:30px;">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true" style="top:1px;">×</button>
已采集网址可防止重复采集,如无必要,请勿删除!
<button type="button" id="btn_clear_error" class="btn btn-sm btn-warning" style="padding:2px 10px;">清理失败的数据</button>
@ -33,7 +33,7 @@
<td class="chk"><input type="checkbox" name="ids[]" value="{$item['id']}" /></td>
<td class="url"><a href="{$item['url']}" target="_blank">{$item['url']}</a></td>
<td class="desc">
{if condition="!empty($item['error'])"}
{if empty($item['status'])}
失败:{$item['error']}
{else /}
{$item['target']} {$item['desc']?$item['desc']:''}
@ -92,7 +92,7 @@
<select name="status" class="form-control">
<option value="">全部</option>
<option value="1">发布成功</option>
<option value="2">发布失败</option>
<option value="0">发布失败</option>
</select>
</div>
<div class="form-group form-group-sm">

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/collector.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/collector.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}

@ -2,7 +2,7 @@
{block name="cssjs"}
{/block}
{block name="content"}
<form method="post" role="form" action="{:url('collector/export')}">
<form method="post" role="form" action="{:url('collector/export')}" target="_blank">
<div class="box box-default">
<div class="box-body" style="padding-bottom:0;">
{:html_usertoken()}

@ -1,6 +1,6 @@
{if condition="!empty($collList)"}
<div id="window_colls">
<ul class="row" id="coll_list">
<ul class="row" id="coll_list" {$pagenav?'':' style="margin-bottom:0;"'}>
{foreach name="collList" item="coll"}
{php}
if(!empty($taskNames[$coll['task_id']])){
@ -9,7 +9,7 @@
$collTitle='采集器:'.$coll['name'];
}
{/php}
<li class="col-xs-6" style="padding:0;">
<li class="col-xs-6" style="padding:3px 15px 3px 0;">
<a href="javascript:;" data-id="{$coll['id']}" data-title="{$collTitle|htmlentities}">
{$collTitle}
</a>

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/collector.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/collector.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}

@ -55,9 +55,9 @@
<li><a href="{:url('admin/setting/email')}"><i class="fa fa-circle-o"></i> {$Think.lang.setting_email}</a></li>
</ul>
</li>
<li class="treeview{$curMenu['task']}{$curMenu['taskgroup']}{$curMenu['collector']}{$curMenu['release']}">
<li class="treeview{$curMenu['task']}{$curMenu['taskgroup']}{$curMenu['collector']}{$curMenu['release']}{$curMenu['collected']}">
<a href="#">
<i class="fa fa-tasks"></i> <span>{$Think.lang.task}</span>
<i class="fa fa-th-list"></i> <span>{$Think.lang.task}</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
@ -65,17 +65,20 @@
<ul class="treeview-menu">
<li><a href="{:url('admin/task/list')}"><i class="fa fa-circle-o"></i> {$Think.lang.task_list}</a></li>
<li><a href="{:url('admin/task/set')}"><i class="fa fa-circle-o"></i> {$Think.lang.task_add}</a></li>
<li class="treeview{$curMenu['taskgroup']}">
<a href="#"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup}
<li><a href="{:url('admin/taskgroup/list')}"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup}</a></li>
<li><a href="{:url('admin/collected/list')}"><i class="fa fa-circle-o"></i> 已采集数据</a></li>
</ul>
</li>
<li class="treeview{$curMenu['dataset']}{$curMenu['dataapi']}">
<a href="#">
<i class="fa fa-database"></i> <span>数据</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="{:url('taskgroup/list')}"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup_list}</a></li>
<li><a href="{:url('taskgroup/add')}"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup_add}</a></li>
</ul>
</li>
<li><a href="{:url('admin/dataset/list')}"><i class="fa fa-circle-o"></i> 数据集</a></li>
<li><a href="{:url('admin/dataapi/list')}"><i class="fa fa-circle-o"></i> 数据接口</a></li>
</ul>
</li>
<li class="treeview{$curMenu['store']}{$curMenu['mystore']}{$curMenu['provider']}">
@ -103,18 +106,6 @@
</li>
</ul>
</li>
<li class="treeview{$curMenu['collected']}">
<a href="#">
<i class="fa fa-database"></i> <span>{$Think.lang.collected}</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="{:url('admin/collected/list')}"><i class="fa fa-circle-o"></i> 数据列表</a></li>
<li><a href="{:url('admin/collected/chart')}"><i class="fa fa-circle-o"></i> 统计图表</a></li>
</ul>
</li>
<li class="treeview{$curMenu['user']}">
<a href="#">
<i class="fa fa-user"></i> <span>{$Think.lang.user}</span>

@ -154,13 +154,13 @@
</div>
</div>
<div class="c-p-field-extract-module" extract-module="rule" style="display:none;">
{include file="cpattern:rule_module" _type="rule" _name="field" _name_pre="extract_" _allow_loop="" /}
{include file="cpattern:rule_module" _type="rule" _name="field" _name_pre="extract_" _allow_loop="1" /}
</div>
<div class="c-p-field-extract-module" extract-module="xpath" style="display:none;">
{include file="cpattern:rule_module" _type="xpath" _name="field" _name_pre="extract_" _allow_loop="" /}
{include file="cpattern:rule_module" _type="xpath" _name="field" _name_pre="extract_" _allow_loop="1" /}
</div>
<div class="c-p-field-extract-module" extract-module="json" style="display:none;">
{include file="cpattern:rule_module" _type="json" _name="field" _name_pre="extract_" _allow_loop="" /}
{include file="cpattern:rule_module" _type="json" _name="field" _name_pre="extract_" _allow_loop="1" /}
</div>
</div>
<div class="c-p-field-module" module="sign" style="display:none;">

@ -42,6 +42,7 @@
</section>
</div>
<div class="c-p-process-module" module="insert">
<section>
<div class="form-group">
<label>位置</label>
<select data-process="insert:insert_loc" class="form-control">
@ -54,7 +55,9 @@
<div class="form-group">
<label>内容</label>
<textarea data-process="insert:insert_txt" rows="3" class="form-control"></textarea>
<p class="help-block">可输入任何内容或 <select class="p-m-insert-field"><option value="">插入字段</option></select></p>
</div>
</section>
</div>
<div class="c-p-process-module" module="replace">
<div class="input-group">
@ -262,6 +265,7 @@
&nbsp; <label><input type="checkbox" data-process="tool:tool_list" value="url_not_complete" />禁止补全网址</label>
&nbsp; <label title="将网址替换成重定向后的真实地址"><input type="checkbox" data-process="tool:tool_list" value="url_real" />网址真实地址</label>
&nbsp; <label title="从html中提取出音视频网址建议字段的值是渲染后的html"><input type="checkbox" data-process="tool:tool_list" value="vedio_url" />提取音视频网址</label>
&nbsp; <label title="将文本中的网址补齐为&lt;img src=&quot;网址&quot;&gt;"><input type="checkbox" data-process="tool:tool_list" value="img_tag" />补齐为&lt;img&gt;标签</label>
</div>
</div>
<div class="c-p-process-module" module="download">

@ -167,7 +167,7 @@
<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 c-p-request-headers">
<table class="table table-bordered">
<table class="table table-bordered table-hover">
<thead>
<tr>
<td>名称</td>
@ -213,7 +213,7 @@
<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 c-p-request-headers-img">
<table class="table table-bordered">
<table class="table table-bordered table-hover">
<thead>
<tr>
<td>名称</td>
@ -259,7 +259,7 @@
<div class="form-group">
<label class="control-label">自定义 <a href="javascript:;" class="glyphicon glyphicon-plus add-request-header-file" title="添加"></a></label>
<div class="table-responsive c-p-request-headers-file">
<table class="table table-bordered">
<table class="table table-bordered table-hover">
<thead>
<tr>
<td>名称</td>

@ -178,9 +178,9 @@
<thead>
<tr>
<th class="sorting">页面</th>
<th>区域</th>
<th>网址</th>
<th>提取</th>
<th title="“获取网址区域”中的{:cp_sign('match')}标签">区域</th>
<th title="“提取网址规则”中的{:cp_sign('match')}标签">网址</th>
<th title="“提取内容标签”中的{:cp_sign('match')}标签">提取</th>
</tr>
</thead>
<tbody>

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/collector.css?{$Think.config.html_v}">
{/block}
{block name="content"}
<div class="box box-default">

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/collector.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/collector.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/collector.css?{$Think.config.html_v}">
{/block}
{block name="content"}
<div class="box box-default">

@ -0,0 +1,78 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/dataapi.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/dataapi.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div class="box">
<div class="box-body">
<form id="form_list" method="post" ajax-submit="true" action="{:url('dataapi/op')}">
{:html_usertoken()}
<div class="table-responsive" style="border:0;">
<table id="dataapi_list" class="table table-hover datatable">
<thead>
<tr>
<th>{$Think.lang.sort}</th>
<th>名称</th>
<th>ID</th>
<th>状态</th>
<th>数据集</th>
<th style="width:150px;">{$Think.lang.op}</th>
</tr>
</thead>
<tbody>
{foreach name="daList" item="item"}
<tr data-ds-id="{$item['id']}" data-da-id="{$item['id']}">
<td class="sort"><input type="text" name="newsort[{$item['id']}]" class="form-control" value="{$item['sort']}" autocomplete="off" /></td>
<td><a href="{:url('dataapi/set?id='.$item['id'])}">{$item['name']}</a></td>
<td>{$item['id']}</td>
<td><a href="javascript:;" class="status{$item['status']?'':' status-close'}">{$item['status']?'开启':'关闭'}</a></td>
<td><a href="{:url('dataset/set?id='.$item['ds_id'])}">{$dsNames[$item['ds_id']]}</a></td>
<td>
<ul class="in-line">
<li><a href="{:url('dataapi/set?id='.$item['id'])}">编辑</a></li>
<li class="sep">|</li>
<li><a href="javascript:;" class="delete">{$Think.lang.delete}</a></li>
</ul>
</td>
</tr>
{/foreach}
</tbody>
<tfoot>
<tr>
<td colspan="5">
<button type="submit" class="btn btn-default">{$Think.lang.save}</button>
<a href="{:url('dataapi/set')}" class="btn btn-primary">添加数据接口</a>
</td>
</tr>
{if condition="!empty($pagenav)"}
<tr>
<td colspan="5">{$pagenav}</td>
</tr>
{/if}
</tfoot>
</table>
</div>
</form>
</div>
</div>
<div class="list-footer">
<form id="form_search" method="post" action="{:url('dataapi/list')}" class="form-inline">
{:html_usertoken()}
<div class="form-group form-group-sm">
<label>ID</label>
<input type="number" name="id" class="form-control" value="" placeholder="精确搜索" autocomplete="off" />
</div>
<div class="form-group form-group-sm">
<label>名称</label>
<input type="text" name="name" class="form-control" value="" placeholder="模糊搜索" autocomplete="off" />
</div>
<div class="form-group form-group-sm">
<button type="submit" class="btn btn-default btn-sm">{$Think.lang.search}</button>
</div>
</form>
</div>
<script type="text/javascript">
dataapiClass.init_list({$search|json_encode});
</script>
{/block}

@ -0,0 +1,247 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/dataapi.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/dataapi.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<form id="form_dataapi" method="post" ajax-submit="true" role="form" action="{:url('admin/dataapi/set')}">
{if !empty($daData)}
<input type="hidden" name="id" value="{$daData['id']}" />
{/if}
<div class="box box-default">
<div class="box-body" style="padding-bottom:0;">
{:html_usertoken()}
<div class="form-group">
<label>名称</label>
<div class="input-group">
<input type="text" name="name" class="form-control" autocomplete="off" placeholder="数据接口名称" />
<span class="input-group-addon brl_0 brr_0">网址别名</span>
<input type="text" name="route" class="form-control" autocomplete="off" placeholder="选填,可通过该别名访问接口" />
</div>
</div>
<div class="form-group">
<label>状态</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="status" value="1">开启</label>
<label class="radio-inline"><input type="radio" name="status" value="0" checked="checked">关闭</label>
</div>
</div>
<div class="form-group">
<label>描述</label>
<textarea name="desc" class="form-control" placeholder="选填"></textarea>
</div>
<div class="form-group">
<label>排序</label>
<input type="number" class="form-control" name="sort" autocomplete="off" value="0">
<p class="help-block">数字越大越靠前</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">接口配置</div>
</div>
<div class="panel-body">
<div class="form-group">
<label>请求方式</label>
<select name="config[api_method]" class="form-control">
<option value="">同时允许GET和POST</option>
<option value="get">仅限GET</option>
<option value="post">仅限POST</option>
</select>
</div>
<div class="form-group">
<label>密钥</label>
<div class="input-group">
<span class="input-group-addon">密钥</span>
<input type="text" class="form-control" name="config[api_key]" placeholder="选填,防止接口被盗用" autocomplete="off">
<span class="input-group-addon brl_0 brr_0">模式</span>
<select name="config[api_mode]" class="form-control">
<option value="">便捷(密钥明文传输有泄露风险)</option>
<option value="safe">安全(需要签名处理)</option>
</select>
</div>
<p class="help-block"></p>
</div>
<div class="form-group">
<label>数据量</label>
<div class="input-group">
<span class="input-group-addon">每页最大数量</span>
<input type="number" name="config[page_per]" class="form-control" placeholder="默认50" />
<span class="input-group-addon brl_0 brr_0">最大分页数</span>
<input type="number" name="config[page_max]" class="form-control" placeholder="默认不限制" />
<span class="input-group-addon brl_0 brr_0">分页参数名</span>
<input type="text" name="config[page_name]" class="form-control" placeholder="默认p" />
</div>
<p class="help-block">限制接口输出的数据量</p>
</div>
</div>
</div>
<div class="form-group">
<input type="hidden" name="ds_id" class="form-control"/>
<button type="button" class="btn btn-default btn-block" style="font-weight:bold;" id="btn_dataset">绑定数据集</button>
</div>
<div class="panel panel-default" id="config_conds_box" style="display:none;">
<div class="panel-heading">
<div class="panel-title">数据查询</div>
</div>
<div class="panel-body" style="padding:0;">
<div class="table-responsive">
<table class="table table-hover" id="config_conds">
<thead>
<tr>
<th>条件逻辑</th>
<th>数据集字段</th>
<th>条件判断</th>
<th>传入参数名 <a href="javascript:;" class="glyphicon glyphicon-info-sign icon-info-tips" id="tips_config_cond" title="提示信息"></a></th>
<th style="width:90px;">操作 <a href="javascript:;" class="glyphicon glyphicon-plus" id="add_config_cond" style="font-size:12px;" title="添加条件"></a></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="panel-body">
<div class="form-group">
<label>排序字段</label>
<div class="input-group">
<select name="config[order_field]" class="form-control">
<option value=""></option>
</select>
<div class="input-group-addon">
<label class="radio-inline"><input type="radio" name="config[order_sort]" value="" checked="checked">升序</label>
<label class="radio-inline"><input type="radio" name="config[order_sort]" value="desc">降序</label>
</div>
</div>
</div>
<div class="form-group">
<label>隐藏字段</label>
<div id="config_hide_fields"></div>
<p class="help-block">勾选的字段不会在接口中显示</p>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
{if !empty($daData)}
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">使用接口</div>
</div>
<div class="panel-body">
<table class="table" style="margin-bottom:0;">
<tr>
<td style="width:80px;border-top:0">接口网址</td>
<td style="border-top:0">
{if $isSafeMode}
{$apiUrl.'签名_时间戳'}
<div class="help-block">
由于密钥启用了安全模式,需将“签名”替换成 md5({$config['api_key']|md5}+时间戳)注意时间戳是10位数字不是日期格式<br>
PHP中的示例$url='{$apiUrl}'.md5('{$config['api_key']|md5}'.time()).'_'.time();
</div>
{else/}
{$apiUrl}
{/if}
</td>
</tr>
<tr>
<td>请求方式</td>
<td>{$config['api_method']?$config['api_method']:'不限制'}</td>
</tr>
{if !empty($groupConds)}
<tr>
<td>发送数据</td>
<td>
{foreach $groupConds as $kgc=>$conds}
<div style="margin-bottom:15px;">
{if $kgc>0}
<div style="text-align:left;margin-bottom:15px;font-size:16px;font-weight:bold;">或者</div>
{/if}
<div style="border:3px solid #eee;border-radius:5px;display:inline-block;">
<table class="table table-bordered" style="width:auto;margin:0">
<tr>
<td style="text-align:right">条件</td>
<td>参数名</td>
</tr>
{foreach $conds as $kc=>$cond}
{if $kc>0}
<tr>
<td style="text-align:right;border-right:0;"><b>并且</b></td>
<td style="border-left:0;"></td>
</tr>
{/if}
{if empty($cond['subs'])}
<tr>
<td style="text-align:right">字段"{$fieldNames[$cond['field']]}" {$condOps[$cond['op']]}</td>
<td>{$cond['name']}</td>
</tr>
{else/}
{foreach $cond['subs'] as $kcs=>$condSubs}
{if $kcs>0}
<tr>
<td></td>
<td>或者</td>
</tr>
{/if}
{foreach $condSubs as $condSub}
<tr>
<td style="text-align:right">字段"{$fieldNames[$condSub['field']]}" {$condOps[$condSub['op']]}</td>
<td>{$condSub['name']}</td>
</tr>
{/foreach}
{/foreach}
{/if}
{/foreach}
</table>
</div>
</div>
{/foreach}
{if count($groupConds)>1}
<p class="help-block">满足其中一组条件即可执行数据查询</p>
{/if}
</td>
</tr>
{/if}
</table>
</div>
</div>
{/if}
<table style="display:none;">
<tr id="tpl_config_cond">
<td>
<input type="hidden" name="conds[sub][]" value="" />
<select class="form-control" name="conds[logic][]">
<option value="and">并且</option>
<option value="or">或者</option>
</select>
</td>
<td>
<select class="form-control" name="conds[field][]">
<option value=""></option>
</select>
</td>
<td>
<select class="form-control" name="conds[op][]">
<option value=""></option>
{foreach $condOps as $k=>$v}
<option value="{$k}">{$v}</option>
{/foreach}
</select>
</td>
<td>
<input type="text" name="conds[name][]" class="form-control" value="" placeholder="" autocomplete="off" />
</td>
<td>
<a href="javascript:;" class="glyphicon icon-drag-move config-cond-move" title="移动"></a>
<a href="javascript:;" class="fa fa-remove config-cond-dlt" title="删除"></a>
<a href="javascript:;" class="fa fa-plus config-cond-add" title="添加子条件"></a>
</td>
</tr>
</table>
<script type="text/javascript">
dataapiClass.init({$daData|json_encode});
</script>
{/block}

@ -0,0 +1,103 @@
{extend name="common:main" /}
{block name="cssjs"}
<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>
<link rel="stylesheet" href="__PUBLIC__/static/css/dataset.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/dataset.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div class="box">
<div class="box-body">
<form id="form_list" ajax-submit="true" method="post" action="{:url('dataset/dbSet')}">
<div class="overlay">
<i class="fa fa-refresh fa-spin"></i>
</div>
{:html_usertoken()}
{if !empty($dsData)}
<input type="hidden" name="ds_id" value="{$dsData['id']}"/>
{/if}
<div class="table-responsive dataset-db-list" style="border:0;">
<table id="dataset_db_list" class="table table-striped datatable">
<thead>
<tr>
<th class="chk">ID</th>
{foreach $fields as $field}
<th>{$field['name']}</th>
{/foreach}
<th style="width:50px;">{$Think.lang.op}</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
{php}$colspan=count($fields)+2;{/php}
<tr>
<td class="chk"><label class="chk-all"><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')"><span>全部</span></label></td>
<td colspan="{$colspan}">
<button type="submit" class="btn btn-default">保存</button>
<button type="button" class="btn btn-danger" id="deleteall">删除</button>
<button type="button" class="btn btn-primary" id="addnew">新增</button>
</td>
</tr>
{if condition="!empty($pagenav)"}
<tr>
<td colspan="{$colspan+1}">{$pagenav}</td>
</tr>
{/if}
</tfoot>
</table>
</div>
</form>
</div>
</div>
<div class="list-footer dataset-search">
<form id="form_search" method="post" action="{:url('dataset/db')}" class="form-inline">
{:html_usertoken()}
{if !empty($dsData)}
<input type="hidden" name="ds_id" value="{$dsData['id']}"/>
{/if}
<div class="form-group form-group-sm" style="margin-bottom:5px;">
<label>每页显示</label>
<select name="num" class="form-control">
<option value="30">30</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="200">200</option>
<option value="300">300</option>
</select>
</div>
<div class="form-group form-group-sm" style="margin-bottom:5px;">
<label>ID</label>
<input type="number" name="id" class="form-control" value="" placeholder="精确搜索" autocomplete="off" />
</div>
{foreach $fields as $fname=>$field}
<div class="form-group form-group-sm" style="margin-bottom:5px;">
<label>{$field['name']}</label>
<input type="text" name="{$fname}" class="form-control" value="" placeholder="模糊搜索" autocomplete="off" />
</div>
{/foreach}
<div class="form-group form-group-sm" style="margin-bottom:5px;margin-right:10px;">
<button type="submit" class="btn btn-default btn-sm">{$Think.lang.search}</button>
</div>
</form>
</div>
<table style="display:none;">
<tr id="tpl_db" data-db-id="">
<td class="chk"><label class="checkbox-inline"><input type="checkbox" name="ids[]" value=""> <span data-field="id"></span></label></td>
{foreach $fields as $fname=>$field}
<td>
{if $field['type']=='mediumtext'}
<textarea data-field="{$fname}" name="{$fname}[_id_]" class="form-control" placeholder="{:lang('ds_f_type_'.$field['type'])}"></textarea>
{else/}
<input type="{if $field['type']=='bigint'}number{else/}text{/if}" data-field="{$fname}" name="{$fname}[_id_]" class="form-control{if $field['type']=='datetime'} db-time{/if}" placeholder="{:lang('ds_f_type_'.$field['type'])}" autocomplete="off" />
{/if}
</td>
{/foreach}
<td><a href="javascript:;" class="db-delete">{$Think.lang.delete}</a></td>
</tr>
</table>
<script type="text/javascript">
datasetClass.db_init({$list|json_encode},{$search|json_encode});
</script>
{/block}

@ -0,0 +1,39 @@
<form id="form_field" method="post" action="{:url('dataset/field')}">
{:html_usertoken()}
<input type="hidden" name="objid" value="" />
<input type="hidden" name="is_submit" value="1" />
<div class="form-group">
<label>字段名称</label>
<input type="text" name="name" class="form-control" autocomplete="off" value="" />
<input type="hidden" name="name_original" value="" />
</div>
<div class="form-group">
<label>数据类型</label>
<div class="input-group input-select-custom">
<div class="input-group-btn">
<select name="type" class="form-control">
<option value="">请选择</option>
<option value="bigint">{$Think.lang.ds_f_type_bigint}</option>
<option value="double">{$Think.lang.ds_f_type_double}</option>
<option value="varchar">{$Think.lang.ds_f_type_varchar}</option>
<option value="mediumtext">{$Think.lang.ds_f_type_mediumtext}</option>
<option value="datetime">{$Think.lang.ds_f_type_datetime}</option>
</select>
</div>
<input type="number" name="len" class="form-control" placeholder="长度默认500" autocomplete="off" />
</div>
{if !empty($field['name_original'])}
<p class="help-block">修改类型可能会造成数据丢失,请谨慎操作!</p>
{/if}
</div>
<div class="form-group">
<label>字段描述</label>
<textarea name="desc" class="form-control" placeholder="选填"></textarea>
</div>
<div class="form-group form-group-sm">
<button type="submit" class="btn btn-primary btn-block">确定</button>
</div>
</form>
<script type="text/javascript">
datasetClass.field_init('{$objid}',{$field|json_encode});
</script>

@ -0,0 +1,61 @@
<div id="win_dataset_indexes" style="margin-top:-10px;margin-bottom:-10px;">
<form method="post" ajax-submit="true" action="{:url('dataset/indexes')}">
{:html_usertoken()}
{if !empty($dsData)}
<input type="hidden" name="ds_id" value="{$dsData['id']}" />
{/if}
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover index-list">
<thead>
<tr>
<th style="width:130px;">索引类型</th>
<th>字段(多个字段为联合索引)</th>
<th style="width:70px;">操作<a href="javascript:;" class="glyphicon glyphicon-plus index-add-index" style="margin-left:5px;font-size:12px;" title="添加索引"></a></th>
</tr>
</thead>
</table>
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">保存</button>
</form>
<div class="index-tpl" style="display:none;">
<table>
<tr data-tpl="index">
<td>
<select class="form-control index-type">
<option value=""></option>
<option value="index">{$Think.lang.ds_ix_type_index}</option>
<option value="unique">{$Think.lang.ds_ix_type_unique}</option>
<option value="fulltext">{$Think.lang.ds_ix_type_fulltext}</option>
</select>
</td>
<td>
<table class="table">
<tr class="index-fields"></tr>
</table>
</td>
<td>
<div class="input-group">
<div class="input-group-addon"><a href="javascript:;" class="glyphicon glyphicon-plus index-add-field" style="font-size:12px;" title="添加字段"></a></div>
<div class="input-group-addon" style="border-left:1px solid #d2d6de;"><a href="javascript:;" class="glyphicon glyphicon-remove index-delete-index" style="font-size:12px;" title="删除索引"></a></div>
</div>
</td>
</tr>
<tr>
<td data-tpl="fields">
<select class="form-control index-field">
<option value=""></option>
{foreach $fields as $k=>$v}
<option value="{$k}" data-type="{$v['type']}">{$v['name']}</option>
{/foreach}
<option value="-1">删除字段</option>
</select>
</td>
</tr>
</table>
</div>
</div>
<script type="text/javascript">
datasetClass.indexes_init({$dbIndexes|json_encode});
</script>

@ -0,0 +1,80 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/dataset.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/dataset.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div class="box">
<div class="box-body">
<form id="form_list" method="post" ajax-submit="true" action="{:url('dataset/op')}">
{:html_usertoken()}
<div class="table-responsive" style="border:0;">
<table id="dataset_list" class="table table-hover datatable">
<thead>
<tr>
<th>{$Think.lang.sort}</th>
<th style="width:150px;">名称</th>
<th style="width:50px;">ID</th>
<th>字段</th>
<th style="width:100px;">数据量</th>
<th style="width:150px;">{$Think.lang.op}</th>
</tr>
</thead>
<tbody>
{foreach name="dsList" item="item"}
<tr data-ds-id="{$item['id']}">
<td class="sort"><input type="text" name="newsort[{$item['id']}]" class="form-control" value="{$item['sort']}" autocomplete="off" /></td>
<td><a href="{:url('dataset/set?id='.$item['id'])}">{$item['name']}</a></td>
<td>{$item['id']}</td>
<td>{if !empty($dsFields[$item['id']])}<input type="text" class="form-control fields" readonly="true" value="{$dsFields[$item['id']]|htmlspecialchars}">{/if}</td>
<td><a href="{:url('dataset/db?ds_id='.$item['id'])}" class="db-count">0</a></td>
<td>
<ul class="in-line">
<li><a href="{:url('dataset/db?ds_id='.$item['id'])}">数据</a></li>
<li class="sep">|</li>
<li><a href="{:url('dataset/set?id='.$item['id'])}">编辑</a></li>
<li class="sep">|</li>
<li><a href="javascript:;" class="delete">{$Think.lang.delete}</a></li>
</ul>
</td>
</tr>
{/foreach}
</tbody>
<tfoot>
<tr>
<td colspan="5">
<button type="submit" class="btn btn-default">{$Think.lang.save}</button>
<a href="{:url('dataset/set')}" class="btn btn-primary">添加数据集</a>
</td>
</tr>
{if condition="!empty($pagenav)"}
<tr>
<td colspan="5">{$pagenav}</td>
</tr>
{/if}
</tfoot>
</table>
</div>
</form>
</div>
</div>
<div class="list-footer">
<form id="form_search" method="post" action="{:url('dataset/list')}" class="form-inline">
{:html_usertoken()}
<div class="form-group form-group-sm">
<label>ID</label>
<input type="number" name="id" class="form-control" value="" placeholder="精确搜索" autocomplete="off" />
</div>
<div class="form-group form-group-sm">
<label>名称</label>
<input type="text" name="name" class="form-control" value="" placeholder="模糊搜索" autocomplete="off" />
</div>
<div class="form-group form-group-sm">
<button type="submit" class="btn btn-default btn-sm">{$Think.lang.search}</button>
</div>
</form>
</div>
<script type="text/javascript">
datasetClass.init_list({$search|json_encode});
</script>
{/block}

@ -0,0 +1,51 @@
{if !empty($dsList)}
<div id="window_dataset_list">
<ul class="row">
{foreach $dsList as $v}
<li class="col-xs-6" style="padding:3px 15px 3px 0;">
<a href="javascript:;" data-id="{$v['id']}" data-title="{$v['name']|htmlentities}">
{$v['name']}
</a>
</li>
{/foreach}
</ul>
{$pagenav}
<form method="get" action="{:url('dataset/select?from='.$from)}" class="form-inline" style="padding-top:15px;margin-top:10px;border-top:solid 1px #f4f4f4;">
{:html_usertoken()}
<div class="form-group form-group-sm">
<label>ID</label>
<input type="number" name="id" class="form-control" value="{$search['id']}" placeholder="精确搜索" />
</div>
<div class="form-group form-group-sm">
<label>名称</label>
<input type="text" name="name" class="form-control" value="{$search['name']}" placeholder="模糊搜索" />
</div>
<div class="form-group form-group-sm">
<button type="submit" class="btn btn-default btn-sm" style="margin-bottom:0;">{$Think.lang.search}</button>
</div>
</form>
</div>
{else/}
没有数据集!<a href="{:url('dataset/set')}" target="_blank">创建一个</a>
{/if}
<script type="text/javascript">
'use strict';
(function(){
$('#window_dataset_list .pagination').addClass('pagination-sm');
$('#window_dataset_list .pagination a').bind('click',function(){
windowModal('数据集',$(this).attr('href'));
return false;
});
$('#window_dataset_list form').bind('submit',function(){
windowModal('数据集',$(this).attr('action'),{ajax:{data:$(this).serialize()}});
return false;
});
$('#window_dataset_list a[data-id]').bind('click',function(){
{if $from=='release'}
releaseClass.dataset_load({'dataset_id':$(this).attr('data-id')});
{else if $from=='dataapi'}
dataapiClass.dataset_load({'dataset_id':$(this).attr('data-id')});
{/if}
});
})();
</script>

@ -0,0 +1,83 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/dataset.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/dataset.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<form id="form_dataset" method="post" role="form" action="{:url('admin/dataset/set')}">
{if !empty($dsData)}
<input type="hidden" name="id" value="{$dsData['id']}" />
{/if}
<div class="box box-default">
<div class="box-body" style="padding-bottom:0;">
{:html_usertoken()}
<div class="form-group">
<label>名称</label>
<input type="text" name="name" class="form-control" autocomplete="off" />
</div>
<div class="form-group">
<label>描述</label>
<textarea name="desc" class="form-control" placeholder="选填"></textarea>
</div>
<div class="form-group">
<label>排序</label>
<input type="number" class="form-control" name="sort" autocomplete="off" value="{$dsData?intval($dsData['sort']):0}">
<p class="help-block">数字越大越靠前</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body" style="padding:0;">
<div class="table-responsive">
<table class="table table-hover ui-sortable" id="dataset_fields">
<thead>
<tr>
<th style="width:200px">字段名称</th>
<th>数据类型</th>
<th>字段描述</th>
<th style="width:80px">操作 <a href="javascript:;" class="glyphicon glyphicon-plus" id="add_dataset_field" style="font-size:12px;" title="添加字段"></a></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
{if !empty($dsData)}
<div class="panel panel-default">
<div class="panel-heading">
<a href="javascript:;" id="set_dataset_indexes">设置索引</a> <span class="dataset-sep">|</span>
<a href="{:url('dataset/db?ds_id='.$dsData['id'])}">查看数据</a>
</div>
{if !empty($indexes)}
<div class="panel-body">
{foreach $indexes as $k=>$v}
<span class="label label-default" style="font-size:12px;margin-left:5px;">{$v['type']}{:implode(',',$v['fields'])}</span>
{/foreach}
</div>
{/if}
</div>
{/if}
<table style="display:none;">
<tr id="tpl_field">
<td><a href="javascript:;" class="field-name" data-dbname="" style="white-space:nowrap;"></a></td>
<td>
<span class="field-type"></span>
</td>
<td class="field-desc"></td>
<td>
<input type="hidden" name="fields[]" value="" />
<a href="javascript:;" class="glyphicon icon-drag-move field-move" style="font-size:12px;" title="移动"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove field-dlt" style="font-size:12px;" title="删除"></a>
</td>
</tr>
</table>
<script type="text/javascript">
datasetClass.init({$dsData|json_encode});
</script>
{/block}

@ -127,8 +127,6 @@
<label class="control-label">扩展</label>
<a href="javascript:;" id="add_pack" class="glyphicon glyphicon-plus" title="添加"></a>
</div>
</div>
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover" id="pack_list" style="margin-bottom:0;">
<thead>

@ -65,8 +65,6 @@
<label class="control-label">参数</label>
<a href="javascript:;" id="add_param" class="glyphicon glyphicon-plus" title="添加"></a>
</div>
</div>
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover" id="param_list" style="margin-bottom:0;">
<thead>

@ -65,7 +65,7 @@
<td class="chk"><label class="chk-all"><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" /><span>全部</span></label></td>
<td colspan="2">
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
&nbsp;<a href="{:url('develop/func')}" class="btn btn btn-success">开发一个</a>
&nbsp;<a href="{:url('develop/func')}" class="btn btn-primary">开发一个</a>
</td>
<td colspan="5" style="text-align:right;font-size:12px;">
{if !empty($appList)}

@ -60,7 +60,7 @@
<td class="chk"><label class="chk-all"><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" /><span>全部</span></label></td>
<td colspan="2">
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
&nbsp;<a href="{:url('develop/releaseCms')}" class="btn btn btn-success">开发一个</a>
&nbsp;<a href="{:url('develop/releaseCms')}" class="btn btn-primary">开发一个</a>
</td>
<td colspan="5" style="text-align:right;font-size:12px;">
{if !empty($appList)}

@ -1,8 +1,8 @@
{if condition="!empty($ruleList)"}
<div id="window_rules">
<ul class="row" id="rule_list">
<ul class="row" id="rule_list" {$pagenav?'':' style="margin-bottom:0;"'}>
{foreach name="ruleList" item="rule"}
<li class="col-xs-6" style="padding:0;"><a href="javascript:;" data-id="{$rule['id']}" data-title="{$rule['name']|htmlentities}">{$rule['name']}</a></li>
<li class="col-xs-6" style="padding:3px 15px 3px 0;"><a href="javascript:;" data-id="{$rule['id']}" data-title="{$rule['name']|htmlentities}">{$rule['name']}</a></li>
{/foreach}
</ul>
{$pagenav}

@ -9,7 +9,7 @@
<th>密码(选填)</th>
<th>类型</th>
<th>分组</th>
<th style="width:65px;">操作 <a href="javascript:;" class="glyphicon glyphicon-plus add-proxy-ip" style="font-size:11px;" title="添加"></a></th>
<th style="width:65px;">操作 <a href="javascript:;" class="glyphicon glyphicon-plus add-proxy-ip" title="添加"></a></th>
</tr>
</thead>
<tbody>

@ -6,7 +6,7 @@
<tr>
<th style="width:100px;">排序</th>
<th>分组名称</th>
<th style="width:65px;">操作 <a href="javascript:;" class="glyphicon glyphicon-plus proxy-group-add" style="font-size:11px;" title="添加"></a></th>
<th style="width:65px;">操作 <a href="javascript:;" class="glyphicon glyphicon-plus proxy-group-add" title="添加"></a></th>
</tr>
</thead>
<tbody>

@ -0,0 +1,40 @@
<div class="box box-primary">
<div class="box-body">
<input type="hidden" name="dataset[dataset_id]" value="{$dsData['id']|intval}" />
<table class="table">
<thead>
<tr>
<th>数据集</th>
<th>绑定数据</th>
</tr>
</thead>
<tbody>
{foreach $fields as $k=>$v}
<tr>
<td>{$v['name']}</td>
<td>
<div class="input-group dataset-field-txt">
<input type="text" name="dataset[fields][{$k}]" class="form-control" autocomplete="off" />
<div class="input-group-addon">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">字段 <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right">
{if !empty($collFields)}
{foreach $collFields as $v}
<li><a href="javascript:;" data-val="[采集字段:{$v}]">采集字段:{$v}</a></li>
{/foreach}
{/if}
</ul>
</div>
</div>
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
(function(){
$('#rele_module_dataset #btn_dataset').html("数据集:{$dsData['name']?:''} <span class='caret'></span>");
})();
</script>

@ -27,7 +27,7 @@
<th>条件值</th>
<th style="width:70px;min-width:70px;">
操作
<a href="javascript:;" class="glyphicon glyphicon-plus db-table-bind-where-add" style="font-size:11px;" title="添加"></a>
<a href="javascript:;" class="glyphicon glyphicon-plus db-table-bind-where-add" style="font-size:12px;" title="添加"></a>
</th>
</tr>
</thead>
@ -77,8 +77,8 @@
</div>
</td>
<td style="padding-top:15px;padding-bottom:0;">
<a href="javascript:;" class="glyphicon icon-drag-move db-table-bind-where-move" style="font-size:11px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove db-table-bind-where-del" style="font-size:11px;"></a>
<a href="javascript:;" class="glyphicon icon-drag-move db-table-bind-where-move" style="font-size:12px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove db-table-bind-where-del" style="font-size:12px;"></a>
</td>
</tr>
</tbody>
@ -93,7 +93,7 @@
<th>输入名称以供调用</th>
<th style="width:70px;min-width:70px;">
操作
<a href="javascript:;" class="glyphicon glyphicon-plus db-table-bind-query-add" style="font-size:11px;" title="添加"></a>
<a href="javascript:;" class="glyphicon glyphicon-plus db-table-bind-query-add" style="font-size:12px;" title="添加"></a>
</th>
</tr>
</thead>
@ -123,7 +123,7 @@
<input type="text" class="form-control" data-name="[query][sign][]" placeholder="默认使用字段名称" />
</td>
<td style="padding-top:15px;padding-bottom:0;">
<a href="javascript:;" class="glyphicon glyphicon-remove db-table-bind-query-del" style="font-size:11px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove db-table-bind-query-del" style="font-size:12px;"></a>
</td>
</tr>
</tbody>

@ -2,7 +2,7 @@
{block name="cssjs"}
{/block}
{block name="content"}
<form method="post" role="form" action="{:url('release/export')}">
<form method="post" role="form" action="{:url('release/export')}" target="_blank">
<div class="box box-default">
<div class="box-body" style="padding-bottom:0;">
{:html_usertoken()}

@ -1,6 +1,6 @@
{if condition="!empty($releList)"}
<div id="window_reles">
<ul class="row" id="rele_list">
<ul class="row" id="rele_list" {$pagenav?'':' style="margin-bottom:0;"'}>
{foreach name="releList" item="rele"}
{php}
if(!empty($taskNames[$rele['task_id']])){
@ -9,7 +9,7 @@
$releTitle='发布:'.$rele['name'];
}
{/php}
<li class="col-xs-6" style="padding:0;">
<li class="col-xs-6" style="padding:3px 15px 3px 0;">
<a href="javascript:;" data-id="{$rele['id']}" data-title="{$releTitle|htmlentities}">
{$releTitle}
</a>

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/release.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/admin/release.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
@ -31,6 +32,22 @@
</div>
</div>
</div>
<div class="rele-module" id="rele_module_dataset" module="dataset" style="display:none;">
<div class="form-group">
<input type="hidden" name="dataset[auto_create]" class="form-control" value="" />
<div class="dropdown">
<button class="btn btn-default btn-block dropdown-toggle" type="button" id="btn_dataset" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
设置数据集 <span class="caret"></span>
</button>
<ul class="dropdown-menu" style="width:100%;text-align:center;" aria-labelledby="btn_dataset">
<li><a href="javascript:" id="btn_dataset_list">选择数据集</a></li>
<li><a href="javascript:" id="btn_dataset_create">自动创建数据集</a></li>
</ul>
</div>
</div>
<div id="dataset_config" style="display:none;">
</div>
</div>
<div class="rele-module" id="rele_module_cms" module="cms" style="display:none;">
<ul id="cms_tab" class="nav nav-tabs">
<li class="active"><a href="#cms_tab_detect" data-toggle="tab">检测CMS程序</a></li>

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/task.css?{$Think.config.html_v}">
<script src="__PUBLIC__/static/js/admin/tasks.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
@ -18,7 +19,7 @@
<th>{$Think.lang.task_auto}</th>
<th>{$Think.lang.task_addtime}</th>
<th>{$Think.lang.task_caijitime}</th>
<th>{$Think.lang.task_collected}</th>
<th width="200">{$Think.lang.task_collected}</th>
<th>{$Think.lang.op}</th>
</tr>
</thead>

@ -1,5 +1,6 @@
{extend name="common:main" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/task.css?{$Think.config.html_v}">
<script src="__PUBLIC__/static/js/admin/tasks.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
@ -20,7 +21,7 @@
<th class="sorting{$orderClass['auto']}" data-order="auto" title="{$orderSort['auto']}" style="min-width:90px;">{$Think.lang.task_auto}</th>
<th class="sorting{$orderClass['addtime']}" data-order="addtime" title="{$orderSort['addtime']}">{$Think.lang.task_addtime}</th>
<th class="sorting{$orderClass['caijitime']}" data-order="caijitime" title="{$orderSort['caijitime']}">{$Think.lang.task_caijitime}</th>
<th>{$Think.lang.task_collected}</th>
<th width="200">{$Think.lang.task_collected}</th>
<th>{$Think.lang.op}</th>
</tr>
</thead>
@ -51,15 +52,11 @@
</ul>
</td>
<td>
{if is_array($item['_collected_info'])}
<ul class="in-line">
<li>今日<a href="{:url('collected/list?task_id='.$item['id'].'&begin='.$todayDate)}" target="_blank">{$item['_collected_info']['today']}</a></li>
<li>今日<a href="{:url('collected/list?task_id='.$item['id'].'&begin='.$todayDate)}" class="today-num" target="_blank">0</a></li>
<li class="sep">|</li>
<li>总共<a href="{:url('collected/list?task_id='.$item['id'])}" target="_blank">{$item['_collected_info']['total']}</a></li>
<li>总共<a href="{:url('collected/list?task_id='.$item['id'])}" class="total-num" target="_blank">0</a></li>
</ul>
{else/}
{/if}
</td>
<td>
<ul class="in-line">

@ -1,7 +0,0 @@
{extend name="common:main" /}
{block name="cssjs"}
{/block}
{block name="content"}
{include file="task:save_form" /}
{include file="task:stepsbar" /}
{/block}

@ -1,3 +0,0 @@
<div class="">
{include file="task:save_form" /}
</div>

@ -1,547 +0,0 @@
<form id="form_item" method="post" ajax-submit="true" enctype="multipart/form-data" action="{:url('task/save')}">
{:html_usertoken()}
<div class="box box-default">
<div class="box-body">
{if condition="$taskData"}
<input type="hidden" name="id" value="{$taskData['id']}" />
{/if}
<input type="hidden" name="task_id" value="" />
<input type="hidden" name="rule_id" value="" />
<div class="form-group">
<label>{$Think.lang.task_name}</label>
{if condition="$taskData"}
<input name="name" class="form-control" value="{$taskData['name']}">
{else/}
<div class="input-group">
<input name="name" class="form-control" value="">
<div class="input-group-btn"><button class="btn btn-default" onclick="windowModal('复制一个任务的所有设置','{:url("task/import")}');" type="button" id="btn_import_task">导入任务</button></div>
</div>
{/if}
</div>
<div class="form-group">
<label>{$Think.lang.task_tg}</label>
{$tgSelect}
</div>
<div class="form-group">
<label>{$Think.lang.task_module}</label>
<div class="input-group" style="width:100%;">
<select name="module" class="form-control">
{foreach name="Think.config.allow_coll_modules" item="cmodule"}
<option value="{$cmodule}">{:lang('task_module_'.$cmodule)}</option>
{/foreach}
</select>
<div class="input-group-btn dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="btn_import_rule" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
导入规则
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right dropdown-import-rule" aria-labelledby="btn_import_rule">
<li><a href="javascript:;" onclick="windowModal('导入规则会覆盖该任务的规则设置,且不可恢复','{:url("mystore/rule?tpl=task&type=collect")}');">已下载规则</a></li>
<li><a href="javascript:;" onclick="windowModal('导入规则会覆盖该任务的规则设置,且不可恢复','{:url("collector/list?module=pattern&tpl=task")}');">其它任务的规则</a></li>
<li role="separator" class="divider"></li>
<li style="padding-left:20px;padding-bottom:5px;"><input type="file" name="rule_file" style="margin-right:15px;" /></li>
</ul>
</div>
</div>
</div>
<div id="import_rule_file_plugins" class="form-group well" style="display:none;text-align:right;">
<label style="margin-bottom:0;">检测到文件中包含插件,可选择需要导入的插件(导入后会覆盖已有插件)</label>
<div class="plugins-info"></div>
</div>
<div class="form-group">
<label>{$Think.lang.task_auto}</label>
<select name="auto" class="form-control">
<option value="0">关闭</option>
<option value="1">循环采集(采集完后间隔一段时间再次运行)</option>
<option value="2">定时采集(指定时间运行采集)</option>
</select>
{if is_empty(g_sc_c('caiji','auto'))}
<p class="help-block" id="config_task_auto_tips" style="display:none;">需要全局<a href="{:url('setting/caiji')}" target="_blank">开启自动采集</a>该功能才会生效</p>
{/if}
</div>
<div class="form-group" id="config_task_timer" style="display:none;">
<input type="hidden" name="task_timer[month]" value="" />
<input type="hidden" name="task_timer[day]" value="" />
<input type="hidden" name="task_timer[hour]" value="" />
<input type="hidden" name="task_timer[minute]" value="" />
<div style="padding:0 15px 0 15px;">
<div class="row">
<div class="col-sm-3 col-xs-6" style="padding:0;">
<div class="input-group">
<span class="input-group-addon" style="background:#f4f4f4;">月份</span>
<select id="task_timer_month" data-name="task_timer[month]" class="form-control" multiple="multiple" size="4">
<option value="">全部</option>
<option value="1">一月</option>
<option value="2">二月</option>
<option value="3">三月</option>
<option value="4">四月</option>
<option value="5">五月</option>
<option value="6">六月</option>
<option value="7">七月</option>
<option value="8">八月</option>
<option value="9">九月</option>
<option value="10">十月</option>
<option value="11">十一月</option>
<option value="12">十二月</option>
</select>
</div>
</div>
<div class="col-sm-3 col-xs-6" style="padding:0;">
<div class="input-group">
<span class="input-group-addon" style="background:#f4f4f4;">日期</span>
<select id="task_timer_day" data-name="task_timer[day]" class="form-control" multiple="multiple" size="4">
<option value="">全部</option>
{for start="1" end="32"}
<option value="{$i}">{$i} </option>
{/for}
<option value="w1">周一</option>
<option value="w2">周二</option>
<option value="w3">周三</option>
<option value="w4">周四</option>
<option value="w5">周五</option>
<option value="w6">周六</option>
<option value="w7">周日</option>
</select>
</div>
</div>
<div class="col-sm-3 col-xs-6" style="padding:0;">
<div class="input-group">
<span class="input-group-addon" style="background:#f4f4f4;">小时</span>
<select id="task_timer_hour" data-name="task_timer[hour]" class="form-control" multiple="multiple" size="4">
<option value="">全部</option>
{for start="0" end="24"}
<option value="{:sprintf('%02d',$i)}">{:sprintf('%02d',$i)} </option>
{/for}
</select>
</div>
</div>
<div class="col-sm-3 col-xs-6" style="padding:0;">
<div class="input-group">
<span class="input-group-addon" style="background:#f4f4f4;">分钟</span>
<select id="task_timer_minute" data-name="task_timer[minute]" class="form-control" multiple="multiple" size="4">
<option value="">全部</option>
{for start="0" end="60"}
<option value="{:sprintf('%02d',$i)}">{:sprintf('%02d',$i)} </option>
{/for}
</select>
</div>
</div>
</div>
</div>
<p class="help-block" style="word-wrap:break-word;"><b>多选:</b>Windows按住Ctrl按钮来选择多个选项Mac按住command按钮来选择多个选项 {$timerInfo}</p>
</div>
<div class="form-group" style="margin-bottom:0;">
<label>{$Think.lang.task_sort}</label>
<input type="number" class="form-control" name="sort" autocomplete="off" value="{$taskData?intval($taskData['sort']):0}" />
<p class="help-block">{$Think.lang.task_sort_help}</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#task_config" aria-expanded="false">更多设置</a>
</h4>
</div>
<div id="task_config" class="panel-collapse collapse">
<div class="panel-body">
<p class="help-block">以下选项受<a href="{:url('setting/caiji')}" target="_blank">采集设置</a>影响</p>
<div class="form-group">
<label>{$Think.lang.set_caiji_num}</label>
<input type="number" name="config[num]" class="form-control" placeholder="全局设置:{$gConfig['num']}" />
<p class="help-block">该任务每次采集的数据量,不能超过采集设置中的“{$Think.lang.set_caiji_num}”,留空使用全局设置
{if $numGtG}<br/>注意:当前数量超过全局设置的数量,实际最大采集数量为:{$gConfig['num']}{/if}
</p>
</div>
<div class="form-group">
<label>{$Think.lang.set_caiji_interval}(分钟)</label>
<input type="number" name="config[num_interval]" class="form-control" placeholder="全局设置:{$gConfig['num_interval']}" />
<p class="help-block">留空使用全局设置</p>
</div>
<div class="form-group">
<label>页面抓取间隔毫秒1000毫秒=1秒)</label>
<input type="number" name="config[num_interval_html]" class="form-control" placeholder="全局设置:{$gConfig['num_interval_html']}" />
<p class="help-block">留空使用全局设置</p>
</div>
<div class="form-group">
<label>不同任务采集同一网址</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[same_url]" value="" checked="checked">
全局设置:{$gConfig['same_url']}
</label>
<label class="radio-inline"><input type="radio" name="config[same_url]" value="y">允许</label>
<label class="radio-inline"><input type="radio" name="config[same_url]" value="n">过滤</label>
</div>
</div>
<div class="form-group">
<label>不同任务采集同一标题</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[same_title]" value="" checked="checked">
全局设置:{$gConfig['same_title']}
</label>
<label class="radio-inline"><input type="radio" name="config[same_title]" value="y">允许</label>
<label class="radio-inline"><input type="radio" name="config[same_title]" value="n">过滤</label>
</div>
</div>
<div class="form-group">
<label>不同任务采集相同内容</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[same_content]" value="" checked="checked">
全局设置:{$gConfig['same_content']}
</label>
<label class="radio-inline"><input type="radio" name="config[same_content]" value="y">允许</label>
<label class="radio-inline"><input type="radio" name="config[same_content]" value="n">过滤</label>
</div>
</div>
<div class="form-group">
<label>实时发布数据</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[real_time]" value="" checked="checked">
全局设置:{$gConfig['real_time']}
</label>
<label class="radio-inline"><input type="radio" name="config[real_time]" value="y"></label>
<label class="radio-inline"><input type="radio" name="config[real_time]" value="n"></label>
</div>
</div>
<div class="form-group">
<label>使用翻译</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[translate]" value="" checked="checked">
全局设置:{$gConfig['translate']?'是':'否'}
</label>
<label class="radio-inline"><input type="radio" name="config[translate]" value="y"></label>
<label class="radio-inline"><input type="radio" name="config[translate]" value="n"></label>
</div>
</div>
</div>
<div class="panel-body{$gConfig['proxy']?'':' box-not-enable'}" id="config_proxy" style="border-top:solid 1px #ddd;">
<div class="form-group" style="margin-bottom:0;">
<label>使用代理</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[proxy]" value="" data-global="{$gConfig['proxy']}" checked="checked">
全局设置:{$gConfig['proxy']?'是':'否'}
</label>
<label class="radio-inline"><input type="radio" name="config[proxy]" value="y"></label>
<label class="radio-inline"><input type="radio" name="config[proxy]" value="n"></label>
</div>
</div>
<div class="box-enable-wrapper">
<div class="form-group">
<label>使用分组IP</label>
<select name="config[proxy_group_id]" class="form-control">
<option value="">全局设置:{$gConfig['proxy_group_id']}</option>
<option value="0">全部</option>
{foreach $proxyGroups as $proxyGroup}
<option value="{$proxyGroup['id']}">{$proxyGroup['name']}</option>
{/foreach}
</select>
</div>
</div>
</div>
<div class="panel-body{$gConfig['download_img']?'':' box-not-enable'}" id="config_download_img" style="border-top:solid 1px #ddd;">
<div class="form-group" style="margin-bottom:0;">
<label>图片本地化</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[download_img]" value="" data-global="{$gConfig['download_img']}" checked="checked">
全局设置:{$gConfig['download_img']?'是':'否'}
</label>
<label class="radio-inline"><input type="radio" name="config[download_img]" value="y"></label>
<label class="radio-inline"><input type="radio" name="config[download_img]" value="n"></label>
</div>
</div>
<div class="box-enable-wrapper">
<div class="form-group">
<label>图片下载间隔毫秒1000毫秒=1秒)</label>
<input type="number" name="config[num_interval_img]" class="form-control" placeholder="全局设置:{$gConfig['num_interval_img']}" />
<p class="help-block">留空使用全局设置</p>
</div>
<div class="form-group">
<label>图片保存目录(绝对路径)</label>
<input type="text" name="config[img_path]" class="form-control" placeholder="全局设置:{$gConfig['img_path']}">
</div>
<div class="form-group">
<label>图片链接地址(绝对地址)</label>
<input type="text" name="config[img_url]" class="form-control" placeholder="全局设置:{$gConfig['img_url']}">
</div>
<div class="form-group">
<label>图片名称</label>
<select name="config[img_name]" class="form-control">
<option value="">全局设置:{:lang('down_file_name_'.$gConfig['img_name'])}</option>
<option value="url">{$Think.lang.down_file_name_url}</option>
<option value="time">{$Think.lang.down_file_name_time}</option>
<option value="custom">{$Think.lang.down_file_name_custom}</option>
</select>
<div id="config_img_name_custom" style="display:none;">
<p class="help-block" style="margin-bottom:5px;font-size:12px;">注意字段值的长度限制100字内超出自动截取字段值中任何特殊字符都会被替换成下划线自定义路径或名称太长都可能导致图片保存失败</p>
<div style="width:100%;">
<div style="width:50%;float:left">
<div class="input-group">
<input type="text" name="config[name_custom_path]" class="form-control" placeholder="路径,全局设置:{$gConfig['name_custom_path']}" autocomplete="off" />
<div class="input-group-addon" style="border-left:0;border-right:0;font-weight:bold;">/</div>
</div>
<div class="help-block name-custom-path">
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
系统
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<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>
<li><a href="javascript:;" data-val="[前两位]" title="图片网址MD5码的前两位">[前两位]</a></li>
<li><a href="javascript:;" data-val="[后两位]" title="图片网址MD5码的后两位">[后两位]</a></li>
<li><a href="javascript:;" data-val="[任务名]">[任务名]</a></li>
<li><a href="javascript:;" data-val="[任务ID]">[任务ID]</a></li>
</ul>
</div>&nbsp;
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
采集器字段
<span class="caret"></span>
</a>
<ul class="dropdown-menu name-custom-path-fields">
<li><a href="javascript:;">没有字段,请先配置采集器设置!</a></li>
</ul>
</div>&nbsp;
/分隔子目录
</div>
</div>
<div style="width:50%;float:left">
<input type="text" name="config[name_custom_name]" class="form-control" placeholder="名称,全局设置:{$gConfig['name_custom_name']}" autocomplete="off" />
<div class="help-block name-custom-name">
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
系统
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="javascript:;" data-val="[图片网址MD5码]">[图片网址MD5码]</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>
<li><a href="javascript:;" data-val="[分]">[]</a></li>
<li><a href="javascript:;" data-val="[秒]">[]</a></li>
<li><a href="javascript:;" data-val="[前两位]" title="图片网址MD5码的前两位">[前两位]</a></li>
<li><a href="javascript:;" data-val="[后两位]" title="图片网址MD5码的后两位">[后两位]</a></li>
<li><a href="javascript:;" data-val="[任务名]">[任务名]</a></li>
<li><a href="javascript:;" data-val="[任务ID]">[任务ID]</a></li>
</ul>
</div>&nbsp;
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
采集器字段
<span class="caret"></span>
</a>
<ul class="dropdown-menu name-custom-name-fields">
<li><a href="javascript:;">没有字段,请先配置采集器设置!</a></li>
</ul>
</div>
</div>
</div>
</div>
<div style="clear:both;height:0;">&nbsp;</div>
</div>
</div>
<div class="form-group">
<label>图片加水印</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[img_watermark]" value="" data-global="{$gConfig['img_watermark']}" checked="checked">
全局设置:{$gConfig['img_watermark']?'是':'否'}
</label>
<label class="radio-inline"><input type="radio" name="config[img_watermark]" value="y"></label>
<label class="radio-inline"><input type="radio" name="config[img_watermark]" value="n"></label>
</div>
</div>
<div class="form-group" id="config_img_watermark" style="{$gConfig['img_watermark']?'':'display:none;'}">
<div class="form-group">
<label>水印logo</label>
<div class="input-group">
<span class="input-group-addon">logo</span>
<input type="file" name="img_wm_logo_upload" class="form-control" />
<span class="input-group-addon brl_0 brr_0">下边距</span>
<input type="number" name="config[img_wm_bottom]" class="form-control" placeholder="全局设置:{$gConfig['img_wm_bottom']}" />
<span class="input-group-addon brl_0 brr_0">右边距</span>
<input type="number" name="config[img_wm_right]" class="form-control" placeholder="全局设置:{$gConfig['img_wm_right']}" />
<span class="input-group-addon brl_0 brr_0">透明度</span>
<input type="number" name="config[img_wm_opacity]" class="form-control" placeholder="全局设置:{$gConfig['img_wm_opacity']}" />
</div>
<p class="help-block">留空使用全局设置</p>
<input type="hidden" name="config[img_wm_logo]" class="form-control" />
<div id="img_wm_logo_show" data-global="{$gConfig['img_wm_logo']}" style="display:none;">
<p class="help-block">默认使用全局设置logo</p>
<div>
<img src="" style="max-width:300px;border:solid 1px #ccc;" />
<a href="javascript:;" class="glyphicon glyphicon-remove" style="display:none;font-size:20px;margin:10px;"></a>
</div>
</div>
</div>
</div>
<div class="form-group">
<label>使用函数</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[img_funcs_open]" value="" checked="checked">
全局设置:{$gConfig['img_funcs']?('存在'.count($gConfig['img_funcs']).'个函数'):'无函数'}
</label>
<label class="radio-inline"><input type="radio" name="config[img_funcs_open]" value="y">自定义</label>
<label class="radio-inline"><input type="radio" name="config[img_funcs_open]" value="n">不使用</label>
</div>
</div>
<div class="form-group" id="config_img_funcs_open">
<label>添加函数</label>
<a href="javascript:;" class="glyphicon glyphicon-plus" id="add_config_img_func" title="添加"></a>
<div class="panel-group ui-sortable" id="config_img_funcs" style="margin-bottom:0;">
</div>
</div>
</div>
</div>
<div class="panel-body{$gConfig['download_file']?'':' box-not-enable'}" id="config_download_file" style="border-top:solid 1px #ddd;">
<div class="form-group" style="margin-bottom:0;">
<label>文件本地化</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[download_file]" value="" data-global="{$gConfig['download_file']}" checked="checked">
全局设置:{$gConfig['download_file']?'是':'否'}
</label>
<label class="radio-inline"><input type="radio" name="config[download_file]" value="y"></label>
<label class="radio-inline"><input type="radio" name="config[download_file]" value="n"></label>
</div>
</div>
<div class="box-enable-wrapper">
<div class="form-group">
<label>文件下载间隔毫秒1000毫秒=1秒)</label>
<input type="number" name="config[file_interval]" class="form-control" placeholder="全局设置:{$gConfig['file_interval']}" />
<p class="help-block">留空使用全局设置</p>
</div>
<div class="form-group">
<label>文件保存目录(绝对路径)</label>
<input type="text" name="config[file_path]" class="form-control" placeholder="全局设置:{$gConfig['file_path']}">
</div>
<div class="form-group">
<label>文件链接地址(绝对地址)</label>
<input type="text" name="config[file_url]" class="form-control" placeholder="全局设置:{$gConfig['file_url']}">
</div>
<div class="form-group">
<label>文件名称</label>
<select name="config[file_name]" class="form-control">
<option value="">全局设置:{:lang('down_file_name_'.$gConfig['file_name'])}</option>
<option value="url">{$Think.lang.down_file_name_url}</option>
<option value="time">{$Think.lang.down_file_name_time}</option>
<option value="custom">{$Think.lang.down_file_name_custom}</option>
</select>
<div id="config_file_name_custom" style="display:none;">
<p class="help-block" style="margin-bottom:5px;font-size:12px;">注意字段值的长度限制100字内超出自动截取字段值中任何特殊字符都会被替换成下划线自定义路径或名称太长都可能导致文件保存失败</p>
<div style="width:100%;">
<div style="width:50%;float:left">
<div class="input-group">
<input type="text" name="config[file_custom_path]" class="form-control" placeholder="路径,全局设置:{$gConfig['file_custom_path']}" autocomplete="off" />
<div class="input-group-addon" style="border-left:0;border-right:0;font-weight:bold;">/</div>
</div>
<div class="help-block file-custom-path">
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
系统
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<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>
<li><a href="javascript:;" data-val="[前两位]" title="文件网址MD5码的前两位">[前两位]</a></li>
<li><a href="javascript:;" data-val="[后两位]" title="文件网址MD5码的后两位">[后两位]</a></li>
<li><a href="javascript:;" data-val="[任务名]">[任务名]</a></li>
<li><a href="javascript:;" data-val="[任务ID]">[任务ID]</a></li>
</ul>
</div>&nbsp;
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
采集器字段
<span class="caret"></span>
</a>
<ul class="dropdown-menu file-custom-path-fields">
<li><a href="javascript:;">没有字段,请先配置采集器设置!</a></li>
</ul>
</div>&nbsp;
/分隔子目录
</div>
</div>
<div style="width:50%;float:left">
<input type="text" name="config[file_custom_name]" class="form-control" placeholder="名称,全局设置:{$gConfig['file_custom_name']}" autocomplete="off" />
<div class="help-block file-custom-name">
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
系统
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="javascript:;" data-val="[文件网址MD5码]">[文件网址MD5码]</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>
<li><a href="javascript:;" data-val="[分]">[]</a></li>
<li><a href="javascript:;" data-val="[秒]">[]</a></li>
<li><a href="javascript:;" data-val="[前两位]" title="文件网址MD5码的前两位">[前两位]</a></li>
<li><a href="javascript:;" data-val="[后两位]" title="文件网址MD5码的后两位">[后两位]</a></li>
<li><a href="javascript:;" data-val="[任务名]">[任务名]</a></li>
<li><a href="javascript:;" data-val="[任务ID]">[任务ID]</a></li>
</ul>
</div>&nbsp;
<div class="dropup" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
采集器字段
<span class="caret"></span>
</a>
<ul class="dropdown-menu file-custom-name-fields">
<li><a href="javascript:;">没有字段,请先配置采集器设置!</a></li>
</ul>
</div>
</div>
</div>
</div>
<div style="clear:both;height:0;">&nbsp;</div>
</div>
</div>
<div class="form-group">
<label>使用函数</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[file_funcs_open]" value="" checked="checked">
全局设置:{$gConfig['file_funcs']?('存在'.count($gConfig['file_funcs']).'个函数'):'无函数'}
</label>
<label class="radio-inline"><input type="radio" name="config[file_funcs_open]" value="y">自定义</label>
<label class="radio-inline"><input type="radio" name="config[file_funcs_open]" value="n">不使用</label>
</div>
</div>
<div class="form-group" id="config_file_funcs_open">
<label>添加函数</label>
<a href="javascript:;" class="glyphicon glyphicon-plus" id="add_config_file_func" title="添加"></a>
<div class="panel-group ui-sortable" id="config_file_funcs" style="margin-bottom:0;">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
{include file="setting:download_img_func" func_tpl_id="config_img_tpl_func" func_list_id="config_img_funcs" /}
{include file="setting:download_file_func" func_tpl_id="config_file_tpl_func" func_list_id="config_file_funcs" /}
{php}$nTaskData=is_array($taskData)?json_encode($taskData):'null';$nFieldList=is_array($fieldList)?json_encode($fieldList):'null';{/php}
<script src="__PUBLIC__/static/js/admin/task.js?{$Think.config.html_v}"></script>
<script type="text/javascript">
taskOpClass.task_load({$nTaskData},{$nFieldList});
</script>

@ -163,7 +163,7 @@
<label class="radio-inline"><input type="radio" name="config[single][open]" value="0" checked="checked"></label>
</div>
<p class="help-block">
允许通过访问接口方式传入网址参数采集单个页面<br>该模式仅在web中运行会受web服务器运行时长影响如遇采集中断需修改web服务器的超时时间
允许通过访问接口方式传入网址参数采集发布单个页面<br>该模式仅在web中运行会受web服务器运行时长影响如遇采集中断需修改web服务器的超时时间
</p>
</div>
<div class="form-group">

@ -10,7 +10,6 @@
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th class="chk">{$Think.lang.select}</th>
<th>{$Think.lang.sort}</th>
<th>{$Think.lang.taskgroup_name}</th>
<th>{$Think.lang.op}</th>
@ -21,7 +20,6 @@
{php}$num++;$itemList=is_array($subList[$pitem['id']])?array_merge(array($pitem),$subList[$pitem['id']]):array($pitem);{/php}
{foreach name="itemList" item="item"}
<tr class="bg{$num%2}">
<td class="chk"><input type="checkbox" name="ids[]" value="{$item['id']}" /></td>
<td class="sort"><input type="text" name="newsort[{$item['id']}]" class="form-control" value="{$item['sort']}" autocomplete="off" /></td>
<td{$item['parent_id']?' class="sub"':''}>{$item['name']}</td>
<td>
@ -37,13 +35,10 @@
</tbody>
<tfoot>
<tr>
<td class="chk"><label class="chk-all"><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" /><span>全部</span></label></td>
<td colspan="2">
<button type="submit" class="btn btn-primary">{$Think.lang.save}</button>
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
<button type="button" class="btn btn btn-success" onclick="windowModal('{$Think.lang.tg_add_sub}','{:url('taskgroup/add')}')">{$Think.lang.taskgroup_add}</button>
<td colspan="3">
<button type="submit" class="btn btn-default">{$Think.lang.save}</button>
<button type="button" class="btn btn btn-primary" onclick="windowModal('{$Think.lang.taskgroup_add}','{:url('taskgroup/add')}')">{$Think.lang.taskgroup_add}</button>
</td>
<td></td>
</tr>
</tfoot>
</table>
@ -89,7 +84,7 @@ $(document).ready(function(){
success: function(data){
data.code==1?toastr.success(data.msg):toastr.error(data.msg);
if(data.code==1){
obj.parent().parent().remove();
obj.parents('tr').eq(0).remove();
}
}
});
@ -115,28 +110,6 @@ $(document).ready(function(){
dropdown.find('.dropdown-menu').remove();
dropdown.append(options);
});
//sort改变值后选中
$('input[name^="newsort"]').bind('change',function(){
$(this).parent().parent().find('input[name="ids[]"]').prop('checked',true);
});
//删除选中
$('#deleteall').bind('click',function(){
var obj=$(this);
confirmRight('{$Think.lang.confirm_delete}',function(){
ajaxOpen({
type: "POST",
url: "{:url('taskgroup/op')}",
dataType: "json",
data:$('#form_list').serialize()+'&op=deleteall',
success: function(data){
data.code==1?toastr.success(data.msg):toastr.error(data.msg);
setTimeout("window.location.reload();",2500);
}
});
});
});
});
</script>
{/block}

@ -32,7 +32,7 @@
<tfoot>
<tr>
<td colspan="5">
<a href="{:url('user/add')}" class="btn btn-success">{$Think.lang.user_add}</a>
<a href="{:url('user/add')}" class="btn btn-primary">{$Think.lang.user_add}</a>
</td>
</tr>
{if condition="!empty($pagenav)"}

@ -0,0 +1,102 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\api\controller;
use skycaiji\common\controller\BaseController;
class Data extends BaseController {
public function indexAction(){
$params=input('param.');
$mda=model('Dataapi');
$daData=array();
if(is_numeric($params['i'])){
$daData=$mda->getById($params['i']);
}else{
$daData=$mda->where('route',$params['i'])->find();
$daData=$mda->get_da_data($daData);
}
if(empty($daData)){
$this->jsonSend('数据接口不存在');
}
$config=$daData['config'];
if(empty($config)){
$this->jsonSend('无效的数据接口');
}
if(!empty($config['api_key'])){
$iptK=$params['k']?:'';
if(empty($config['api_mode'])){
if(strcasecmp($iptK,md5($config['api_key']))!==0){
$this->jsonSend('密钥错误');
}
}else{
$iptK=explode('_', $iptK);
if(strcasecmp($iptK[0],md5(md5($config['api_key']).$iptK[1]))!==0){
$this->jsonSend('密钥错误');
}
if(abs(time()-$iptK[1])>300){
$this->jsonSend('密钥已过期');
}
}
}
if(!empty($config['api_method'])){
if(strtolower($config['api_method'])=='post'){
if(!$this->request->isPost()){
$this->jsonSend('请使用post模式请求接口');
}
}else{
if(!$this->request->isGet()){
$this->jsonSend('请使用get模式请求接口');
}
}
}
if(empty($daData['status'])){
$this->jsonSend('接口已关闭');
}
$dsData=$daData['ds_id']?model('Dataset')->getById($daData['ds_id']):array();
if(empty($dsData)){
$this->jsonSend('接口无数据');
}
if(empty($config['conds'])){
$this->jsonSend('接口没有数据查询条件');
}
$pageNo=intval($params[$config['page_name']?:'p']);
$pageNo=$pageNo<=1?1:$pageNo;
$config['page_max']=intval($config['page_max']);
if($config['page_max']>0&&$pageNo>$config['page_max']){
$this->jsonSend('已超出最大分页数');
}
$error='';
try{
$queryData=$mda->do_query_conds($pageNo,$config,$dsData,$params);
}catch (\Exception $ex){
$error=$ex->getMessage();
}
if($error){
$this->jsonSend($error);
}
if($queryData['count']<=0){
$this->jsonSend('没有查询到数据');
}
$options=array();
if($queryData['pages']>1){
$options['page']=$pageNo;
$options['pages']=$queryData['pages'];
}
$this->jsonSend('',$queryData['data'],1,$options);
}
}

@ -10,7 +10,7 @@
*/
define('SKYCAIJI_VERSION', '2.6.2');
define('SKYCAIJI_VERSION', '2.7');
\think\Loader::addNamespace('plugin', realpath(SKYCAIJI_PATH.'plugin'));
\think\Loader::addNamespace('util',realpath(APP_PATH.'extend/util'));
@ -178,6 +178,8 @@ function paginate_auto_config($path='',$queryParamsOrAuto=true){
$params=is_array($queryParamsOrAuto)?$queryParamsOrAuto:array();
}
init_array($params);
unset($params['_usertoken_']);
$params[config('paginate.var_page')]='-_-PAGE-_-';
$params=http_build_query($params);

@ -23,6 +23,18 @@ class BaseController extends Controller {
exit();
}
public function jsonSend($msg='',$data=array(),$code=0,$options=null){
$json=array(
'code' => $code,
'msg' => $msg,
'data' => is_array($data)?$data:array()
);
if(is_array($options)){
$json=array_merge($json,$options);
}
json($json)->send();
exit();
}
/**
* tp3.2默认跳转操作 支持错误导向和正确跳转
* @param Boolean $success 状态

@ -0,0 +1,309 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\common\model;
class Dataapi extends BaseModel{
private static $cond_keys=array('sub','logic','field','op','name');
private static $cond_ops=array(
'eq'=>'=(等于)',
'neq'=>'!=(不等于)',
'gt'=>'&gt;(大于)',
'egt'=>'&gt;=(大于等于)',
'lt'=>'&lt;(小于)',
'elt'=>'&lt;=(小于等于)',
'like'=>'like包含',
'nlike'=>'not like不包含',
'in'=>'in范围值用,号分隔)',
'nin'=>'not in不在范围',
'between'=>'between区间值用,号分隔)',
'nbetween'=>'not between不在区间',
);
private static $cond_sqls=array(
'eq'=>'=',
'neq'=>'!=',
'gt'=>'>',
'egt'=>'>=',
'lt'=>'<',
'elt'=>'<=',
'like'=>'like',
'nlike'=>'not like',
'in'=>'in',
'nin'=>'not in',
'between'=>'between',
'nbetween'=>'not between',
);
public function getById($id){
$daData=$this->where('id',$id)->find();
$daData=$this->get_da_data($daData);
return $daData;
}
public function get_da_data($daData){
$daData=$daData?$daData->toArray():array();
if($daData){
$daData['config']=unserialize($daData['config']);
init_array($daData['config']);
}
return $daData;
}
public function get_cond_op($op){
return $op?self::$cond_ops[$op]:self::$cond_ops;
}
public function get_cond_sql($op){
return self::$cond_sqls[$op]?:'';
}
public function check_url_param_name($name){
$result=return_result('');
if(!preg_match('/^\w+$/i',$name)){
$result['msg']='参数名只能由字母、数字和下划线组成!';
}elseif(!preg_match('/^[a-z]/i',$name)){
$result['msg']='参数名必须是字母开头!';
}elseif(strlen($name)<=1){
$result['msg']='参数名最少2个字符';
}else{
$result['success']=true;
}
return $result;
}
public function filter_conds($conds){
init_array($conds);
foreach (self::$cond_keys as $key){
init_array($conds[$key]);
}
foreach (array('logic','field','op') as $k){
foreach ($conds[$k] as $kk=>$kv){
if(empty($kv)){
foreach (self::$cond_keys as $key){
unset($conds[$key][$kk]);
}
}
}
}
foreach ($conds['name'] as $k=>$v){
$conds['name'][$k]=empty($v)?'':$v;
}
foreach (self::$cond_keys as $key){
$conds[$key]=array_values($conds[$key]);
}
return $conds;
}
public function get_group_conds($conds){
$conds=$this->filter_conds($conds);
$condSubs=array();
$condIx=-1;
foreach ($conds['logic'] as $k=>$v){
$cond=array();
foreach (self::$cond_keys as $key){
$cond[$key]=$conds[$key][$k];
}
if(empty($cond['name'])){
$cond['name']=$cond['field'];
}
if($cond['sub']){
init_array($condSubs[$condIx]['subs']);
$condSubs[$condIx]['subs'][]=$cond;
}else{
$condIx++;
$condSubs[$condIx]=$cond;
}
}
$condSubs=array_values($condSubs);
foreach ($condSubs as $k=>$v){
if($v['subs']){
$vv=$v;
unset($vv['subs']);
array_unshift($v['subs'],$vv);
$v['subs']=$this->_group_conds($v['subs']);
}
$condSubs[$k]=$v;
}
$condSubs=$this->_group_conds($condSubs);
return $condSubs;
}
private function _group_conds($conds){
init_array($conds);
$groups=array();
$group=array();
foreach ($conds as $cond){
if($cond['logic']!='and'){
if($group){
$groups[]=$group;
}
$group=array();
}
$group[]=$cond;
}
if($group){
$groups[]=$group;
}
return $groups;
}
public function do_query_conds($pageNo,$config,$dataset,$params){
init_array($config);
init_array($params);
$pagePer=intval($config['page_per']);
$pagePer=$pagePer>0?$pagePer:50;
$groupConds=$this->get_group_conds($config['conds']);
foreach ($groupConds as $kgc=>$group){
foreach ($group as $kg=>$cond){
if($cond['subs']){
foreach ($cond['subs'] as $kcs=>$subConds){
$subConds=$this->_conds_query($subConds,$params);
if(empty($subConds)){
unset($cond['subs'][$kcs]);
}else{
$cond['subs'][$kcs]=$subConds;
}
}
$cond=$cond['subs'];
}else{
if(isset($params[$cond['name']])){
$cond=$this->_cond_query($cond,$params);
$cond['is_cond']=true;
}else{
$cond=null;
}
}
if(empty($cond)){
$group=null;
break;
}else{
$group[$kg]=$cond;
}
}
if(empty($group)){
unset($groupConds[$kgc]);
}else{
$groupConds[$kgc]=$group;
}
}
$dataCount=0;
$dataData=array();
if(empty($groupConds)){
throw new \Exception('没有符合的查询条件');
}else{
$dstDb=DatasetTable::getInstance($dataset['id']);
$dstDb=$dstDb->db();
$this->_conds_db($dstDb,$groupConds);
$dataCount=$dstDb->count();
if($dataCount>0){
$this->_conds_db($dstDb,$groupConds);
init_array($config['hide_fields']);
if($config['hide_fields']){
$dstDb->field($config['hide_fields'],true);
}
if($config['order_field']){
$dstDb->order($config['order_field'],$config['order_sort']=='desc'?'desc':'asc');
}
$dataData=$dstDb->limit(($pageNo-1)*$pagePer,$pagePer)->select();
if($dataData){
$fields=$dataset['config']?$dataset['config']['fields']:null;
init_array($fields);
foreach ($fields as $k=>$v){
if($k==$v['name']){
unset($fields[$k]);
}else{
$fields[$k]=$v['name'];
}
}
foreach ($dataData as $k=>$v){
foreach ($v as $vk=>$vv){
if(isset($fields[$vk])){
$v[$fields[$vk]]=$vv;
unset($v[$vk]);
}
}
$dataData[$k]=$v;
}
}
}
}
return array('count'=>$dataCount,'data'=>$dataData,'pages'=>ceil($dataCount/$pagePer));
}
private function _conds_db($dstDb,$groupConds){
foreach ($groupConds as $group){
init_array($group);
if($group){
$dstDb->whereOr(function($queryG)use($group){
foreach ($group as $cond){
init_array($cond);
if($cond){
$queryG->where(function($queryC)use($cond){
if($cond['is_cond']){
$queryC->where($cond[0],$cond[1],$cond[2]);
}else{
foreach ($cond as $condSubs){
init_array($condSubs);
if($condSubs){
$queryC->whereOr(function($queryCs)use($condSubs){
foreach ($condSubs as $condSub){
$queryCs->where($condSub[0],$condSub[1],$condSub[2]);
}
});
}
}
}
});
}
}
});
}
}
}
private function _conds_query($conds,$params){
init_array($conds);
foreach ($conds as $k=>$cond){
if(isset($params[$cond['name']])){
$conds[$k]=$this->_cond_query($cond,$params);
}else{
$conds=null;
break;
}
}
return $conds;
}
private function _cond_query($cond,$params){
return array($cond['field'],$this->get_cond_sql($cond['op']),$params[$cond['name']]);
}
}
?>

@ -0,0 +1,97 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\common\model;
class Dataset extends BaseModel{
public function getById($id){
$data=$this->where('id',$id)->find();
$data=$this->get_ds_data($data);
return $data;
}
public function get_ds_data($dsData){
$dsData=$dsData?$dsData->toArray():array();
if($dsData){
$dsData['config']=unserialize($dsData['config']);
init_array($dsData['config']);
}
return $dsData;
}
public function get_config_field($dsData,$fname){
$field=array();
if($dsData['config']&&$dsData['config']['fields']){
$field=$dsData['config']['fields'][$fname];
}
init_array($field);
return $field;
}
public function check_field_name($name){
$result=return_result('');
if(empty($name)){
$result['msg']='字段名称不能为空!';
}elseif(strcasecmp($name,'id')===0){
$result['msg']='字段名称不能设为id';
}elseif(!preg_match('/^[\x{4e00}-\x{9fa5}\w\-]+$/u', $name)){
$result['msg']='字段名称只能由汉字、字母、数字和下划线组成';
}elseif(strlen($name)<=1){
$result['msg']='字段名称最少2个字符';
}else{
$result['success']=true;
}
return $result;
}
public function check_field_type($type){
$result=return_result('');
static $types=array('bigint','double','varchar','mediumtext','datetime');
if(!in_array($type, $types)){
$result['msg']='请选择数据类型';
}else{
$result['success']=true;
}
return $result;
}
public function filter_fields($fields){
init_array($fields);
$newFields=array();
foreach ($fields as $v){
init_array($v);
$check=$this->check_field_name($v['name']);
if($check['success']){
$check=$this->check_field_type($v['type']);
if($check['success']){
$key=$this->field_db_name($v['name']);
$newFields[$key]=$v;
}
}
}
return $newFields;
}
public static function field_db_name($name){
$name=strtolower($name);
if(!preg_match('/^[a-z]\w{0,30}$/i',$name)){
$md5=md5($name);
$name='';
if(preg_match('/[a-z]/i',$md5,$mfirst)){
$name=$mfirst[0];
}
$name=$name?:'a';
$name.=substr($md5,-4,4);
}
$name=strtolower($name);
return $name;
}
}
?>

@ -0,0 +1,216 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\common\model;
use think\db\Query;
/**
* 数据集表模型
* 不继承model类直接调用db防止不同表实例化的静态变量混淆
*/
class DatasetTable{
private static $instances;
public $dataset_id='';
public $table_name='dataset_t';
public function __construct($dataset_id=''){
$this->dataset_id=$dataset_id;
$this->table_name='dataset_t'.($this->dataset_id?('_'.$this->dataset_id):'');
}
/*获取实例化类*/
public static function getInstance($dataset_id=''){
if(!isset(self::$instances[$dataset_id])){
self::$instances[$dataset_id] = new static($dataset_id);
}
return self::$instances[$dataset_id];
}
/**
* 获取数据库连接
* @return \think\db\Query
*/
public function db(){
try {
$db=db($this->table_name);
$db->getPk();
}catch (\Exception $ex){
$this->create_table();
$db=db($this->table_name);
}
return $db;
}
public function convertDate($date){
$date=strtotime($date);
$date=$date>0?date('Y-m-d H:i:s',$date):'';
return $date;
}
public function dbColumns(){
$dbColumns=$this->db()->query('SHOW COLUMNS FROM '.$this->fullTableName());
$columns=array();
if(!empty($dbColumns)){
foreach ($dbColumns as $dbColumn){
$dbColumn=\util\Funcs::array_keys_to_lower($dbColumn);
$columns[strtolower($dbColumn['field'])]=$dbColumn;
}
}
return $columns;
}
public function alertTableFields($fields,$dsData){
$oldFields=array();
if(!empty($dsData)){
if(is_array($dsData['config'])&&$dsData['config']){
$oldFields=$dsData['config']['fields'];
init_array($oldFields);
}
}
foreach ($fields as $field){
$oldField=null;
if($field['name_original']){
$oldField=$oldFields[\skycaiji\common\model\Dataset::field_db_name($field['name_original'])];
}
$this->alertTableField($field,$oldField);
}
$dbColumns=$this->dbColumns();
$hasId=false;
if($dbColumns){
foreach ($dbColumns as $dbKey=>$dbColumn){
if($dbKey=='id'){
$hasId=true;
continue;
}
if(empty($fields[$dbKey])){
$sql='alter table '.$this->fullTableName().' drop column `'.$dbKey.'`';
$this->db()->execute($sql);
}
}
}
if(!$hasId){
$this->db()->execute('alter table '.$this->fullTableName().' add column id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY');
}
}
public function alertTableField($newField,$oldField){
if(empty($oldField)){
$oldField=$newField;
}
$upType=false;
if(($newField['type']!=$oldField['type'])||($newField['type']=='varchar'&&$newField['len']!=$oldField['len'])){
$upType=true;
$typeSql=$this->getTypeSql($newField['type'],$newField['len']);
}else{
$typeSql=$this->getTypeSql($oldField['type'],$oldField['len']);
}
$dbFname=\skycaiji\common\model\Dataset::field_db_name($oldField['name']);
$hasField=false;
$dbColumns=$this->dbColumns();
if($dbColumns&&!empty($dbColumns[$dbFname])){
$hasField=true;
}
$commentSql=" COMMENT '".addslashes($newField['name'])."'";
if($hasField){
try{
if($newField['name']!=$oldField['name']){
$sql='alter table '.$this->fullTableName().' change `'.$dbFname.'` `'.\skycaiji\common\model\Dataset::field_db_name($newField['name']).'` '.$typeSql.$commentSql;
$this->db()->execute($sql);
}elseif($upType){
$sql='alter table '.$this->fullTableName().' modify column `'.$dbFname.'` '.$typeSql.$commentSql;
$this->db()->execute($sql);
}
}catch(\Exception $ex){
$msg=$ex->getMessage();
if(stripos($msg,'Specified key was too long')!==false){
$msg.=sprintf(',请先删除<b>%s</b>字段的全部索引',$oldField['name']);
}
throw new \Exception($msg);
}
}else{
$sql='alter table '.$this->fullTableName().' add column `'.\skycaiji\common\model\Dataset::field_db_name($newField['name']).'` '.$typeSql.$commentSql;
$this->db()->execute($sql);
}
}
public function getTypeSql($type,$len=null){
$sql='';
switch ($type){
case 'bigint':$sql=" bigint(20) DEFAULT '0'";break;
case 'double':$sql=" double";break;
case 'varchar':$len=intval($len);$sql=" varchar(".$len.") DEFAULT ''";break;
case 'mediumtext':$sql=" mediumtext";break;
case 'datetime':$sql=" datetime";break;
}
return $sql;
}
public function fullTableName(){
return config('database.prefix').$this->table_name;
}
public function convertErrorColumn($msg,$fields){
if($msg){
$msg=preg_replace_callback('/\b(key|column)(\s*[\'\"])([^\'\"]+)/i',function($match)use($fields){
if($fields[$match[3]]){
$match[3]=$fields[$match[3]]['name'];
}
return $match[1].$match[2].$match[3];
},$msg);
}
return $msg;
}
/**
* 创建表
* @return boolean
*/
public function create_table(){
$tname=$this->fullTableName();
$exists=db()->query("show tables like '{$tname}'");
if(empty($exists)){
$dataset=model('Dataset')->getById($this->dataset_id);
if(empty($dataset)){
throw new \Exception('无效的数据集');
}
$fields=model('Dataset')->filter_fields($dataset['config']['fields']);
$table="CREATE TABLE `{$tname}`( `id` int(11) NOT NULL AUTO_INCREMENT,";
foreach ($fields as $dbName=>$field){
$typeSql=$this->getTypeSql($field['type'],$field['len']);
if($typeSql){
$table.=$dbName.$typeSql." COMMENT '".addslashes($field['name'])."'";
}
$table.=',';
}
$table.='PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4';
db()->execute($table);
}
}
public function drop_table(){
$tname=$this->fullTableName();
db()->execute("drop table `{$tname}`");
}
}
?>

@ -247,7 +247,7 @@ return [
'root_website'=>(Request::instance()->isSsl()?'https':'http').'://'.trim(Request::instance()->host()?:'','\/\\').rtrim(preg_replace('/\/index\.php.*/i','',Request::instance()->root()?:''),'\/\\'),//带域名网站根目录去掉index.php结尾不带/
'allow_coll_modules'=>array('pattern'),//允许的采集器模块
'release_modules'=>array('cms','db','file','toapi','api','diy'),//发布模块
'release_modules'=>array('dataset','file','db','toapi','api','cms','diy'),//发布模块
'yzm_expire'=>1200, //邮箱验证码过期时间(秒)
'allow_origins'=>array('http://www.skycaiji.com','https://www.skycaiji.com'),//默认允许的官方平台网址

@ -16,8 +16,8 @@ return [
'dsn' => '',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库编码默认采用utf8mb4
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => 'skycaiji_',
// 数据库调试模式

@ -118,7 +118,11 @@ class ChromeSocket{
$return['error']='页面渲染需开启proc_open或在服务器中执行命令'.$command;
}else{
try{
$return['info']=\util\Tools::proc_open_exec_curl($command,$isTest?'all':true,10,$isTest?true:false);
}catch (\Exception $ex){
$return['error']=$ex->getMessage();
}
}
}
return $return;

@ -163,6 +163,13 @@ class Funcs{
return $val;
}
public static function array_keys_to_lower($arr){
if($arr&&is_array($arr)){
$arr=array_change_key_case($arr,CASE_LOWER);
}
return $arr;
}
public static function convert_html2json($html,$returnStr=false){
static $jsonpRegExp='/^(\s*[\$\w\-]+\s*[\{\(])+(?P<json>[\s\S]+)(?P<end>[\}\]])\s*\)\s*[\;]{0,1}/i';

@ -1,49 +0,0 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
/*日志驱动*/
namespace util;
use think\log\driver\File;
class Log extends File{
public function save(array $log = [], $append = false){
static $passList=array(
'未定义','Undefined',
'A session had already been started','DOMDocument::loadHTML',
'MySQL server has gone away',"Error reading result set's header",
'The /e modifier is deprecated',
'Invalid argument supplied for foreach',
'CURLOPT_FOLLOWLOCATION',
'open_basedir restriction in effect',
']unlink(',']rmdir('
);
foreach ($log as $type => $val) {
foreach ($val as $key=>$msg) {
if (!is_string($msg)) {
$msg = var_export($msg, true);
}
foreach ($passList as $passStr){
if(stripos($msg, $passStr)!==false){
unset($val[$key]);
break;
}
}
}
$log[$type]=$val;
}
parent::save($log,$append);
}
}
?>

@ -43,6 +43,7 @@ class Tools{
if(file_exists(config('root_path').'/data/config.php')){
$dataConfig=include config('root_path').'/data/config.php';
if($dataConfig&&is_array($dataConfig)){
$dbConfig=array();
foreach ($dataConfig as $k=>$v){
@ -73,6 +74,7 @@ class Tools{
}
}
}
}
public static function check_verify($verifycode){
if(empty($verifycode)){
@ -263,7 +265,13 @@ class Tools{
}else{
init_array($curlParams);
return self::proc_open_exec_curl($commandStr,$curlParams['showInfo'],$curlParams['timeout'],$curlParams['closeProc'],$curlParams['killProc']);
$return=null;
try{
$return=self::proc_open_exec_curl($commandStr,$curlParams['showInfo'],$curlParams['timeout'],$curlParams['closeProc'],$curlParams['killProc']);
}catch(\Exception $ex){
$return=array('error'=>$ex->getMessage());
}
return $return;
}
}
@ -280,11 +288,28 @@ class Tools{
}
$params=array($commandStr,$showInfo,$timeout,$closeProc,$killProc);
cache('proc_open_exec_params',$params);
$json=get_html(url('admin/index/proc_open_exec?key='.\util\Param::set_url_cache_key('proc_open_exec'),null,false,true),null,array('timeout'=>3));
$data=get_html(url('admin/index/proc_open_exec?key='.\util\Param::set_url_cache_key('proc_open_exec'),null,false,true),null,array('timeout'=>3),'auto',null,true);
$json=$data?$data['html']:null;
if($json){
$json=json_decode($json,true);
}
$error='';
init_array($json);
if(empty($json)){
if($data['ok']){
if(empty($data['html'])||preg_match('/^(\[|\{)/',$data['html'])){
$error='执行失败请检查web服务器是否拥有执行命令的权限';
}else{
$error=strip_tags($data['html']);
}
}else{
$error=strip_tags($data['header']);
}
}
if($error){
throw new \Exception($error);
}
return $json;
}
@ -761,7 +786,7 @@ class Tools{
);
if(!$returnArray){
$data=vsprintf($data[0],htmlspecialchars($data[1],ENT_QUOTES));
$data=sprintf($data[0],htmlspecialchars($data[1],ENT_QUOTES));
}
}
}

@ -165,7 +165,7 @@ class Index extends BaseController{
unset($dbConfig['db_name']);
Config::set('database',$this->_get_db_config($dbConfig));
$dbConn=Db::connect();
$dbConn->execute('create database if not exists '.$dbName.' default character set utf8');
$dbConn->execute('create database if not exists '.$dbName.' default character set utf8mb4');
$dbConn->execute('use '.$dbName);
foreach($sqlList as $sql){

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -8,6 +8,6 @@ return array(
'DB_PORT' => '{$DB_PORT}', // 端口
'DB_PREFIX' => '{$DB_PREFIX}', // 数据库表前缀
'DB_DSN' => '', // 数据库连接DSN 用于PDO方式
'DB_CHARSET' => 'utf8', // 数据库的编码 默认为utf8
'DB_CHARSET' => 'utf8mb4', // 数据库的编码 默认为utf8mb4
);
?>

@ -12,7 +12,7 @@ CREATE TABLE `skycaiji_app` (
`uptime` int(11) NOT NULL DEFAULT '0',
`config` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_collected` */
@ -34,7 +34,7 @@ CREATE TABLE `skycaiji_collected` (
KEY `ix_taskid` (`task_id`),
KEY `ix_addtime` (`addtime`),
KEY `ix_titlemd5` (`titleMd5`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_collector` */
@ -49,7 +49,7 @@ CREATE TABLE `skycaiji_collector` (
`uptime` int(11) NOT NULL DEFAULT '0',
`config` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_config` */
@ -62,7 +62,7 @@ CREATE TABLE `skycaiji_config` (
`data` mediumblob NOT NULL,
PRIMARY KEY (`cname`),
KEY `dateline` (`dateline`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Data for the table `skycaiji_config` */
@ -86,7 +86,7 @@ CREATE TABLE `skycaiji_func_app` (
UNIQUE KEY `ix_app` (`app`),
UNIQUE KEY `module_app` (`module`,`app`),
KEY `module_enable` (`module`,`enable`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_provider` */
@ -101,8 +101,8 @@ CREATE TABLE `skycaiji_provider` (
`enable` tinyint(4) NOT NULL DEFAULT '0',
`sort` mediumint(9) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
KEY `domain` (`domain`(250))
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_proxy_group` */
@ -114,7 +114,7 @@ CREATE TABLE `skycaiji_proxy_group` (
`parent_id` int(11) NOT NULL DEFAULT '0',
`sort` mediumint(9) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_proxy_ip` */
@ -138,7 +138,7 @@ CREATE TABLE `skycaiji_proxy_ip` (
KEY `num_no` (`num`,`no`),
KEY `time_no` (`time`,`no`),
KEY `gid_no` (`group_id`,`no`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_release` */
@ -152,7 +152,7 @@ CREATE TABLE `skycaiji_release` (
`addtime` int(11) NOT NULL DEFAULT '0',
`config` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_release_app` */
@ -170,7 +170,7 @@ CREATE TABLE `skycaiji_release_app` (
PRIMARY KEY (`id`),
UNIQUE KEY `module_app` (`module`,`app`),
UNIQUE KEY `ix_app` (`app`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_rule` */
@ -188,7 +188,7 @@ CREATE TABLE `skycaiji_rule` (
`config` mediumtext,
PRIMARY KEY (`id`),
KEY `store_id` (`store_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_task` */
@ -205,7 +205,7 @@ CREATE TABLE `skycaiji_task` (
`caijitime` int(11) NOT NULL DEFAULT '0',
`config` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_task_timer` */
@ -217,7 +217,7 @@ CREATE TABLE `skycaiji_task_timer` (
`data` varchar(10) NOT NULL DEFAULT '',
KEY `ix_tid` (`task_id`),
KEY `ix_name` (`name`,`data`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_taskgroup` */
@ -229,7 +229,7 @@ CREATE TABLE `skycaiji_taskgroup` (
`parent_id` int(11) NOT NULL DEFAULT '0',
`sort` mediumint(9) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_user` */
@ -244,9 +244,9 @@ CREATE TABLE `skycaiji_user` (
`email` varchar(255) NOT NULL DEFAULT '',
`regtime` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`uid`),
UNIQUE KEY `username` (`username`),
KEY `email` (`email`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
UNIQUE KEY `username` (`username`(250)),
KEY `email` (`email`(250))
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
/*Table structure for table `skycaiji_usergroup` */
@ -259,7 +259,7 @@ CREATE TABLE `skycaiji_usergroup` (
`founder` tinyint(4) NOT NULL DEFAULT '0',
`admin` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
/*Data for the table `skycaiji_usergroup` */

@ -10,9 +10,9 @@
*/
namespace skycaiji\install\event;
use skycaiji\common\controller\BaseController;
use think\db\Query;
/*数据库升级操作*/
class UpgradeDb extends BaseController{
class UpgradeDb extends UpgradeDbVers{
/*后台更新时升级入口:当所有更新文件下载替换完毕,最后需要升级数据库*/
public function run(){
\util\Tools::clear_runtime_dir();
@ -42,78 +42,6 @@ class UpgradeDb extends BaseController{
}
return $programVersion;
}
/*判断存在索引*/
public function check_exists_index($name,$indexes){
if(empty($name)){
return false;
}
$exists_index=false;
foreach ($indexes as $k=>$v){
if(strcasecmp($name,$v['Key_name'])==0){
$exists_index=true;
break;
}
}
return $exists_index;
}
/*判断存在字段*/
public function check_exists_field($name,$columns){
if(empty($name)){
return false;
}
$exists_column=false;
foreach ($columns as $k=>$v){
if(strcasecmp($name,$v['Field'])==0){
$exists_column=true;
break;
}
}
return $exists_column;
}
/*修改字段类型*/
public function modify_field_type($field,$type,$modifySql,$columns){
foreach ($columns as $v){
if(strcasecmp($field,$v['Field'])==0){
if(strcasecmp($type,$v['Type'])!=0){
db()->execute($modifySql);
}
break;
}
}
}
/*添加字段*/
protected function table_add_columns($table,$columns){
if($table&&is_array($columns)&&$columns){
$db_prefix=config('database.prefix');
$dbColumns=db()->query("SHOW COLUMNS FROM `{$db_prefix}{$table}`");
foreach($columns as $cname=>$cset){
if($cname&&$cset){
if(!$this->check_exists_field($cname,$dbColumns)){
db()->execute("alter table `{$db_prefix}{$table}` add `{$cname}` {$cset}");
}
}
}
}
}
/*添加索引*/
protected function table_add_indexes($table,$indexes){
if($table&&is_array($indexes)&&$indexes){
$db_prefix=config('database.prefix');
$dbIndexes=db()->query("SHOW INDEX FROM `{$db_prefix}{$table}`");
foreach($indexes as $iname=>$iset){
if($iname&&$iset){
if(!$this->check_exists_index($iname,$dbIndexes)){
db()->execute("ALTER TABLE `{$db_prefix}{$table}` ADD INDEX {$iname} ({$iset})");
}
}
}
}
}
public function execute_upgrade(){
$mconfig=model('common/Config');
@ -166,271 +94,138 @@ class UpgradeDb extends BaseController{
return return_result('升级完毕',true);
}
public function upgrade_db_to_1_3(){
$db_prefix=config('database.prefix');
$proxy_table=$db_prefix.'proxy_ip';
$exists=db()->query("show tables like '{$proxy_table}'");
if(empty($exists)){
$addTable=<<<EOF
CREATE TABLE `{$proxy_table}` (
`ip` varchar(100) NOT NULL,
`user` varchar(100) NOT NULL DEFAULT '',
`pwd` varchar(100) NOT NULL DEFAULT '',
`invalid` tinyint(4) NOT NULL DEFAULT '0',
`failed` int(11) NOT NULL DEFAULT '0',
`num` int(11) NOT NULL DEFAULT '0',
`time` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
EOF;
db()->execute($addTable);
public function upgrade_db_to_2_7(){
$ver=db()->query('SELECT VERSION() as ver;');
if(is_array($ver)&&is_array($ver[0])){
$ver=$ver[0]['ver'];
}
/*修改表*/
$columns_collected=db()->query("SHOW COLUMNS FROM `{$db_prefix}collected`");
if(!$this->check_exists_field('titleMd5', $columns_collected)){
db()->execute("alter table `{$db_prefix}collected` add `titleMd5` varchar(32) NOT NULL DEFAULT ''");
if(empty($ver)||version_compare($ver,'5.5.3','<')){
throw new \Exception('请使用5.5.3及以上版本的mysql数据库');
}
$indexes_collected=db()->query("SHOW INDEX FROM `{$db_prefix}collected`");
if(!$this->check_exists_index('ix_titlemd5', $indexes_collected)){
db()->execute('set names utf8mb4;');
$db_prefix=config('database.prefix');
$db_name=config('database.database');
$tableStatus=db()->query("SHOW TABLE STATUS FROM `{$db_name}` LIKE '{$db_prefix}%'");
foreach ($tableStatus as $v){
if(is_array($v)){
$v=\util\Funcs::array_keys_to_lower($v);
$tbName=$v['name'];
if($tbName&&stripos($v['collation'],'utf8mb4')!==0){
db()->execute("ALTER TABLE `{$db_prefix}collected` ADD INDEX ix_titlemd5 ( `titleMd5` )");
if($tbName==($db_prefix.'provider')){
$dbIndexes=db()->query("SHOW INDEX FROM `{$tbName}`");
if($this->check_exists_index('domain',$dbIndexes)){
db()->execute("ALTER TABLE `{$tbName}` DROP INDEX `domain`");
db()->execute("ALTER TABLE `{$tbName}` ADD INDEX `domain`(`domain`(250))");
}
$columns_task=db()->query("SHOW COLUMNS FROM `{$db_prefix}task`");
if(!$this->check_exists_field('config', $columns_task)){
db()->execute("alter table `{$db_prefix}task` add `config` mediumtext");
}
$columns_collector=db()->query("SHOW COLUMNS FROM `{$db_prefix}collector`");
$this->modify_field_type('config', 'mediumtext', "alter table `{$db_prefix}collector` modify column `config` mediumtext", $columns_collector);
$columns_release=db()->query("SHOW COLUMNS FROM `{$db_prefix}release`");
$this->modify_field_type('config', 'mediumtext', "alter table `{$db_prefix}release` modify column `config` mediumtext", $columns_release);
$columns_rule=db()->query("SHOW COLUMNS FROM `{$db_prefix}rule`");
$this->modify_field_type('config', 'mediumtext', "alter table `{$db_prefix}rule` modify column `config` mediumtext", $columns_rule);
if($tbName==($db_prefix.'user')){
$dbIndexes=db()->query("SHOW INDEX FROM `{$tbName}`");
if($this->check_exists_index('username',$dbIndexes)){
db()->execute("ALTER TABLE `{$tbName}` DROP INDEX `username`");
db()->execute("ALTER TABLE `{$tbName}` ADD CONSTRAINT `username` UNIQUE(`username`(250))");
}
if($this->check_exists_index('email',$dbIndexes)){
db()->execute("ALTER TABLE `{$tbName}` DROP INDEX `email`");
db()->execute("ALTER TABLE `{$tbName}` ADD INDEX `email`(`email`(250))");
}
}
db()->execute("ALTER TABLE `{$tbName}` CONVERT TO CHARACTER SET utf8mb4;");
}
}
public function upgrade_db_to_2_2(){
$db_prefix=config('database.prefix');
$provider_table=$db_prefix.'provider';
$exists=db()->query("show tables like '{$provider_table}'");
if(empty($exists)){
$addTable=<<<EOF
CREATE TABLE `{$provider_table}` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`url` varchar(255) NOT NULL DEFAULT '',
`domain` varchar(255) NOT NULL DEFAULT '',
`enable` tinyint(4) NOT NULL DEFAULT '0',
`sort` mediumint(9) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
EOF;
db()->execute($addTable);
}
$app_table=$db_prefix.'app';
$exists=db()->query("show tables like '{$app_table}'");
$dataset_table=$db_prefix.'dataset';
$exists=db()->query("show tables like '{$dataset_table}'");
if(empty($exists)){
$addTable=<<<EOF
CREATE TABLE `{$app_table}` (
$addTable=<<<EOF
CREATE TABLE `{$dataset_table}` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app` varchar(100) NOT NULL,
`provider_id` int(11) NOT NULL DEFAULT '0',
`addtime` int(11) NOT NULL DEFAULT '0',
`uptime` int(11) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL DEFAULT '',
`sort` mediumint(9) NOT NULL DEFAULT '0',
`desc` text,
`config` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
EOF;
db()->execute($addTable);
}
/*修改表*/
$columns_user=db()->query("SHOW COLUMNS FROM `{$db_prefix}user`");
if(!$this->check_exists_field('salt', $columns_user)){
db()->execute("alter table `{$db_prefix}user` add `salt` varchar(50) NOT NULL DEFAULT ''");
}
$columns_rule=db()->query("SHOW COLUMNS FROM `{$db_prefix}rule`");
if(!$this->check_exists_field('provider_id', $columns_rule)){
db()->execute("alter table `{$db_prefix}rule` add `provider_id` int(11) NOT NULL DEFAULT '0'");
}
$columns_rapp=db()->query("SHOW COLUMNS FROM `{$db_prefix}release_app`");
if(!$this->check_exists_field('provider_id', $columns_rapp)){
db()->execute("alter table `{$db_prefix}release_app` add `provider_id` int(11) NOT NULL DEFAULT '0'");
}
$indexes_release_app=db()->query("SHOW INDEX FROM `{$db_prefix}release_app`");
if(!$this->check_exists_index('ix_app', $indexes_release_app)){
db()->execute("ALTER TABLE `{$db_prefix}release_app` ADD unique ix_app ( `app` )");
}
}
public function upgrade_db_to_2_3(){
$db_prefix=config('database.prefix');
$func_app_table=$db_prefix.'func_app';
$exists=db()->query("show tables like '{$func_app_table}'");
$dataapi_table=$db_prefix.'dataapi';
$exists=db()->query("show tables like '{$dataapi_table}'");
if(empty($exists)){
$addTable=<<<EOF
CREATE TABLE `{$func_app_table}` (
CREATE TABLE `{$dataapi_table}` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`module` varchar(20) NOT NULL DEFAULT '',
`app` varchar(100) NOT NULL,
`name` varchar(100) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`route` varchar(100) NOT NULL DEFAULT '',
`sort` mediumint(9) NOT NULL DEFAULT '0',
`status` tinyint(4) NOT NULL DEFAULT '0',
`desc` text,
`enable` tinyint(1) NOT NULL DEFAULT '0',
`addtime` int(11) NOT NULL DEFAULT '0',
`uptime` int(11) NOT NULL DEFAULT '0',
`provider_id` int(11) NOT NULL DEFAULT '0',
`ds_id` int(11) NOT NULL DEFAULT '0',
`config` mediumtext,
PRIMARY KEY (`id`),
UNIQUE KEY `ix_app` (`app`),
UNIQUE KEY `module_app` (`module`,`app`),
KEY `module_enable` (`module`,`enable`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
KEY `ix_sort` (`sort`),
KEY `ix_ds_id` (`ds_id`),
KEY `ix_route` (`route`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
EOF;
db()->execute($addTable);
}
$columns_proxyip=db()->query("SHOW COLUMNS FROM `{$db_prefix}proxy_ip`");
if(!$this->check_exists_field('type', $columns_proxyip)){
db()->execute("alter table `{$db_prefix}proxy_ip` add `type` varchar(20) NOT NULL DEFAULT ''");
}
if(!$this->check_exists_field('addtime', $columns_proxyip)){
db()->execute("alter table `{$db_prefix}proxy_ip` add `addtime` int(11) NOT NULL DEFAULT '0'");
}
if(!$this->check_exists_field('no', $columns_proxyip)){
db()->execute("alter table `{$db_prefix}proxy_ip` add `no` bigint(20) NOT NULL");
}
$indexes_proxyip=db()->query("SHOW INDEX FROM `{$db_prefix}proxy_ip`");
if(!$this->check_exists_index('no', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX no ( `no` )");
}
db()->execute("alter table `{$db_prefix}proxy_ip` modify `no` bigint auto_increment");
if(!$this->check_exists_index('addtime_no', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX addtime_no ( `addtime`,`no` )");
}
if(!$this->check_exists_index('ix_num', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX ix_num ( `num` )");
}
if(!$this->check_exists_index('ix_time', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX ix_time ( `time` )");
}
}
public function upgrade_db_to_2_4(){
$db_prefix=config('database.prefix');
$indexes_proxyip=db()->query("SHOW INDEX FROM `{$db_prefix}proxy_ip`");
if($this->check_exists_index('ix_num', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` DROP INDEX ix_num");
}
if(!$this->check_exists_index('num_no', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX num_no ( `num`,`no` )");
}
if($this->check_exists_index('ix_time', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` DROP INDEX ix_time");
}
if(!$this->check_exists_index('time_no', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX time_no ( `time`,`no` )");
}
$columns_provider=db()->query("SHOW COLUMNS FROM `{$db_prefix}provider`");
if(!$this->check_exists_field('authkey', $columns_provider)){
db()->execute("alter table `{$db_prefix}provider` add `authkey` varchar(255) NOT NULL DEFAULT ''");
}
}
public function upgrade_db_to_2_5(){
$db_prefix=config('database.prefix');
$task_timer_table=$db_prefix.'task_timer';
$exists=db()->query("show tables like '{$task_timer_table}'");
$collected_info_table=$db_prefix.'collected_info';
$exists=db()->query("show tables like '{$collected_info_table}'");
if(empty($exists)){
$addTable=<<<EOF
CREATE TABLE `{$task_timer_table}` (
`task_id` int(11) NOT NULL DEFAULT '0',
`name` varchar(10) NOT NULL DEFAULT '',
`data` varchar(10) NOT NULL DEFAULT '',
KEY `ix_tid` (`task_id`),
KEY `ix_name` (`name`,`data`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
$addTable=<<<EOF
CREATE TABLE `{$collected_info_table}` (
`id` int(11) NOT NULL DEFAULT '0',
`url` text,
`target` text,
`desc` text,
`error` text,
KEY `ix_id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
EOF;
db()->execute($addTable);
}
}
public function upgrade_db_to_2_5_2(){
$db_prefix=config('database.prefix');
$proxy_group_table=$db_prefix.'proxy_group';
$exists=db()->query("show tables like '{$proxy_group_table}'");
if(empty($exists)){
$addTable=<<<EOF
CREATE TABLE `{$proxy_group_table}` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`parent_id` int(11) NOT NULL DEFAULT '0',
`sort` mediumint(9) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
EOF;
db()->execute($addTable);
}
$columns_proxyip=db()->query("SHOW COLUMNS FROM `{$db_prefix}proxy_ip`");
if(!$this->check_exists_field('group_id', $columns_proxyip)){
$collected_table=$db_prefix.'collected';
$collectedCount=db()->table($collected_table)->count();
if($collectedCount>0){
do{
$maxId=db()->table($collected_info_table)->max('id');
$maxId=intval($maxId);
$exists=db()->table($collected_table)->field('id')->where('id','>',$maxId)->limit(1)->find();
if(!empty($exists)){
db()->execute("alter table `{$db_prefix}proxy_ip` add `group_id` int(11) NOT NULL DEFAULT '0'");
$sql="INSERT INTO `{$collected_info_table}` (`id`,`url`,`target`,`desc`,`error`) SELECT `id`,`url`,`target`,`desc`,`error` FROM {$collected_table} WHERE id>{$maxId} order by id asc limit 1000";
db()->execute($sql);
}else{
break;
}
$indexes_proxyip=db()->query("SHOW INDEX FROM `{$db_prefix}proxy_ip`");
if(!$this->check_exists_index('gid_no', $indexes_proxyip)){
db()->execute("ALTER TABLE `{$db_prefix}proxy_ip` ADD INDEX gid_no ( `group_id`,`no` )");
}while(1==1);
}
$this->table_add_columns('collected',array('status'=>"tinyint(1) NOT NULL DEFAULT '0'"));
$this->table_add_indexes('collected',array('ix_status'=>'status'));
$dbColumns=db()->query("SHOW COLUMNS FROM `{$collected_table}`");
if($this->check_exists_field('target', $dbColumns)){
db()->execute("update `{$collected_table}` set `status`=1 where `target`<>'';");
}
$lockFileOld1=config('root_path').'/SkycaijiApp/install/data/install.lock';
$lockFileOld2=config('app_path').'/install/data/install.lock';
if(file_exists($lockFileOld1)||file_exists($lockFileOld2)){
write_dir_file(config('root_path').'/data/install.lock', '1');
foreach (array('url','target','desc','error') as $fname){
if($this->check_exists_field($fname, $dbColumns)){
db()->execute("ALTER TABLE `{$collected_table}` DROP COLUMN `{$fname}`;");
}
}
public function upgrade_db_to_2_6_1(){
$this->table_add_columns('collected', array('contentMd5'=>"varchar(32) NOT NULL DEFAULT ''"));
$this->table_add_indexes('collected', array('ix_contentmd5'=>"`contentMd5`"));
}
}
?>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save