فهرست منبع

Try one click Update / 尝试一键更新

star7th 4 سال پیش
والد
کامیت
e13104a30d

+ 215 - 14
server/Application/Api/Controller/AdminUpdateController.class.php

@@ -3,21 +3,222 @@ namespace Api\Controller;
 use Think\Controller;
 class AdminUpdateController extends BaseController {
 
-    // 下载更新代码包
-    // 未完成。此方式下载代码包不行
-    public function dowmload(){
-        return ;
-        set_time_limit(1200);
-        ignore_user_abort(1);
-        $url = 'https://github.com/star7th/showdoc/archive/master.tar.gz';
-        $file = './master.tar.gz';
-
-        $file_content = file_get_contents($url);
-        var_dump($file_content);
+    //检测showdoc版本更新
+    public function checkUpdate(){
+        //获取当前版本
+        $text = file_get_contents("../composer.json");
+        $composer = json_decode($text, true);
+        $version = $composer['version'] ;
+        $url = "https://www.showdoc.cc/server/api/open/checkUpdate";
+        $ch = curl_init();
+        $timeout = 2;
+        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
+        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+        curl_setopt ( $ch, CURLOPT_POST, true );
+        curl_setopt ( $ch, CURLOPT_POSTFIELDS, "version={$version}" );
+        curl_setopt($ch,CURLOPT_URL,$url);
+        $sContent = curl_exec($ch);
         curl_close($ch);
-        $downloaded_file = fopen($file, 'w');
-        fwrite($downloaded_file, $file_content);
-        fclose($downloaded_file);
+        echo $sContent  ;
+    }
+
+    // 下载更新代码包
+    public function download(){
+        set_time_limit(1000);
+        ini_set('memory_limit','500M');
+        $new_version = I("new_version") ;
+        $file_url = I("file_url") ;
+        $version_num = str_replace("v","",$new_version) ;
+
+        $showdoc_path = sys_get_temp_dir()."/showdoc/";
+
+        // 进行文件读写权限检查
+        if(!$this->new_is_writeable($showdoc_path)
+            || !$this->new_is_writeable($showdoc_path."Sqlite/" )
+            || !$this->new_is_writeable($showdoc_path."web/" )
+            || !$this->new_is_writeable($showdoc_path."web/index.php" )
+            || !$this->new_is_writeable($showdoc_path."server/" )
+            || !$this->new_is_writeable($showdoc_path."server/vendor/autoload.php" )
+            || !$this->new_is_writeable($showdoc_path."server/Application/Api" )
+        ){
+            $this->sendError(10101,'请手动给showdoc安装目录下的所有文件可写权限,否则程序无法覆盖旧文件');
+            return ;
+        }
+
+        $temp_dir = sys_get_temp_dir()."/showdoc_update/";
+        $zip_file = $temp_dir.'showdoc-'.$version_num.'.zip' ;
+        mkdir($temp_dir) ;
+        unlink($zip_file);
+        $file = file_get_contents($file_url);
+        file_put_contents($zip_file,$file);
+        
+        $zip = new \ZipArchive();
+        $flag = $zip->open($zip_file);
+        if($flag!==true){
+            $this->sendError(10101,'下载更新压缩包失败');
+            return ;
+        }
+        $zip->extractTo($temp_dir);
+        $flag = $zip->close();
+        
+        $zip_file_subpath = $temp_dir.'showdoc-'.$version_num."/" ;
+        
+        if(file_exists($zip_file_subpath.'composer.json') && file_exists($zip_file_subpath.'web/index.php') && file_exists($zip_file_subpath.'server/vendor/autoload.php') ){
+            //echo $zip_file_subpath.'存在';
+            // 移动目录到upload/update
+            $this->copydir($zip_file_subpath ,$showdoc_path.'Public/Uploads/update/' );
+            $this->deldir($temp_dir);
+            $this->sendResult(array());
+        
+        }else{
+            $this->sendError(10101,'下载更新压缩包后,解压的文件缺失');
+            return ;
+        }
+    }
+
+    // 执行升级操作,升级覆盖文件
+    public function updateFiles(){
+        set_time_limit(1000);
+        ini_set('memory_limit','500M');
+        
+        $showdoc_path = sys_get_temp_dir()."/showdoc/";
+        
+        // 进行文件读写权限检查
+        if(!$this->new_is_writeable($showdoc_path)
+            || !$this->new_is_writeable($showdoc_path."Sqlite/" )
+            || !$this->new_is_writeable($showdoc_path."web/" )
+            || !$this->new_is_writeable($showdoc_path."web/index.php" )
+            || !$this->new_is_writeable($showdoc_path."server/" )
+            || !$this->new_is_writeable($showdoc_path."server/vendor/autoload.php" )
+            || !$this->new_is_writeable($showdoc_path."server/Application/Api" )
+        ){
+            $this->sendError(10101,'请手动给showdoc安装目录下的所有文件可写权限,否则程序无法覆盖旧文件');
+            return ;
+        }
+
+        if(file_exists($showdoc_path.'Public/Uploads/update/composer.json') && file_exists($showdoc_path.'Public/Uploads/update/server/vendor/autoload.php') ){
+        
+                $text = file_get_contents($showdoc_path."composer.json");
+                $composer = json_decode($text, true);
+                $cur_version = $composer['version'] ;
+                $cur_version = str_replace("v","",$cur_version) ;
+        
+                $text = file_get_contents($showdoc_path."Public/Uploads/update/composer.json");
+                $composer = json_decode($text, true);
+                $update_version = $composer['version'] ;
+                $update_version = str_replace("v","",$update_version) ;
+        
+                if(version_compare($update_version,$cur_version) > 0 ){
+                    //复制数据库文件备份
+                    $bak_name = $showdoc_path.'Sqlite/showdoc.db.bak.'.date("Y-m-d-H-i-s").'.php';
+                    copy($showdoc_path.'Sqlite/showdoc.db.php', $bak_name);
+        
+                    // 目录覆盖
+                    $this->copydir($showdoc_path.'Public/Uploads/update/',$showdoc_path);
+                    // 用备份的数据库还原
+                    copy($bak_name, $showdoc_path.'Sqlite/showdoc.db.php' );
+        
+                    $this->deldir($showdoc_path.'Public/Uploads/update/') ;
+        
+                    // echo '升级成功!' ;
+                    $this->sendResult(array());
+        
+                }else{
+                    // echo '不需要升级';
+                    $this->sendError(10101,'版本号显示不需要升级');
+                }
+        }else{
+            $this->sendError(10101,'升级文件不存在');
+        }
+    }
+
+    /**
+     * 复制到目录
+    * $dirsrc  原目录
+    * $dirto  目标目录
+    *
+    */
+    private function copydir($dirsrc, $dirto) {
+        //如果原来的文件存在, 是不是一个目录
+
+        if(file_exists($dirto)) {
+            if(!is_dir($dirto)) {
+                echo "目标不是一个目录, 不能copy进去<br>";
+                exit;   
+            }
+        }else{
+            mkdir($dirto);
+        }
+
+
+        $dir = opendir($dirsrc);
+
+        while($filename = readdir($dir)) {
+            if($filename != "." && $filename !="..") {
+                $srcfile = $dirsrc."/".$filename;  //原文件
+                $tofile = $dirto."/".$filename;    //目标文件
+
+                if(is_dir($srcfile)) {
+                    $this->copydir($srcfile, $tofile);  //递归处理所有子目录
+                }else{
+                    copy($srcfile, $tofile);
+                }
+
+            }
+        }
+    }
+
+    // 删除文件夹及文件夹下所有的文件
+    private function deldir($dir) {
+        //先删除目录下的文件:
+        $dh = opendir($dir);
+        while ($file = readdir($dh)) {
+            if($file != "." && $file!="..") {
+            $fullpath = $dir."/".$file;
+            if(!is_dir($fullpath)) {
+                unlink($fullpath);
+            } else {
+                $this->deldir($fullpath);
+            }
+            }
+        }
+        closedir($dh);
+
+        //删除当前文件夹:
+        if(rmdir($dir)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * 判断 文件/目录 是否可写(取代系统自带的 is_writeable 函数)
+     *
+     * @param string $file 文件/目录
+     * @return boolean
+     */
+    private function new_is_writeable($file) {
+        if (is_dir($file)){
+        $dir = $file;
+        if ($fp = @fopen("$dir/test.txt", 'w')) {
+            @fclose($fp);
+            @unlink("$dir/test.txt");
+            $writeable = 1;
+        } else {
+            $writeable = 0;
+        }
+        } else {
+        if ($fp = @fopen($file, 'a+')) {
+            @fclose($fp);
+            $writeable = 1;
+        } else {
+            $writeable = 0;
+        }
+        }
+    
+        return $writeable;
     }
 
 }

+ 1 - 18
server/Application/Api/Controller/AdminUserController.class.php

@@ -108,23 +108,6 @@ class AdminUserController extends BaseController {
 
     }
 
-    //检测showdoc版本更新
-    public function checkUpdate(){
-        //获取当前版本
-        $text = file_get_contents("../composer.json");
-        $composer = json_decode($text, true);
-        $version = $composer['version'] ;
-        $url = "https://www.showdoc.cc/server/api/open/checkUpdate";
-        $ch = curl_init();
-        $timeout = 2;
-        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
-        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
-        curl_setopt ( $ch, CURLOPT_POST, true );
-        curl_setopt ( $ch, CURLOPT_POSTFIELDS, "version={$version}" );
-        curl_setopt($ch,CURLOPT_URL,$url);
-        $sContent = curl_exec($ch);
-        curl_close($ch);
-        echo $sContent  ;
-    }
+
 
 }

+ 1 - 1
web/index.html

@@ -16,4 +16,4 @@
       "server": window.location.protocol +'//'+ window.location.host + window.location.pathname+ '../server/index.php?s=',
       //"lang" :'en'
       "lang" :'zh-cn'
-  }</script><link href=./static/css/app.f4bb312ff035546ab76b6f80a8b3937d.css rel=stylesheet></head><body class=grey-bg><div id=app></div><div style=display:none>本网站基于开源版showdoc搭建,仅供私人使用。如需访问showdoc官网,请在搜索引擎里搜索showdoc字样或者直接访问showdoc.com.cn</div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.1eb6213d11eb61d1bd46.js></script><script type=text/javascript src=./static/js/app.6cdcf8cc77eba45c5b2b.js></script></body></html>
+  }</script><link href=./static/css/app.bc7c08fc4b7b7ee670032d4cc4ce18f1.css rel=stylesheet></head><body class=grey-bg><div id=app></div><div style=display:none>本网站基于开源版showdoc搭建,仅供私人使用。如需访问showdoc官网,请在搜索引擎里搜索showdoc字样或者直接访问showdoc.com.cn</div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.1eb6213d11eb61d1bd46.js></script><script type=text/javascript src=./static/js/app.88a06f676c877b74727f.js></script></body></html>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
web/static/css/app.bc7c08fc4b7b7ee670032d4cc4ce18f1.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
web/static/js/app.6cdcf8cc77eba45c5b2b.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
web/static/js/app.88a06f676c877b74727f.js


