Jelajahi Sumber

新增插件卸载时删除相关数据表功能

Karson 4 tahun lalu
induk
melakukan
260198e1cb

+ 24 - 0
application/admin/controller/Addon.php

@@ -8,6 +8,7 @@ use think\addons\AddonException;
 use think\addons\Service;
 use think\addons\Service;
 use think\Cache;
 use think\Cache;
 use think\Config;
 use think\Config;
+use think\Db;
 use think\Exception;
 use think\Exception;
 
 
 /**
 /**
@@ -19,6 +20,7 @@ use think\Exception;
 class Addon extends Backend
 class Addon extends Backend
 {
 {
     protected $model = null;
     protected $model = null;
+    protected $noNeedRight = ['get_table_list'];
 
 
     public function _initialize()
     public function _initialize()
     {
     {
@@ -144,14 +146,26 @@ class Addon extends Backend
     {
     {
         $name = $this->request->post("name");
         $name = $this->request->post("name");
         $force = (int)$this->request->post("force");
         $force = (int)$this->request->post("force");
+        $droptables = (int)$this->request->post("droptables");
         if (!$name) {
         if (!$name) {
             $this->error(__('Parameter %s can not be empty', 'name'));
             $this->error(__('Parameter %s can not be empty', 'name'));
         }
         }
         if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
         if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {
             $this->error(__('Addon name incorrect'));
             $this->error(__('Addon name incorrect'));
         }
         }
+        //只有开启调试且为超级管理员才允许删除相关数据库
+        $tables = [];
+        if ($droptables && Config::get("app_debug") && $this->auth->isSuperAdmin()) {
+            $tables = get_addon_tables($name);
+        }
         try {
         try {
             Service::uninstall($name, $force);
             Service::uninstall($name, $force);
+            if ($tables) {
+                //删除插件关联表
+                foreach ($tables as $index => $table) {
+                    Db::execute("DROP TABLE IF EXISTS `{$table}`");
+                }
+            }
             $this->success(__('Uninstall successful'));
             $this->success(__('Uninstall successful'));
         } catch (AddonException $e) {
         } catch (AddonException $e) {
             $this->result($e->getData(), $e->getCode(), __($e->getMessage()));
             $this->result($e->getData(), $e->getCode(), __($e->getMessage()));
@@ -367,4 +381,14 @@ class Addon extends Backend
         $callback = $this->request->get('callback') ? "jsonp" : "json";
         $callback = $this->request->get('callback') ? "jsonp" : "json";
         return $callback($result);
         return $callback($result);
     }
     }
+
+    /**
+     * 获取插件相关表
+     */
+    public function get_table_list()
+    {
+        $name = $this->request->post("name");
+        $tables = get_addon_tables($name);
+        $this->success('', null, ['tables' => $tables]);
+    }
 }
 }

+ 95 - 89
application/admin/lang/zh-cn/addon.php

