系統升級需要校驗本地的文件是否被修改過,系統默認每次檢驗1千個文件,一般來說需要分四到五頁來處理,如下圖所示。

如果你的服務器性能太差的話,就需要手工把數值調小。把下面的代碼復制出來。進入后臺數據庫管理工具那里執行一下,導入數據庫。然后就可以在后臺核心設置那里修改數值
~~~
INSERT INTO `qb_config` (`id`, `type`, `title`, `c_key`, `c_value`, `form_type`, `options`, `ifsys`, `htmlcode`, `c_descrip`, `list`, `sys_id`) VALUES(0, 1, '系統升級每次核對文件數', 'sys_update_filenum', '10', 'number', '', 1, '', '留空則默認是1000,如果你的空間性能太差,就手工調為50甚至10', 0, 0);
~~~
導入數據庫后,需要在下面那里做設置,如下圖

把數值相應調小,測試看看能否正常升級。
復制下面的代碼修改兩個文件后,將會實現如下圖的效果.

要實現分頁檢驗文件的話,需要修改兩個文件.
> 復制下面的代碼替換`\application\admin\controller\Upgrade.php`中的內容
~~~
<?php
namespace app\admin\controller;
use app\common\controller\AdminBase;
use app\common\model\Module;
use app\common\model\Plugin;
use app\common\model\Hook_plugin;
use app\common\model\Market as MarketModel;
use app\common\model\Timedtask AS TaskModel;
class Upgrade extends AdminBase
{
public function _initialize(){
parent::_initialize();
if(config('client_upgrade_edition')==''){
config('client_upgrade_edition',RUNTIME_PATH . '/client_upgrade_edition.php');
}
}
public function index()
{
$this->clean_cache();
$array = @include(config('client_upgrade_edition'));
$this->assign('upgrade',$array);
return $this->fetch('index');
}
/**
* 清除相關緩存
*/
protected function clean_cache(){
cache('timed_task',null);
cache('cache_modules_config',null);
cache('cache_plugins_config',null);
cache('hook_plugins',null);
}
/**
* 更新升級日志
* @param string $upgrade_edition
* @return boolean|string
*/
private function writelog($upgrade_edition=''){
$data = $this->request->post();
if($data['m']){
$array = modules_config();
foreach ($array AS $rs){
$de = $data['m'][$rs['keywords']];
if($de){
$vs = $de['time']."\t".$de['md5'];
Module::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
if($data['p']){
$array = plugins_config();
foreach ($array AS $rs){
$de = $data['p'][$rs['keywords']];
if($de){
$vs = $de['time']."\t".$de['md5'];
Plugin::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
if($data['h']){
$array = cache('hook_plugins');
foreach ($array AS $rs){
$de = $data['h'][$rs['version_id']];
if($de){
$vs = $de['time']."\t".$de['md5'];
Hook_plugin::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
if($data['t']){
$array = cache('timed_task');
foreach ($array AS $rs){
$de = $data['t'][$rs['version_id']];
if($de){
$vs = $de['time']."\t".$de['md5'];
TaskModel::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
$this->upgrade_mark($data['admin_style'],'admin_style');
$this->upgrade_mark($data['index_style'],'index_style');
$this->upgrade_mark($data['member_style'],'member_style');
$this->upgrade_mark($data['qun_style'],'qun_style');
$this->upgrade_mark($data['haibao_style'],'haibao_style');
$this->upgrade_mark($data['model_style'],'model_style');
$this->upgrade_mark($data['packet'],'packet');
$this->clean_cache();
if( file_put_contents(config('client_upgrade_edition'), '<?php return ["md5"=>"'.$upgrade_edition.'","time"=>"'.date('Y-m-d H:i').'",];') ){
return true;
}else{
return '權限不足,日志寫入失敗';
}
}
/**
* 應用市場,比如風格更新升級日志
* @param array $data
* @param string $type 比如admin_style index_style member_style
*/
private function upgrade_mark($data=[],$type=''){
if($data){
$array = MarketModel::get_list(['type'=>$type]);
foreach ($array AS $rs){
$de = $data[$rs['version_id']];
if($de){
$vs = $de['time']."\t".$de['md5'];
MarketModel::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
}
/**
* 更新前,先備份一下文件
* @param string $filename
*/
private function bakfile($filename=''){
$bakpath = RUNTIME_PATH.'bakfile/';
if(!is_dir($bakpath)){
mkdir($bakpath);
}
$new_name = $bakpath.date('Y_m_d-H_i--').str_replace(['/','\\'], '--', $filename);
copy(ROOT_PATH.$filename,$new_name);
}
/**
* 升級數據庫
* @param string $filename
*/
private function up_sql($filename=''){
if(preg_match('/\/upgrade\/([\w]+)\.sql$/', $filename)){
//if(preg_match('/^\/application\/common\/upgrade\/([\w]+)\.sql/', $filename)){
into_sql(ROOT_PATH.$filename,true,0);
}
}
/**
* 執行更多復雜的邏輯性的升級
* @param string $filename
*/
private function up_run($filename=''){
if(preg_match('/^\/application\/common\/upgrade\/([\w]+)\.php$/', $filename)){
$classname = "app\\common\\upgrade\\".ucfirst(substr(basename($filename), 0,-4));
}elseif( preg_match('/(application|plugins)\/([\w]+)\/upgrade\/([\w]+)\.php$/',$filename,$array) ){ //實際已包含了上面的
$m_p = $array[1]=='application'?'app':'plugins';
$model = $array[2];
$file = $array[3];
$classname = "$m_p\\$model\\upgrade\\".ucfirst($file);
}else{
return;
}
if( class_exists($classname) && method_exists($classname, 'up') ){
$obj = new $classname;
try {
$obj->up();
} catch(\Exception $e) {
//echo $e;
}
}
}
/**
* 正式執行開始升級,一個一個的文件升級替換
*/
public function sysup($filename='',$upgrade_edition=''){
if($upgrade_edition){ //升級完畢,寫入升級信息日志
$result = $this->writelog($upgrade_edition);
if( $result===true ){
return $this->ok_js([],'升級成功');
}else{
return $this->err_js($result);
}
}
list($filename,$id) = explode(',',$filename);
if($filename==''){
return $this->err_js('文件不存在!');
}
$str = $this->get_server_file($filename,$id);
if($str){
$filename = $this->format_filename($filename); //針對模塊或插件的升級做替換處理
$this->bakfile($filename);
makepath(dirname(ROOT_PATH.$filename)); //檢查并生成目錄
if( file_put_contents(ROOT_PATH.$filename, $str) ){
$this->up_sql($filename);
$this->up_run($filename);
return $this->ok_js([],'文件升級成功');
}else{
return $this->err_js('目錄權限不足,文件寫入失敗');
}
}else{
return $this->err_js('獲取云端數據失敗,請確認服務器DNS是否正常,能否訪問外網?');
}
}
/**
* 升級前,可以查看任何一個文件的源代碼
* @param string $filename
*/
public function view_file($filename='',$id=0,$oldfile=''){
$str = $this->get_server_file($filename,$id);
if ( preg_match("/(\.jpg|\.png|\.jpeg|\.gif)$/i", $filename) ) {
//header('Content-type:image/'.substr($filename,strripos($filename,'.')+1));echo $str;
if (is_file(ROOT_PATH.$oldfile)) {
echo "<img style='max-width:200px;' src='".request()->domain().'/'.$oldfile."'><br>";
}
$temp_file = "uploads/images/temp.".substr($filename,strripos($filename,'.')+1);
file_put_contents(PUBLIC_PATH.$temp_file, $str);
echo "<br><br><img style='max-width:200px;' src='".tempdir($temp_file)."?".time()."'>";
exit;
}
$this->assign('new_code',str_replace(['<','>'], ['<','>'], $str));
$this->assign('old_code', str_replace(['<','>'], ['<','>'], file_get_contents(str_replace('//', '/', ROOT_PATH.$oldfile)) ) );
return $this->fetch();
}
/**
* 針對要升級的模塊與插件的文件名特別處理, 替換后,// 雙斜杠開頭的文件就是插件或模塊升級的文件
* @param string $filename
* @return string|mixed
*/
protected function format_filename($filename=''){
if(strstr($filename,'/../../')){
$filename = str_replace(['/../../template/','/../../plugin/','/../../hook/'], '/../../', $filename);
$filename = preg_replace('/^\/..\/..\/([\w]+)/','/',$filename);
}
return $filename;
}
/**
* 核對需要升級文件,展示出來給用戶挑選哪些不想升級
* 這里的升級文件列表,即有系統的,也有頻道插件與風格的
* @param string $upgrade_edition
* @param string $page 分頁檢驗需要升級的文件.一次處理的話,有的服務器可能吃不消
* @return string|mixed
*/
public function check_files($upgrade_edition='',$page=0,$rows=1000){
if ($this->webdb['sys_update_filenum']>0) {
$rows = $this->webdb['sys_update_filenum'];
}
set_time_limit(0); //防止超時
$array = $this->getfile($page);
if(empty($array)){
$str = http_curl("https://x1.php168.com/appstore/upgrade/get_version.html?id=46");
if (!strstr($str,'md5')) {
return $this->err_js('你的服務器無法訪問齊博官網,請檢查你的服務器DNS是否配置正確,或者是否設置了防火墻不能訪問外網');
}
return $this->err_js('獲取云端文件列表數據失敗,請晚點再償試');
}
$totalpage = ceil(count($array)/$rows);
if (!$page) {
set_cookie('need_update',0);
return $this->ok_js($totalpage);
}
$data = [];
$min = ($page-1)*$rows;
for($i=$min;$i<$min+$rows;$i++){
$rs = $array[$i];
if (!$rs) {
break;
}
// }
// foreach($array AS $rs){
$showfile = $this->format_filename($rs['file']);
$file = ROOT_PATH.$showfile;
if (is_file($file.'.lock') && file_get_contents($file.'.lock')=='hide') {
continue; //用戶不想升級的文件,也不想提示升級
}
$ispic = false;
$change = false;
$md5_size = '';
if (!is_file($file)) {
$change = true;
}elseif( ($md5_size=md5_file($file)) != $rs['md5'] ){
$change = true;
if ( preg_match("/(\.jpg|\.png|\.jpeg|\.gif)$/i", $file) ) {
$ispic = true;
}elseif ( check_bom($file,true) ) {
file_put_contents($file, check_bom($file));
if (md5_file($file)==$rs['md5']) {
$change = false;
}//elseif(preg_match("/(\/|\\\)upgrade(\/|\\\)([\w]+)(\.sql|\.php)$/i", $file)){
//$change = false;
//}
}
}
if($change){
$data[]=[
'file'=>$rs['file'],
'showfile'=>$showfile,
'md5'=>$md5_size,
'id'=>$rs['id'],
'islock'=>(is_file($file.'.lock')||(is_file($file)&&preg_match("/(\/|\\\)upgrade(\/|\\\)([\w]+)(\.sql|\.php)$/i", $file)))?1:0,
'ctime'=>is_file($file)?date('Y-m-d H:i',filemtime($file)):'缺失的文件',
'time'=>date('Y-m-d H:i',$rs['time']),
];
}
}
$array_sql = $array_php = [];
foreach ($data AS $key=>$rs){
if( preg_match("/\/upgrade\/([\w]+\.sql)/i",$rs['file']) ){
unset($data[$key]);
$array_sql[$rs['file']] = $rs;
}elseif( preg_match("/\/upgrade\/([\w]+\.php)/i",$rs['file']) ){
unset($data[$key]);
$array_php[$rs['file']] = $rs;
}
}
ksort($array_php);
ksort($array_sql);
$data = array_values(array_merge($data,$array_sql,$array_php));
$need_update = get_cookie('need_update')+count($data);
set_cookie('need_update',$need_update);
if ($page==$totalpage) {
unlink(RUNTIME_PATH.'updatelist.txt');
}
if($page==$totalpage && $need_update<1){
$upgrade_edition && $reustl = $this->writelog($upgrade_edition);
return $this->err_js($reustl!==true?$reustl:'沒有可更新文件');
}else{
return $this->ok_js($data?:[]);
}
}
/**
* 獲取云端的某個最新文件
* @param string $filename 升級的文件名
* @param number $id 對應云端的插件ID
* @return string|mixed
*/
protected function get_server_file($filename='',$id=0){
@set_time_limit(600); //防止超時
$str = http_curl('https://x1.php168.com/appstore/upgrade/make_client_file.html?filename='.$filename.'&id='.$id.'&appkey='.urlencode($this->webdb['mymd5']).'&domain='.urlencode($this->request->domain()));
if(substr($str,0,2)=='QB'){ //文件核對,防止網絡故障,抓取一些出錯信息
$str = substr($str,2);
}else{
$str='';
}
return $str;
}
/**
* 獲取云端的最新文件列表
* @return string|mixed
*/
protected function getfile($page=0){
if (!$page) {
$str = http_curl('https://x1.php168.com/appstore/upgrade/get_list_file.html?typeid='.$this->webdb['typeid'].'&appkey='.urlencode($this->webdb['mymd5']).'&domain='.urlencode($this->request->domain()),['app_edition'=>fun('upgrade@local_edition')]);
file_put_contents(RUNTIME_PATH.'updatelist.txt', $str);
}else{
$str = file_get_contents(RUNTIME_PATH.'updatelist.txt');
}
return $str ? json_decode($str,true) : '';
}
}
?>
~~~
> 復制下面的代碼替換`\template\admin_style\default\admin\upgrade\index.htm`中的內容
~~~
{extend name="index:layout" /}
{block name="menu"}{/block}
{block name="content"}
<link rel="stylesheet" href="/public/static/layui/css/layui.css" media="all">
<script src="__STATIC__/js/core/vue.js"></script>
<script type="text/javascript">
<!--
if (navigator.userAgent.indexOf("MSIE") >= 0) {
alert("請使用谷歌或火狐訪問.其它瀏覽器無法操作與使用");
}
//-->
</script>
<style type="text/css">
.locktr td,.locktr td a{
color:orange;
}
.progress_warp{
position:fixed;
top:65%;
z-index:9999999999;
width:100%;
display:none;
}
.progress_warp .layui-progress{
margin:0 200px;
}
</style>
<form name="formlist" method="post" action="" class="up_files">
<div class="MainContainers">
<div class="Header"><span class="tag">在線升級</span><span class="more">>></span></div>
<div class="Conter">
<table class="ListTable" id="upgradeTR">
<tr>
<th width='8%'>選中升級</th>
<th>文件名稱</th>
<th width='17%'>升級前時間</th>
<th width='21%'>更新時間</th>
<th width='19%'>對比差異</th>
</tr>
<tr id="contents">
<td colspan=5 height=30 style="background:#eee;">
<div align="center" style="color:red;" class="upgrade_msg">正在獲取云端數據信息,請稍候...</div>
</td>
</tr>
<tr v-for="rs in listdb" :class="rs.islock?'locktr':''">
<td class="b red">
<input v-if="rs.islock==1||rs.md5!=''" :data-islock="rs.islock" :data-showfile="rs.showfile" :data-md5="rs.md5" type="checkbox" name="filedb[]" :value="rs.file+','+rs.id" onclick="if($(this).is(':checked'))layer.alert('你修改過當前文件,你確認要升級覆蓋現有的文件嗎?')" />
<input v-else type="checkbox" name="filedb[]" :value="rs.file+','+rs.id" checked /> {{rs.i}}
</td>
<td class="Left listfile" :data-id="rs.id">{{rs.showfile}}</td>
<td>
<div align="center">{{rs.ctime}}</div>
</td>
<td>{{rs.time}}</td>
<td><a :href="'{:urls('view_file')}?filename='+rs.file+'&oldfile='+rs.showfile+'&id='+rs.id" target="_blank">對比差異</a>
</td>
</tr>
<tr bgcolor='#FFFFFF' align="center" class="up_btn" style="display:none;">
<td colspan='5'>
<div class='submits'>
<!--<input type='button' onclick="CheckAll(this.form)" name='Submit' value='全選'>-->
<input type='button' style="background:red;" onclick="sys_upgrade();" name='Submit' value='立刻升級'>
</div>
</td>
</tr>
</table>
</div>
</div>
</form>
<div class="MainContainers">
<div class="Header"><span class="tag">升級說明</span></div>
<div class="Conter">
<ul class="notes">
<li>1、你可以選擇哪些文件不升級,不過你最好是在程序目錄,把不想升級的文件,做個標志,比如“index.htm”不想升級,就在對應的目錄創建一個文件“index.htm.lock”,這樣每次升級,文件就處于非選中狀態,而不會升級。</li>
<li>2、如果網絡故障,一次升級不成功,可反復升級</li>
<li>3、如果因為升級文件被替換了,請進目錄/runtime/bakfile/找回來</li>
<li>4、系統默認每次校驗文件數是1千個,如果你的空間性能太差的話,<a href="http://www.hmoore.net/php168/x1_of_qibo/2059526" target="_blank">請點擊查看教程進行設置</a></li>
</ul>
</div>
</div>
<div class="progress_warp">
<div class="layui-progress layui-progress-big" lay-showpercent="true" lay-filter="progressId">
<div class="layui-progress-bar" lay-percent="1%"></div>
</div>
</div>
<script src="__STATIC__/layui/layui.js"></script>
<script type="text/javascript">
var element;
$(function(){
layui.use('element', function(){
element = layui.element;
})
//element.progress('progressId', i+'%');
})
</script>
<script language=JavaScript>
var upgrade_edition = '';
var upgrade_data = {};
//檢查版本更新
function check_upgrade(){
var now_edition = "{$upgrade.md5}";
$.post("https://x1.php168.com/appstore/upgrade/get_edition.html?typeid={$webdb.typeid}&"+Math.random(),{
app_edition:"{:fun('upgrade@local_edition')}",
sys_edition:now_edition,
domin:'{:request()->domain()}',
appkey:'{$webdb.mymd5}'
}).success( function(res){
if(res.code==0){
upgrade_data = res.data;
if(res.data.md5!=now_edition||typeof(res.data.upgrade_msg) != "undefined"){
if(typeof(res.data.time) == "undefined"){
return ;
}
upgrade_edition = res.data.md5;
var msg = typeof(res.data.upgrade_msg) != "undefined" ? res.data.upgrade_msg : '你的系統需要升級<br>云端更新日期:'+res.data.time;
$(".upgrade_msg").html(msg);
layer.confirm(msg, {
btn : [ '查看需要升級的文件', '晚點再升級' ]
}, function(index) {
down_file_list();
});
}else{
$(".upgrade_msg").html('已經是最新了,無須升級');
}
}else{
layer.alert(res.msg,{time:5500});
}
}).fail(function (res) {
//layer.alert('網絡故障,請晚點再償試升級!!');
//layer.closeAll();
layer.open({title: '網絡故障,請晚點再償試升級!!',area:['90%','90%'],content: res.responseText});
});
}
check_upgrade();
var app_ids = {};
var vues = new Vue({
el: '#upgradeTR',
data: {
listdb: [],
},
watch:{
listdb: function() {
this.$nextTick(function(){ //數據渲染完畢才執行
var time = 100;
$("input[data-islock=0]:not(:checked)").each(function(){
time += 200;
var that = $(this);
var url = "https://x1.php168.com/appstore/upgrade/check_md5.html?path="+that.attr('data-showfile')+"&md5="+that.attr('data-md5');
setTimeout(function(){
$.get(url,function(res){
if(res.code==0){
that.attr('checked',true);
}
});
},time);
});
var times = 500;
$(".listfile").each(function(){
var that = $(this);
if(that.attr("data-id")){
var id = that.attr("data-id");
if(app_ids[id]==undefined){
app_ids[id] = {};
times += 500;
setTimeout(function(){
$.get("https://x1.php168.com/appstore/wxapp.show/index.html?id="+id,function(res){
if(res.code==0){
//app_ids[id] = res.data;
$(".listfile[data-id="+id+"]").append(" <a href='https://x1.php168.com/appstore/content/show/id/"+id+".html' target='_blank'>"+res.data.title+"</a>");
}
});
},times);
}
}
});
$(".up_btn").show();
layer.alert('需要升級的文件列表如下,你可以有選擇性的升級');
});
}
},
methods: {
add_data:function(array){
$("#contents").remove();
array.forEach((rs,i)=>{
rs.i = i+1;
this.listdb.push(rs);
});
}
}
});
var need_update_file = [];
function check_need_update(totalpage,page){
if(page==1)layer.load(1,{shade: [0.7, '#393D49']}, {shadeClose: true}); //0代表加載的風格,支持0-2
layer.msg('正在核對需要升級的文件, <b style="color:red;">'+page+'</b> / '+totalpage+' 頁,<br>需要一點時間,請耐心等候!',{icon:1,time:30000, shift: 1});
$.post("{:urls('check_files')}?upgrade_edition="+upgrade_edition+"&page="+page,upgrade_data,function(res){
if(res.code==0){
res.data.forEach((rs)=>{
need_update_file.push(rs);
});
if(page<totalpage){
page++;
check_need_update(totalpage,page);
}else{
layer.closeAll();
vues.add_data(need_update_file);
}
}else{
layer.alert(res.msg);
}
});
}
//下載文件列表,核對需要哪些更新
function down_file_list(){
layer.alert('正在從云端下載升級文件列表,請稍候!');
var index = layer.load(1,{shade: [0.7, '#393D49']}, {shadeClose: true}); //0代表加載的風格,支持0-2
$.post("{:urls('check_files')}?upgrade_edition="+upgrade_edition,upgrade_data).success(function(res){
layer.closeAll();
if(res.code==0){
//vues.add_data(res.data);
check_need_update(res.data,1);
/*
var str = '';
res.data.forEach(function(rs){
var ck = rs.islock?" onclick='layer.alert(\"當前文件已鎖定,你確認要升級嗎?\")' ":' checked ';
var style = rs.islock?" class='locktr' ":' ';
str +='<tr '+style+'>'+
'<td class="b red"> <input type="checkbox" name="filedb[]" value="'+rs.file+','+rs.id+'" '+ck+'></td>'+
'<td class="Left">'+rs.showfile+'</td>'+
'<td><div align="center">'+rs.ctime+'</div></td>'+
'<td>'+rs.time+'</td>'+
'<td><a href="{:urls("view_file")}?filename='+rs.file+'&id='+rs.id+'" target="_blank">查看</a></td>'+
'</tr>';
});
document.getElementById('contents').outerHTML=str;
*/
}else{
layer.alert(res.msg,{time:5500});
}
}).fail(function (res) {
layer.closeAll();
//layer.alert('通信失敗,可能你的后臺權限不足'); )
var parsedJson = $.parseJSON(res.responseText.substr(res.responseText.indexOf('{'))); //用戶程序中有UTF8 +BOM文件導致的
if( typeof(parsedJson) == 'object' && parsedJson.code==0){
//vues.add_data(parsedJson.data);
check_need_update(res.data,1);
/*
var str = '';
parsedJson.data.forEach(function(rs){
var ck = rs.islock?" onclick='layer.alert(\"當前文件已鎖定,你確認要升級嗎?\")' ":' checked ';
var style = rs.islock?" class='locktr' ":' ';
str +='<tr '+style+'>'+
'<td class="b red"> <input type="checkbox" name="filedb[]" value="'+rs.file+','+rs.id+'" '+ck+'></td>'+
'<td class="Left">'+rs.showfile+'</td>'+
'<td><div align="center">'+rs.ctime+'</div></td>'+
'<td>'+rs.time+'</td>'+
'<td><a href="{:urls("view_file")}?filename='+rs.file+'&id='+rs.id+'" target="_blank">查看</a></td>'+
'</tr>';
});
document.getElementById('contents').outerHTML=str;
*/
//$(".up_btn").show();
//layer.alert('需要升級的文件列表如下,你可以有選擇性的升級<br>特別提醒:你的系統中有錯誤的UTF8 +BOM 代碼文件,一般情況是新裝的風格導致的,請仔細排查!');
return ;
}else if( typeof(parsedJson) == 'object' && parsedJson.code==1){
layer.alert(parsedJson.msg+"<br><br>特別提醒:你的系統中有錯誤的UTF8 +BOM 代碼文件,一般情況是新裝的風格導致的,請仔細排查!",{time:5500});
return ;
}
layer.confirm('通信失敗,你是否要新開窗口查看一下詳情?'+JSON.stringify(res), {
btn : [ '查看詳情', '取消' ]
}, function(index) {
window.open("{:urls('check_files')}?upgrade_edition="+upgrade_edition);
});
});
}
//開始升級文件
function sys_upgrade(){
$(".up_files input[type='checkbox']").each(function(i){
if($(this).is(':checked')==true){
ckfile_num++;
}
});
layer.alert('正在升級文件,請耐心稍候...');
var index = layer.load(1,{shade: [0.7, '#393D49']}, {shadeClose: true}); //0代表加載的風格,支持0-2
$(".progress_warp").show();
var time = 0;
$(".up_files input[type='checkbox']").each(function(i){
if($(this).is(':checked')==true){
var file_name = $(this).val();
var obj = $(this).parent().next();
if( file_name.indexOf('/upgrade/')>0 ){
time += 3000;
}else{
time += 500;
}
setTimeout(function(){
upgrade_file(file_name,obj);
},time);
}
});
}
//全部升級完畢
function end_up(){
layer.msg('全部文件升級成功');
$.post("{:urls('sysup')}?upgrade_edition="+upgrade_edition,upgrade_data).success(function(res){
if(res.code==0){
layer.alert('本次升級完畢,'+ok_num+'個文件升級成功!');
}else{
layer.alert('升級信息寫入失敗');
}
}).fail(function (res) {
layer.open({title: '網絡故障,請晚點再償試升級!!',area:['90%','90%'],content: res.responseText});
});
}
var ckfile_num = 0; //選中的升級文件個數
var ok_num = 0; //成功升級文件個數
//一個一個的文件升級
function upgrade_file(filename,obj){
$.post("{:urls('sysup')}?filename="+filename,upgrade_data).success(function(res){
if(res.code==0){
//layer.msg('文件:'+filename+' 升級成功');
var str = obj.html()+' <font color="red">升級成功</font>';
obj.html(str);
ok_num++;
if(ok_num==ckfile_num){ //全部升級完畢
layer.closeAll();
end_up();
$(".progress_warp").hide();
}
element.progress('progressId', parseInt(ok_num*100/ckfile_num)+'%'); //升級進度
}else{
//layer.msg('文件:'+filename+' 升級失敗:'+ res.msg,{time:2500});
var str = obj.html()+' <font color="blue">升級失敗:'+res.msg+'</font>';
obj.html(str);
}
}).fail(function (res) {
//layer.alert('通信失敗,可能你的后臺權限不足');
layer.open({title: '網絡故障,請晚點再償試升級!!',area:['90%','90%'],content: res.responseText});
});
}
function CheckAll(form){
for (var i=0;i<form.elements.length;i++){
var e = form.elements[i];
e.checked == true ? e.checked = false : e.checked = true;
}
}
</script>
{/block}
~~~
- 新手快速入門教程
- AI智能積分體系的開發
- 二次開發教程
- mysql數據表簡介
- CMS文章與論壇的數據表簡介視頻教程
- 鉤子模塊插件數據表講解
- 數據表參數設置講解
- 數據表后臺的所有參數設置
- 表單自動生成器
- 表單器新增與修改
- 不同的選項聯動觸發不同的表單項
- 萬能字段自定義字段的特別講解
- 如何給二維多維數組定義描述
- 商城判斷是否購買過
- 在線支付接口的使用
- 支付視頻教程
- 程序中快速激活當前頁面在線支付付款充值
- JS網頁快速接入支付功能
- 模塊后期要加參數的方法
- 自定義字段下拉菜單關聯其它數據表
- 自定義字段表單默認調用會員資料
- 頻道插件如何對接圈子
- 頻道的二次開發入門講解
- 模塊安裝文件講解
- 表單快速啟用城市地區功能
- 前臺后臺地址跳轉的處理
- 會員中心菜單權限顯示
- 動態改變標簽調用不同頻道的數據
- 自定義字段關聯其它字段的隱藏顯示
- 齊博首創鉤子的使用方法
- 模型里邊鉤子的創建與使用
- 鉤子自動添加頻道參數變量
- 如何增加會員中心及后臺菜單
- 暴力吸粉,強制關注公眾號,再引導進入相關頁面
- 如何發布方案
- 發布方案幾個要點注意事項
- 表單字段如何獲取當前地址
- 快速增加下拉菜單
- 系統與頻道插件的參數配置講解
- 下訂單與付款后的信息通知開關
- 查詢某個時間段內的數據
- 二開小技巧
- 如何自動增加模塊參數
- 新增內容想關閉窗口或者繼續提交相關數據
- 耗時的功能異步啟用子進程
- 增強版緩存cache2
- php操作redis的常用方法
- 后臺自定義搜索
- 如何給會員中心菜單及后臺菜單傳更多的參數
- 如何讓class類標簽增加更多的設置選項
- 程序中如何激活當前頁面在線充值
- 表單只顯示部分字段
- 群聊模塊二次開發
- JS及框架接口的說明
- 幾個重要的方法函數
- JS文件共有4個關鍵類
- 內容重新渲染,使聊天內容更炫
- 如何使用定時群發消息
- 自定義字段下拉框選擇數據表字段
- 表單相關視頻
- 表單入門視頻
- 如何調用上傳文件的接口
- 如何新增加系統表單字段輸入選項
- 如何創建各種類型的填寫表單
- 在模板中快速添加下拉菜單
- 在程序中快速添加下拉菜單
- 圈主自定義用戶組的處理
- 模塊插件安裝程序制作的視頻教程
- 模塊插件安裝程序制作的圖文教程
- 鉤子BUG沖突部分鉤子不生效
- 如何重定義改寫自動表單中的某個字段
- 列表項菜單自定義匿名函數
- 如何新增自定義字段
- 如何添加滑動驗證碼
- 登錄頁及注冊頁增加滑動驗證碼
- 增加系統參數的幾種方法
- 如何定義微信模板消息
- 風格模板教程
- 欄目名稱調用詳解
- where實現條件篩選與數據關聯
- 調用多個圈子同時調用貼子
- 調用多個圈子同時調用相關會員
- 內頁調用本欄目其它內容
- 萬能數據統計之fun函數
- 背景圖如何設置標簽
- 圈子黃頁風格制作說明
- 同一個標簽要更換不同模塊的數據
- 標簽如何調用論壇內容
- 標簽設置取組圖不存在就取內容中的圖片
- 用異步加載,可加快網頁打開速度
- 顯示購物車數量與商品
- 登錄提醒判斷處理
- 如何使用不同的頭部風格
- 輔欄目字段跨頻道調用
- 給頻道內容生成不同的海報
- 如何調用論壇內容里的圖片
- 父欄目的調用判斷
- 根據用戶uid調用圈子信息
- 循環列出某個子分類同時調取對應分類下的內容
- 底部頭部菜單如何設置高亮
- 滑動門+下滑加載更多
- 圈子切換按鈕調用不同頻道的數據
- 如何調用顯示地區
- 內容太多如何分屏顯示
- 向上滾動特效
- 調用欄目分類的字段
- 如何調用系統自定義字段
- 開發者如何展示某套風格
- 如何調用評論
- 如何進入某人的圈子
- 包含碎版模板include的用法
- 圈子風格制作講解
- 圈子頻道風格的目錄講解
- 圈子頻道程序的目錄講解
- 圈子完整一套風格目錄
- 圈子風格實現獨立的頭尾全局布局風格
- 專題標簽調用詳解
- 頻道內容頁圈子專屬模板說明
- 如何列出所有萬能表單
- 添加標簽注意事項
- 制作幻燈片標簽教程
- 萬能數據統計調用方法
- 重新定義微信分享的標題圖片及鏈接
- 網站當天當月積分余額消費收入統計
- 如何生成二維碼
- 如何查詢某個時間段內的數據
- 如何彈出客服會話窗口
- 在當前文章內頁調出所有輔欄目的名稱
- 導航菜單高亮設置
- 標簽調取關注我的粉絲
- 調用當前頁面的小程序碼與普通二維碼
- 使用縮略圖功能加快列表頁打開速度
- 如何調用視頻播放器
- 另一種單頁,創建模板就能實現單頁
- 標簽中如何獲取編輯器里的視頻地址
- 自動添加自定義模板字段的方法
- 自定義模板字段的添加規則
- 把內容評論改造成即時聊天
- 任何頁面加入即時聊天功能
- 標簽如何動態調用不同頻道的數據
- qb:tag萬能標簽的使用
- 如何統計用戶不同時間段的收益支出
- 小程序關注公眾號的方法
- 引用布局模板注意事項
- 如何對自定義字段做特殊顯示處理
- 如何在內容頁或列表頁及主頁調用關聯的圈子信息
- 風格模塊碎片教程
- 風格模塊碎片是什么?
- 模塊碎片入門
- qb:tag與qb:hy的主要區別
- 公共碎片模板與私有碎片模板
- 碎片子模板高級配置
- 自定義表單參數對照表
- 碎片模板高級技巧
- 碎片模板注意事項
- 風格碎片視頻教程
- 第一集,入門基礎篇
- 第二集,進階篇
- 第三集,鞏固篇
- 第四集,實戰篇,萬能數據統計碎片
- 第五集,碎片深入開發
- 第六集,涉及表單碎片的制作開發
- 開發及上架公共碎片注意事項
- 碎片如何獲取主模板的變量值
- 標簽設置中的個性模板配置
- 站內引用主題使用公共碎片的方法
- 碎片如何增加展示選擇預覽圖片
- 飄浮碎片如何定位標簽層
- 標簽碎片中如何做復雜的數據DEMO演示
- 飄浮的標簽元素如何添加占位符
- 標簽變量如何傳到外面使用
- 標簽中如何實現條件篩選過濾查詢
- 標簽或碎片的一些注意事項
- 碎片模板文件后綴名設置為php可防盜
- 模板代碼如何混淆加密
- 常用文件目錄說明
- 風格目錄文件說明
- 模板文件調用的優先級
- 新風格要注意問題
- 幾個關鍵模板文件要熟知
- 安裝云市場應用注意事項
- 標簽快速入門
- 標簽進階之幻燈片制作
- 標簽之無刷新顯示更多
- 異步加載標簽數據
- 做風格常用的變量名
- 標簽動態調用數據
- 文本代碼標簽的使用
- 多張組圖的標簽調用
- 一張圖片展示X1目錄結構簡介
- 如何強制進后臺
- 單張圖片標簽的使用
- 后臺網站參數配置修改與添加
- 簡單的模塊制作說明(隨風編寫)
- 鉤子簡單制作-tag加連接解說版(隨風編寫)
- 模板中常用的TP標簽數據處理
- 做模板組圖單圖無圖混排的處理
- 列表頁制作及無滾動加載內容
- 如何對接公眾號
- 微信支付授權目錄詳細講解
- 公眾號發送關鍵字沒反應的原因
- 公眾號模板消息字段名的設置
- 對接小程序設置
- 商家圈子小程序的配置
- IIS服務器注意事項
- 會員中心如何加標簽
- 再強調嚴禁用記事本改任何文件
- 支付寶對接收款配置
- 標簽的嵌套用法,調用聚合數據
- 阿里云短信配置
- 內容評論的風格制作
- 二次開發的靈魂fun函數
- 自定義字段多文件多圖的顯示處理
- 內容中下一頁上一頁的標簽
- 標簽動態變量查詢
- 相關欄目名稱的調用
- 輔欄目(專題)的使用說明
- 換服務器如何轉移網站
- block模板的分塊替換
- 模板包含文件
- 后臺打不開,空間不支持pathinfo的解決方法
- X1微信小程序的介紹
- 隱藏index.php的方法
- 新做風格路徑注意事項
- 添加公眾號模板消息
- 公眾號菜單跳轉到小程序
- 重復安裝應用導致重復執行的問題
- 如何配置定時任務
- 萬能通用短信接口的配置
- 小技巧
- 重新定義主題的星級名稱
- 如何增加VIP價格
- 如何恢復后臺超管權限
- 頻道二級域名的配置方法
- (頻道菜單)用戶組設置TAG標志的作用
- 如何給內容頁自定義個性模板
- 如何顯示新消息數目
- 啟用redis緩存,讓網站更快
- URL美化偽靜態設置方法
- 標簽緩存時間設置
- 自定義提交PHP相關危險關鍵字
- 如何對CMS等頻道內容進行數據分表進行文本儲值
- 兩個網站共用一個認證服務號
- 關注公眾號自動注冊帳號
- 如何重建模塊數據索引
- 任意頁面生成小程序碼或普通二維碼
- 列表及內容頁模板的優先級順序
- APP配置教程及簽名工具下載
- APP之QQ登錄配置
- 關于APP使用原生微信支付的說明
- 改版后的QQ登錄配置
- APP之QQ登錄接口關聯配置
- APP幾個重要接口在模板中的調用
- 直播及APP相關教程
- 如何上傳與編譯手機可安裝的文件
- app如何加模塊
- 如何靜默修復熱更新
- 如何獲取簽名
- 用SVN導出差異文件做熱修復
- 視頻直播接口設置
- 用第三方直播APP推流
- 如何配置圈子群聊直播APP
- 直播要設置回調地址才能播放
- 直播錄制為點播的配置
- 自建流媒體RTMP直播服務器
- 自建流媒體如何錄制視頻
- 如何錄制阿里等第三方直播流
- APP要實現直播的關鍵兩步
- 直播神器聊天小插件
- 直播相關視頻教程
- 第一集阿里云及騰訊接口配置
- 注意事項
- 如何取消某個標簽的緩存時間
- 商業模塊僅限一個國際域名使用
- 頁面報數據表錯誤如何修復
- 頁面不直接報錯,如何排查
- 如何取消禁止跨城市密碼登錄限制
- 非正常修改后臺入口admin.php導致的問題
- 服務器性能太差,調整系統升級每次校驗的文件數
- 如何開啟自定義標簽模板功能
- 客服系統顯示客戶在哪個頁面
- 給表單某個字段設置初始值
- 如果把萬能表單直接插入到內容中去
- 工單碎片模板制作教程
- 小程序與公眾號長期永久訂閱消息的申請方法
- 小程序集群微信開放平臺配置教程
- 關于小程序個性源代碼的說明
- 小程序風格模板設置
- 開通第三方平臺服務商組件
- 微信公眾號及小程序訂閱模板消息的配置
- 主題內容如何群發給圈子成員
- 如何限制圈子內搜索內容