+ 8 - 22
web_src/src/components/admin/Index.vue

@@ -159,33 +159,19 @@ export default {
       })
     },
     check_upadte() {
-      var that = this
-      var url = DocConfig.server + '/api/adminUser/checkUpdate'
-      var params = new URLSearchParams()
-      that.axios.post(url, params).then(function(response) {
-        if (
-          response &&
-          response.data &&
-          response.data.data &&
-          response.data.data.url
-        ) {
-          that.$message({
-            showClose: true,
-            duration: 10000,
-            dangerouslyUseHTMLString: true,
-            message:
-              '<a target="_blank" href="' +
-              response.data.data.url +
-              '">' +
-              response.data.data.title +
-              '</a>'
-          })
+      this.request('/api/adminUpdate/checkUpdate', {}).then(data => {
+        if (data && data.data && data.data.url) {
+          this.isUpdate = true
         }
       })
     }
   },
   mounted() {
-    this.check_upadte()
+    // 只对中文版进行更新检查
+    if (DocConfig.lang == 'zh-cn') {
+      this.check_upadte()
+    }
+
     this.unset_bg_grey()
   },
   beforeDestroy() {

+ 74 - 5
web_src/src/components/admin/systemUpdate/Index.vue

@@ -1,19 +1,88 @@
 <template>
-  <div class="hello"></div>
+  <div class="">
+    <div>
+      <br />
+      你当前使用的版本是<b>{{ cur_version }}</b
+      >,showdoc最新版本是<b>{{ new_version }}</b>
+      <br />
+      <br />
+      <el-button type="primary" @click="clickToUpdate">点此更新</el-button>
+    </div>
+    <br />
+    <div>
+      如点击上面按钮更新失败,<a
+        href="https://www.showdoc.com.cn/help?page_id=13732"
+        target="_blank"
+        >点击这里</a
+      >参考文档进行手动升级
+    </div>
+  </div>
 </template>
 
 <style scoped></style>
 
 <script>
-import axios from 'axios'
 export default {
   data() {
     return {
-      new: false
+      isUpdate: false,
+      cur_version: '',
+      new_version: '',
+      url: '',
+      file_url: ''
     }
   },
-  methods: {},
-  mounted() {},
+  methods: {
+    check_upadte() {
+      this.request('/api/adminUpdate/checkUpdate', {}).then(data => {
+        if (data && data.data && data.data.url) {
+          this.url = data.data.url
+          this.file_url = data.data.file_url
+          this.new_version = data.data.new_version
+          this.cur_version = data.data.version
+        }
+      })
+    },
+    clickToUpdate() {
+      let loading = this.$loading({
+        text: '正在下载更新包...'
+      })
+      this.request('/api/adminUpdate/download', {
+        new_version: this.new_version,
+        file_url: this.file_url
+      }).then(
+        data => {
+          loading.close()
+          loading = this.$loading({
+            text: '正在更新文件...'
+          })
+          this.request('/api/adminUpdate/updateFiles', {}).then(
+            () => {
+              loading.close()
+              loading = this.$loading({
+                text:
+                  '升级文件成功,准备刷新页面...如果页面缓存迟迟不能自动更新,请手动刷新页面以更新浏览器缓存'
+              })
+              this.request('/api/update/checkDb')
+              // this.axios.get('./')
+              setTimeout(() => {
+                window.location.reload()
+              }, 7000)
+            },
+            () => {
+              loading.close()
+            }
+          )
+        },
+        () => {
+          loading.close()
+        }
+      )
+    }
+  },
+  mounted() {
+    this.check_upadte()
+  },
   beforeDestroy() {}
 }
 </script>

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است