@@ -1,93 +1,99 @@
 <?php
 <?php
 
 
 return [
 return [
-    'Id'                             => 'ID',
-    'Title'                          => '插件名称',
-    'Value'                          => '配置值',
-    'Array key'                      => '键',
-    'Array value'                    => '值',
-    'File'                           => '文件',
-    'Donate'                         => '打赏作者',
-    'Warmtips'                       => '温馨提示',
-    'Pay now'                        => '立即支付',
-    'Offline install'                => '离线安装',
-    'Refresh addon cache'            => '刷新插件缓存',
-    'Userinfo'                       => '会员信息',
-    'Online store'                   => '在线商店',
-    'Local addon'                    => '本地插件',
-    'Conflict tips'                  => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
-    'Login tips'                     => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
-    'Logined tips'                   => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
-    'Pay tips'                       => '扫码支付后如果仍然无法立即下载,请不要重复支付,请稍后再重试安装!',
-    'Pay click tips'                 => '请点击这里在新窗口中进行支付!',
-    'Pay new window tips'            => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
-    'Uninstall tips'                 => '确认卸载<b>[%s]</b>?<p class="text-danger">卸载将会删除所有插件文件且不可找回!!! 插件如果有创建数据库表请手动删除!!!</p>如有重要数据请备份后再操作!',
-    'Upgrade tips'                   => '确认升级<b>[%s]</b>?<p class="text-danger">升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
-    'Offline installed tips'         => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
-    'Online installed tips'          => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
-    'Not login tips'                 => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
-    'Not installed tips'             => '请安装后再访问插件前台页面!',
-    'Not enabled tips'               => '插件已经禁用,请启用后再访问插件前台页面!',
-    'New version tips'               => '发现新版本:%s 点击查看更新日志',
-    'Store now available tips'       => '插件市场暂不可用,是否切换到本地插件?',
-    'Switch to the local'            => '切换到本地插件',
-    'try to reload'                  => '重新尝试加载',
-    'Please disable addon first'     => '请先禁用插件再进行升级',
-    'Login now'                      => '立即登录',
-    'Continue install'               => '不登录,继续安装',
-    'View addon home page'           => '查看插件介绍和帮助',
-    'View addon index page'          => '查看插件前台首页',
-    'View addon screenshots'         => '点击查看插件截图',
-    'Click to toggle status'         => '点击切换插件状态',
-    'Click to contact developer'     => '点击与插件开发者取得联系',
-    'My addons'                      => '我购买的插件',
-    'My posts'                       => '我发布的插件',
-    'Index'                          => '前台',
-    'All'                            => '全部',
-    'Uncategoried'                   => '未归类',
-    'Recommend'                      => '推荐',
-    'Hot'                            => '热门',
-    'New'                            => '新',
-    'Paying'                         => '付费',
-    'Free'                           => '免费',
-    'Sale'                           => '折扣',
-    'No image'                       => '暂无缩略图',
-    'Price'                          => '价格',
-    'Downloads'                      => '下载',
-    'Author'                         => '作者',
-    'Identify'                       => '标识',
-    'Homepage'                       => '主页',
-    'Intro'                          => '介绍',
-    'Version'                        => '版本',
-    'New version'                    => '新版本',
-    'Createtime'                     => '添加时间',
-    'Releasetime'                    => '更新时间',
-    'Detail'                         => '插件详情',
-    'Document'                       => '文档',
-    'Demo'                           => '演示',
-    'Feedback'                       => '反馈BUG',
-    'Install'                        => '安装',
-    'Uninstall'                      => '卸载',
-    'Upgrade'                        => '升级',
-    'Setting'                        => '配置',
-    'Disable'                        => '禁用',
-    'Enable'                         => '启用',
-    'Your username or email'         => '你的手机号、用户名或邮箱',
-    'Your password'                  => '你的密码',
-    'Login FastAdmin'                => '登录',
-    'Login'                          => '登录',
-    'Logout'                         => '退出登录',
-    'Register'                       => '注册账号',
-    'You\'re not login'              => '当前未登录',
-    'Continue uninstall'             => '继续卸载',
-    'Continue operate'               => '继续操作',
-    'Install successful'             => '安装成功',
-    'Uninstall successful'           => '卸载成功',
-    'Operate successful'             => '操作成功',
-    'Addon name incorrect'           => '插件名称不正确',
-    'Addon info file was not found'  => '插件配置文件未找到',
-    'Addon info file data incorrect' => '插件配置信息不正确',
-    'Addon already exists'           => '上传的插件已经存在',
-    'Unable to open the zip file'    => '无法打开ZIP文件',
-    'Unable to extract the file'     => '无法解压ZIP文件',
+    'Id'                                                      => 'ID',
+    'Title'                                                   => '插件名称',
+    'Value'                                                   => '配置值',
+    'Array key'                                               => '键',
+    'Array value'                                             => '值',
+    'File'                                                    => '文件',
+    'Donate'                                                  => '打赏作者',
+    'Warmtips'                                                => '温馨提示',
+    'Pay now'                                                 => '立即支付',
+    'Offline install'                                         => '离线安装',
+    'Refresh addon cache'                                     => '刷新插件缓存',
+    'Userinfo'                                                => '会员信息',
+    'Online store'                                            => '在线商店',
+    'Local addon'                                             => '本地插件',
+    'Conflict tips'                                           => '此插件中发现和现有系统中部分文件发现冲突!以下文件将会被影响,请备份好相关文件后再继续操作',
+    'Login tips'                                              => '此处登录账号为<a href="https://www.fastadmin.net" target="_blank">FastAdmin官网账号</a>',
+    'Logined tips'                                            => '你好!%s<br />当前你已经登录,将同步保存你的购买记录',
+    'Pay tips'                                                => '扫码支付后如果仍然无法立即下载,请不要重复支付,请稍后再重试安装!',
+    'Pay click tips'                                          => '请点击这里在新窗口中进行支付!',
+    'Pay new window tips'                                     => '请在新弹出的窗口中进行支付,支付完成后再重新点击安装按钮进行安装!',
+    'Uninstall tips'                                          => '确认卸载<b>[%s]</b>?<p class="text-danger">卸载将会删除所有插件文件且不可找回!!! 插件如果有创建数据库表请手动删除!!!</p>如有重要数据请备份后再操作!',
+    'Upgrade tips'                                            => '确认升级<b>[%s]</b>?<p class="text-danger">升级后可能出现部分冗余数据记录,请根据需要移除即可!!!</p>如有重要数据请备份后再操作!',
+    'Offline installed tips'                                  => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
+    'Online installed tips'                                   => '插件安装成功!清除浏览器缓存和框架缓存后生效!',
+    'Not login tips'                                          => '你当前未登录FastAdmin,登录后将同步已购买的记录,下载时无需二次付费!',
+    'Not installed tips'                                      => '请安装后再访问插件前台页面!',
+    'Not enabled tips'                                        => '插件已经禁用,请启用后再访问插件前台页面!',
+    'New version tips'                                        => '发现新版本:%s 点击查看更新日志',
+    'Store now available tips'                                => '插件市场暂不可用,是否切换到本地插件?',
+    'Switch to the local'                                     => '切换到本地插件',
+    'try to reload'                                           => '重新尝试加载',
+    'Please disable addon first'                              => '请先禁用插件再进行升级',
+    'Login now'                                               => '立即登录',
+    'Continue install'                                        => '不登录,继续安装',
+    'View addon home page'                                    => '查看插件介绍和帮助',
+    'View addon index page'                                   => '查看插件前台首页',
+    'View addon screenshots'                                  => '点击查看插件截图',
+    'Click to toggle status'                                  => '点击切换插件状态',
+    'Click to contact developer'                              => '点击与插件开发者取得联系',
+    'My addons'                                               => '我购买的插件',
+    'My posts'                                                => '我发布的插件',
+    'Index'                                                   => '前台',
+    'All'                                                     => '全部',
+    'Uncategoried'                                            => '未归类',
+    'Recommend'                                               => '推荐',
+    'Hot'                                                     => '热门',
+    'New'                                                     => '新',
+    'Paying'                                                  => '付费',
+    'Free'                                                    => '免费',
+    'Sale'                                                    => '折扣',
+    'No image'                                                => '暂无缩略图',
+    'Price'                                                   => '价格',
+    'Downloads'                                               => '下载',
+    'Author'                                                  => '作者',
+    'Identify'                                                => '标识',
+    'Homepage'                                                => '主页',
+    'Intro'                                                   => '介绍',
+    'Version'                                                 => '版本',
+    'New version'                                             => '新版本',
+    'Createtime'                                              => '添加时间',
+    'Releasetime'                                             => '更新时间',
+    'Detail'                                                  => '插件详情',
+    'Document'                                                => '文档',
+    'Demo'                                                    => '演示',
+    'Feedback'                                                => '反馈BUG',
+    'Install'                                                 => '安装',
+    'Uninstall'                                               => '卸载',
+    'Upgrade'                                                 => '升级',
+    'Setting'                                                 => '配置',
+    'Disable'                                                 => '禁用',
+    'Enable'                                                  => '启用',
+    'Your username or email'                                  => '你的手机号、用户名或邮箱',
+    'Your password'                                           => '你的密码',
+    'Login FastAdmin'                                         => '登录',
+    'Login'                                                   => '登录',
+    'Logout'                                                  => '退出登录',
+    'Register'                                                => '注册账号',
+    'You\'re not login'                                       => '当前未登录',
+    'Continue uninstall'                                      => '继续卸载',
+    'Continue operate'                                        => '继续操作',
+    'Install successful'                                      => '安装成功',
+    'Uninstall successful'                                    => '卸载成功',
+    'Operate successful'                                      => '操作成功',
+    'Addon name incorrect'                                    => '插件名称不正确',
+    'Addon info file was not found'                           => '插件配置文件未找到',
+    'Addon info file data incorrect'                          => '插件配置信息不正确',
+    'Addon already exists'                                    => '上传的插件已经存在',
+    'Unable to open the zip file'                             => '无法打开ZIP文件',
+    'Unable to extract the file'                              => '无法解压ZIP文件',
+    'Are you sure you want to unstall %s?'                    => '确认卸载插件《%s》?',
+    'Delete all the addon file and cannot be recovered!'      => '卸载将会删除所有插件文件且不可找回!!!',
+    'Delete all the addon database and cannot be recovered!'  => '删除所有插件相关数据表且不可找回!!!',
+    'Please backup important data manually before uninstall!' => '如有重要数据请备份后再操作!!!',
+    'The following data tables will be deleted'               => '以下插件数据表将会被删除',
+    'The Addon did not create a data table'                   => '插件未创建任何数据表',
 ];
 ];

+ 17 - 4
application/admin/view/addon/index.html

@@ -53,11 +53,13 @@
         position: absolute;
         position: absolute;
         box-shadow: 0px 0px 2px #f11414;
         box-shadow: 0px 0px 2px #f11414;
     }
     }
+
     .form-userinfo .breadcrumb {
     .form-userinfo .breadcrumb {
-        margin-bottom:10px;
+        margin-bottom: 10px;
     }
     }
+
     .btn-toggle {
     .btn-toggle {
-        padding:0;
+        padding: 0;
     }
     }
 </style>
 </style>
 <div class="panel panel-default panel-intro">
 <div class="panel panel-default panel-intro">
@@ -170,8 +172,8 @@
                     <div class="col-lg-12">
                     <div class="col-lg-12">
                         <div class="input-group">
                         <div class="input-group">
                             <span class="input-group-addon"><i class="fa fa-lock"></i></span>
                             <span class="input-group-addon"><i class="fa fa-lock"></i></span>
-                        <input type="password" class="form-control" id="inputPassword" value=""
-                               placeholder="{:__('Your password')}">
+                            <input type="password" class="form-control" id="inputPassword" value=""
+                                   placeholder="{:__('Your password')}">
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
@@ -205,6 +207,17 @@
         <%}%>
         <%}%>
     </div>
     </div>
 </script>
 </script>
+<script id="uninstalltpl" type="text/html">
+    <div class="">
+        <div class=""><%=__("Are you sure you want to unstall %s?", addon['title'])%>
+            <p class="text-danger">{:__('Delete all the addon file and cannot be recovered!')} </p>
+            {if config('app_debug')}
+            <p class="text-danger"><input type="checkbox" name="droptables" id="droptables" data-name="<%=addon['name']%>"/> {:__('Delete all the addon database and cannot be recovered!')} </p>
+            {/if}
+            <p class="text-danger">{:__('Please backup important data manually before uninstall!')}</p>
+        </div>
+    </div>
+</script>
 <script id="conflicttpl" type="text/html">
 <script id="conflicttpl" type="text/html">
     <div class="alert alert-dismissable alert-danger">
     <div class="alert alert-dismissable alert-danger">
         <button type="button" class="close" data-dismiss="alert">×</button>
         <button type="button" class="close" data-dismiss="alert">×</button>

+ 26 - 5
public/assets/js/backend/addon.js

@@ -196,6 +196,26 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
                 table.bootstrapTable('refresh', {url: $(this).data("url"), pageNumber: 1});
                 table.bootstrapTable('refresh', {url: $(this).data("url"), pageNumber: 1});
                 return false;
                 return false;
             });
             });
+            var tables = [];
+            $(document).on("click", "#droptables", function () {
+                if ($(this).prop("checked")) {
+                    Fast.api.ajax({
+                        url: "addon/get_table_list",
+                        async: false,
+                        data: {name: $(this).data("name")}
+                    }, function (data) {
+                        tables = data.tables;
+                        return false;
+                    });
+                    var html;
+                    html = tables.length > 0 ? '<div class="alert alert-warning-light droptablestips" style="max-width:480px;max-height:300px;overflow-y: auto;">' + __('The following data tables will be deleted') + ':<br>' + tables.join("<br>") + '</div>'
+                        : '<div class="alert alert-warning-light droptablestips">' + __('The Addon did not create a data table') + '</div>';
+                    $(html).insertAfter($(this).closest("p"));
+                } else {
+                    $(".droptablestips").remove();
+                }
+                $(window).resize();
+            });
 
 
             // 会员信息
             // 会员信息
             $(document).on("click", ".btn-userinfo", function () {
             $(document).on("click", ".btn-userinfo", function () {
@@ -350,10 +370,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
                 });
                 });
             };
             };
 
 
-            var uninstall = function (name, force) {
+            var uninstall = function (name, force, droptables) {
                 Fast.api.ajax({
                 Fast.api.ajax({
                     url: 'addon/uninstall',
                     url: 'addon/uninstall',
-                    data: {name: name, force: force ? 1 : 0}
+                    data: {name: name, force: force ? 1 : 0, droptables: droptables ? 1 : 0}
                 }, function (data, ret) {
                 }, function (data, ret) {
                     delete Config['addons'][name];
                     delete Config['addons'][name];
                     Layer.closeAll();
                     Layer.closeAll();
@@ -372,7 +392,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
 
 
                             },
                             },
                             yes: function () {
                             yes: function () {
-                                uninstall(name, true);
+                                uninstall(name, true, droptables);
                             }
                             }
                         });
                         });
 
 
@@ -466,8 +486,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
                     Layer.alert(__('Please disable addon first'), {icon: 7});
                     Layer.alert(__('Please disable addon first'), {icon: 7});
                     return false;
                     return false;
                 }
                 }
-                Layer.confirm(__('Uninstall tips', Config['addons'][name].title), function () {
-                    uninstall(name, false);
+                Template.helper("__", __);
+                Layer.confirm(Template("uninstalltpl", {addon: Config['addons'][name]}), function (index, layero) {
+                    uninstall(name, false, $("input[name='droptables']", layero).prop("checked"));
                 });
                 });
             });
             });