-
Notifications
You must be signed in to change notification settings - Fork 19
/
FEBS-Cloud项目使用教程.html
1 lines (1 loc) · 69.6 KB
/
FEBS-Cloud项目使用教程.html
1
<!-- build time:Wed Mar 09 2022 10:17:47 GMT+0800 (GMT+08:00) --><!doctype html><html class="theme-next mist" lang="zh-Hans"><head><meta name="generator" content="Hexo 3.8.0"><meta name="google-site-verification" content="7Tau9WyVgxnsEY9oYedu9g0U6_8akOX3wiKbaYcrg9A"><meta name="baidu-site-verification" content="EVwLiaxdxX"><link href="/css/xps13.css" rel="stylesheet" type="text/css"><link href="/css/message.css" rel="stylesheet" type="text/css"><link href="//fonts.googleapis.com/css?family=Baloo+Bhaijaan|Inconsolata|Josefin+Sans|Montserrat" rel="stylesheet"><script type="text/javascript" src="/js/jquery-1.11.3.min.js"></script><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css"><link href="/css/main.css?v=5.1.1" rel="stylesheet" type="text/css"><meta name="keywords" content="FEBS,Spring Cloud,"><link rel="alternate" href="/atom.xml" title="MrBird" type="application/atom+xml"><link rel="shortcut icon" type="image/x-icon" href="/bird.png?v=5.1.1"><meta name="keywords" content="FEBS,Spring Cloud"><meta property="og:type" content="article"><meta property="og:title" content="FEBS Cloud项目使用教程"><meta property="og:url" content="http://mrbird.cc/FEBS-Cloud项目使用教程.html"><meta property="og:site_name" content="MrBird"><meta property="og:locale" content="zh-Hans"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnkPIS.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nncYee.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnMrAs.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnGF0O.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnG2g1.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nncvSx.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnge6f.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nng2nO.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnWoC9.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/05/nnfIZ8.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQXfcq.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQjZKP.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQxFXt.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQxeAS.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQxNh4.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQxIDP.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQxjvn.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nQzeDx.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nlSnQs.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/nlSj00.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1YG0s.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1YjgS.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1t8gO.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1NFZd.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1NyJx.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1NoFI.gif"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lq9Kn1.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1UUht.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1aMUs.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JeXrUU.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JejkMn.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JejeaT.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JejaJe.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JejqFU.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JevCTK.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JevGlj.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jeva7V.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JevfAK.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jex9js.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JexV4U.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jexs58.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1y4vn.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n16DG4.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1c9Qs.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jex3E6.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1cTtU.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1cv0x.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1gkjA.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1gnN8.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1gQ3Q.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqeZad.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqe3qg.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqe2J1.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqmG6K.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqnSc6.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqnANd.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqnfbD.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqKASI.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqKWAe.gif"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqMtgI.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqMaKP.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqQCRA.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqQydO.png"><meta property="og:image" content="https://s2.ax1x.com/2020/01/14/lqlOAO.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JeztoV.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jez4QH.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JezvlQ.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JmSJ6H.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JmpAEt.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jmp8U0.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jmp2xe.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/JmpIat.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jm99iV.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jm9QzD.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jm9BQg.png"><meta property="og:image" content="https://s1.ax1x.com/2020/04/18/Jm9vlD.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1gWCD.png"><meta property="og:image" content="https://s2.ax1x.com/2019/09/07/n1gOPS.gif"><meta property="og:updated_time" content="2022-02-23T03:45:59.891Z"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="FEBS Cloud项目使用教程"><meta name="twitter:image" content="https://s2.ax1x.com/2019/09/05/nnkPIS.png"><script type="text/javascript" id="hexo.configurations">var NexT=window.NexT||{},CONFIG={root:"/",scheme:"Mist",sidebar:{position:"left",display:"always",offset:12,offset_float:0,b2t:!1,scrollpercent:!0},fancybox:!1,motion:!1}</script><title>FEBS Cloud项目使用教程 | MrBird</title></head><body ondragstart="return!1" class="animsition" lang="zh-Hans" style="overflow-x:hidden;padding-left:280px"><script type="text/javascript" src="/js/mo.min.js"></script><style>body{text-rendering:geometricPrecision!important;font-family:'Josefin Sans','PingFang SC'!important;-webkit-font-smoothing:antialiased!important;-webkit-text-size-adjust:100%!important;background-color:#f4f6f7}@media (min-width:768px) and (max-width:991px){body .header-innerr{width:700px!important}}.header-innerr{margin:0 auto;padding:100px 0 70px;width:880px}@media (min-width:1600px){.container .header-innerr{width:996px}}.header-innerr{position:relative}.header-innerr{padding:0}.header-innerr:after,.header-innerr:before{content:" ";display:table}.header-innerr:after{clear:both}@media (max-width:767px){.header-innerr{width:auto;padding:10px;margin-bottom:-20px}}</style><div class="container sidebar-position-left page-post-detail"><div class="headband"></div><header id="header" class="header"><div class="header-inner"><div class="site-brand-wrapper"><div class="site-meta"><link href="https://fonts.font.im/css?family=Merienda" rel="stylesheet"><div class="custom-logo-site-title"></div><h1 class="site-subtitle" itemprop="description"></h1></div><div class="site-nav-toggle"><button><span class="btn-bar"></span> <span class="btn-bar"></span> <span class="btn-bar"></span></button></div></div><nav class="site-nav"><div class="site-search"><div class="popup search-popup local-search-popup"><div class="local-search-header clearfix"><span class="search-icon"><i class="fa fa-search"></i> </span><span class="popup-btn-close"><i class="fa fa-times-circle"></i></span><div class="local-search-input-wrapper"><input autocomplete="off" placeholder="Search" spellcheck="false" type="text" id="local-search-input"></div></div><div id="local-search-result"></div></div></div></nav></div><div class="header-innerr"></div></header><main id="main" class="main"><div class="main-inner"><div class="content-wrap"><div id="content" class="content"><div id="posts" class="posts-expand"><article class="post post-type-normal" itemscope itemtype="http://schema.org/Article"><link itemprop="mainEntityOfPage" href="http://mrbird.cc/FEBS-Cloud项目使用教程.html"><span hidden itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="name" content="MrBird"><meta itemprop="description" content=""><meta itemprop="image" content="/images/blogImage.jpg"></span><span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="MrBird"></span><header class="post-header"><h2 class="post-title" itemprop="name headline">FEBS Cloud项目使用教程</h2><div class="post-meta"><span class="post-time"><span class="post-meta-item-icon"><i class="fa fa-calendar-o"></i> </span><span class="post-meta-item-text"></span> <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-01-03T11:31:48+08:00">2020-01-03 </time></span><span></span> <span class="post-meta-divider">|</span> <span class="page-pv"><i class="fa fa-laptop"></i> Visit count <span class="busuanzi-value" id="busuanzi_value_page_pv"></span></span></div></header><div class="post-body" itemprop="articleBody"><a id="more"></a><h2 id="系统管理"><a href="#系统管理" class="headerlink" title="系统管理"></a>系统管理</h2><h3 id="角色管理"><a href="#角色管理" class="headerlink" title="角色管理"></a>角色管理</h3><h4 id="新增角色"><a href="#新增角色" class="headerlink" title="新增角色"></a>新增角色</h4><p>点击角色管理菜单,页面右侧区域为新增角色区域:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnkPIS.png" alt="230.png"></p><p>可以看到新增角色需要填写“角色名称”,“角色描述”和“角色权限”。其中角色权限需要勾选菜单树。</p><p>比如,我现在需要新增一个“系统监控员”(就是拥有系统监控模块下所有页面及按钮的功能),那么我们需要填写角色名称为“系统监控员”,并且勾选菜单树“系统监控”模块下的所有菜单及按钮:</p><p><img src="https://s2.ax1x.com/2019/09/05/nncYee.png" alt="231.png"></p><p>最后点击新增按钮即可。</p><p>菜单树并没有设置为父子关联的模式,虽然父子关联在操作上会更方便,但在某些业务场景下是行不通的。以“登录日志”菜单为例,如果我想分配一个角色具有查看登录日志的权限,但不能删除日志和导出日志,那么我们只需要勾选系统监控和登录日志模块即可。假如设置了父子关联,一旦我们勾选了登录日志模块,那么它下面的按钮“删除日志”和“导出Excel”也会被勾选,无法满足我们的需求。</p><h4 id="修改角色"><a href="#修改角色" class="headerlink" title="修改角色"></a>修改角色</h4><p>点击页面表格操作区域的“齿轮”按钮,页面右侧会显示对应的角色信息:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnMrAs.png" alt="232.png"></p><p>在右侧区域修改相应内容后,点击“更新”按钮即可。</p><h4 id="删除角色"><a href="#删除角色" class="headerlink" title="删除角色"></a>删除角色</h4><p>您可以点击表格操作区域的“垃圾桶”来删除对应的角色,也可以勾选表格的多选框,然后点击删除按钮(在更多操作下拉选中)来一次性删除多个角色。</p><p>注意,删除角色后,对应的用户将会丧失相应的权限。</p><h3 id="用户管理"><a href="#用户管理" class="headerlink" title="用户管理"></a>用户管理</h3><h4 id="新增用户"><a href="#新增用户" class="headerlink" title="新增用户"></a>新增用户</h4><p>点击用户管理菜单,在“更多操作”下拉选中,包含“添加”按钮:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnGF0O.png" alt="233.png"></p><p>点击该按钮弹出新增用户界面:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnG2g1.png" alt="234.png"></p><p>填写相应的用户信息,角色可以选择我们刚刚创建的“系统监控员”(一个用户可以拥有多个角色)。</p><p>点击“确定”按钮新增用户,用户默认密码为1234qwer。使用该用户登录系统,因为他的角色为“系统监控员”,所以它理所应当只拥有系统监控模块的菜单权限:</p><p><img src="https://s2.ax1x.com/2019/09/05/nncvSx.png" alt="235.png"></p><h4 id="修改用户"><a href="#修改用户" class="headerlink" title="修改用户"></a>修改用户</h4><p>在用户管理界面的表格操作区域,点击“齿轮”按钮,可以修改相应用户:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnge6f.png" alt="236.png"></p><p><img src="https://s2.ax1x.com/2019/09/05/nng2nO.png" alt="237.png"></p><p>除了用户名和密码不能修改外,其他内容都可修改。</p><h4 id="删除用户"><a href="#删除用户" class="headerlink" title="删除用户"></a>删除用户</h4><p>您可以点击用户列表操作栏的“垃圾桶”图标,删除对应的用户,也可以勾选多个用户,然后点击“更多操作”下拉选中的“删除”按钮,一次性删除多个用户。假如待删除用户包含当前用户,系统将会拒绝:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnWoC9.png" alt="238.png"></p><h4 id="密码重置"><a href="#密码重置" class="headerlink" title="密码重置"></a>密码重置</h4><p>假如有用户忘记了登录密码,您可以通过密码重置功能重置他的登录密码。</p><p>在用户管理模块中,选中需要重置密码的用户,然后点击“更多操作”下拉选中的“密码重置”按钮,将其登录密码重置为1234qwer:</p><p><img src="https://s2.ax1x.com/2019/09/05/nnfIZ8.png" alt="239.png"></p><h3 id="菜单管理"><a href="#菜单管理" class="headerlink" title="菜单管理"></a>菜单管理</h3><h4 id="菜单结构介绍"><a href="#菜单结构介绍" class="headerlink" title="菜单结构介绍"></a>菜单结构介绍</h4><p>菜单管理页面可以对系统菜单和按钮进行统一管理。菜单可以拥有层级结构,一个菜单可以作为另一个菜单的上级,但按钮不能作为菜单的上级(虽然系统没有进行限制,但选择按钮作为上级毫无意义)。</p><h4 id="新增菜单"><a href="#新增菜单" class="headerlink" title="新增菜单"></a>新增菜单</h4><p>菜单管理页面右侧为菜单新增区域:</p><p><img src="https://s2.ax1x.com/2019/09/07/nQXfcq.png" alt="240.png"></p><p>其中URL对应浏览器地址栏的URL,组件对应前端系统的Vue组件,权限用于后台系统接口控制。</p><p>比如,我们在系统管理下新增一个菜单:</p><ol><li>勾选左侧菜单树上系统管理,然后点击“更多操作”下拉选中的新增按钮(逻辑已经修改为树形下来选,请知悉):</li></ol><p><img src="https://s2.ax1x.com/2019/09/07/nQjZKP.png" alt="241.png"></p><p>可以看到,“上级ID”输入框的值自动赋值为所勾选菜单的ID,表示以该菜单为上级创建新的菜单。</p><ol start="2"><li>然后填写如下内容,并点击“新增按钮新增”:</li></ol><p><img src="https://s2.ax1x.com/2019/09/07/nQxFXt.png" alt="242.png"></p><p>点击新增后,左侧菜单树已经出现了刚刚新增的菜单:</p><p><img src="https://s2.ax1x.com/2019/09/07/nQxeAS.png" alt="243.png"></p><p>但是你会发现,系统左侧菜单栏中并没有出现该菜单,这是因为我们还没有给角色授权。点击角色管理,然后编辑“管理员”角色,在右侧的权限树中,勾选上刚刚新增的菜单:</p><p><img src="https://s2.ax1x.com/2019/09/07/nQxNh4.png" alt="244.png"></p><p>点击更新后,拥有管理员角色的用户就拥有了该菜单权限。权限更新生效需要重新登录系统,或者可以点击“清除缓存”按钮来刷新缓存:</p><p><img src="https://s2.ax1x.com/2019/09/07/nQxIDP.png" alt="245.png"></p><p>点击后,可以看到菜单栏已经出现了刚刚新增的菜单:</p><p><img src="https://s2.ax1x.com/2019/09/07/nQxjvn.png" alt="246.png"></p><p>但是,点击该菜单后,控制台报错了:</p><p><img src="https://s2.ax1x.com/2019/09/07/nQzeDx.png" alt="247.png"></p><p>这是因为我刚刚新增菜单的时候指定组件地址为<code>febs/system/test/Index</code>,但我们并没有在前端项目里创建该组件。</p><p>在前端系统的src/views/febs/system路径下新建test目录,然后在该目录下新建Index.vue:</p><p><img src="https://s2.ax1x.com/2019/09/07/nlSnQs.png" alt="248.png"></p><p>我们在Index.vue里编写了一些简单的Vue代码,代码如下所示:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"app-container"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"message"</span>></span>{{ hello }}<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">template</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="keyword">export</span> <span class="keyword">default</span> {</span></span><br><span class="line"><span class="undefined"> data() {</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> {</span></span><br><span class="line"><span class="javascript"> hello: <span class="string">'hello world'</span></span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined">}</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"><<span class="name">style</span> <span class="attr">scoped</span>></span><span class="undefined"></span></span><br><span class="line"><span class="css"> <span class="selector-id">#message</span> {</span></span><br><span class="line"><span class="undefined"> font-size: 1rem;</span></span><br><span class="line"><span class="undefined"> font-weight: 600;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">color</span>: <span class="selector-id">#42b983</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">style</span>></span></span><br></pre></td></tr></table></figure><p></p><p>回到系统页面,再次点击测试菜单后,页面就会渲染出我们刚刚新增的组件:</p><p><img src="https://s2.ax1x.com/2019/09/07/nlSj00.png" alt="249.png"></p><h4 id="新增多级菜单"><a href="#新增多级菜单" class="headerlink" title="新增多级菜单"></a>新增多级菜单</h4><p>菜单可以拥有层级结构。一级菜单(如现有的“系统管理”、“系统监控”等)的组件栏固定填写为<strong>Layout</strong>;二级菜单为末级菜单的话,组件栏填写前端系统定义的组件地址;如果二级菜单还有下级菜单的话,那么它就是一个中间菜单。下面演示如何新建一个三级菜单(更多层级以此类推即可,您也可以参考vue element admin的文档:<a href="https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/new-page.html#%E5%A4%9A%E7%BA%A7%E7%9B%AE%E5%BD%95-%E5%B5%8C%E5%A5%97%E8%B7%AF%E7%94%B1" target="_blank" rel="noopener">多级目录</a>)。</p><p>勾选系统管理菜单,点击“更多操作”下拉选中的“新增按钮”,然后在右侧区域填写如下内容:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1YG0s.png" alt="250.png"></p><p>接着在前端项目的src/views/febs/system下新增one目录,然后在该目录下新建Index.vue,代码如下所示:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">router-view</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">template</span>></span></span><br></pre></td></tr></table></figure><p></p><p>因为它是一个中间菜单,所以只要编写一个<code><router-view/></code>即可。</p><p>创建完该菜单后,我们继续创建第三级菜单,勾选刚刚创建的“测试菜单1”,点击“更多操作”下拉选中的“新增按钮”,然后在右侧区域填写如下内容:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1YjgS.png" alt="251.png"></p><p>创建完该菜单后,接着继续在src/views/febs/system/one下新增two目录,然后在该目录下新建Index.vue,代码如下所示:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"app-container"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"message"</span>></span>{{ hello }}<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">template</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="keyword">export</span> <span class="keyword">default</span> {</span></span><br><span class="line"><span class="undefined"> data() {</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> {</span></span><br><span class="line"><span class="javascript"> hello: <span class="string">'hello world'</span></span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined">}</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"><<span class="name">style</span> <span class="attr">scoped</span>></span><span class="undefined"></span></span><br><span class="line"><span class="css"> <span class="selector-id">#message</span> {</span></span><br><span class="line"><span class="undefined"> font-size: 1rem;</span></span><br><span class="line"><span class="undefined"> font-weight: 600;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">color</span>: <span class="selector-id">#42b983</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">style</span>></span></span><br></pre></td></tr></table></figure><p></p><p>至此,三级菜单创建完毕,给角色授权并清除缓存后,系统菜单栏效果如下所示:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1t8gO.png" alt="252.png"></p><h4 id="新增按钮"><a href="#新增按钮" class="headerlink" title="新增按钮"></a>新增按钮</h4><p>新增按钮和新增菜单操作一致,只需要将类型选为按钮即可。比如在上面创建的测试菜单下新建一个“新增文章”按钮:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1NFZd.png" alt="253.png"></p><blockquote><p>新增按钮后,并不是说页面上就会自动出现该按钮了,这里按钮的作用为权限分配。</p></blockquote><h4 id="修改菜单-按钮"><a href="#修改菜单-按钮" class="headerlink" title="修改菜单/按钮"></a>修改菜单/按钮</h4><p>修改菜单或者按钮,只需要点击菜单树中对应的菜单或者按钮(不是勾选)即可,比如我要修改测试菜单的相关信息:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1NyJx.png" alt="254.png"></p><h4 id="删除菜单-按钮"><a href="#删除菜单-按钮" class="headerlink" title="删除菜单/按钮"></a>删除菜单/按钮</h4><p>勾选需要删除的菜单或者按钮,然后点击“更多操作”下拉选中的“删除按钮就可”:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1NoFI.gif" alt="255.gif"></p><p>如果勾选的模块含有下级的话,下级也会一并被删除。</p><h3 id="部门管理"><a href="#部门管理" class="headerlink" title="部门管理"></a>部门管理</h3><p>部门也拥有层级结构,操作大致和菜单一致,所以不再做过多操作介绍。</p><p>部门在本系统中可以用于控制数据权限,后续会介绍到。</p><h3 id="客户端管理"><a href="#客户端管理" class="headerlink" title="客户端管理"></a>客户端管理</h3><p>客户端接入系统需要配置相应的client_id和client_secret,这个模块就是用于管理client的。不同的client可以配置不同的授权模式,不同时长的令牌有效期等。该模块通过数据库和Redis实现client的存储及缓存实时更新:</p><p><img src="https://s2.ax1x.com/2020/01/14/lq9Kn1.png" alt="711.png"></p><h2 id="系统监控"><a href="#系统监控" class="headerlink" title="系统监控"></a>系统监控</h2><h3 id="系统日志"><a href="#系统日志" class="headerlink" title="系统日志"></a>系统日志</h3><p>系统日志模块如下所示:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1UUht.png" alt="256.png"></p><p>该模块用于记录用户操作日志(即访问了什么资源,参数是什么,方法耗时之类的信息),通过后端系统中的<code>@ControllerEndpoint</code>注解实现,具体介绍可参考开发教程的自定义注解介绍一节。</p><h3 id="登录日志"><a href="#登录日志" class="headerlink" title="登录日志"></a>登录日志</h3><p>登录日志模块如下所示:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1aMUs.png" alt="257.png"></p><p>该模块用于记录用户登录系统日志,比如登录用户名,登录的系统,浏览器版本,IP地址,登录地点和登录时间等信息。其中,登录地点使用<a href="https://github.com/lionsoul2014/ip2region" target="_blank" rel="noopener">ip2region</a>实现。</p><h3 id="监控面板"><a href="#监控面板" class="headerlink" title="监控面板"></a>监控面板</h3><p>监控面板聚合了各种监控面板页面,具体包括:</p><ol><li>Nacos控制台面板:</li></ol><p><a href="https://imgchr.com/i/JeXrUU" target="_blank" rel="noopener"><img src="https://s1.ax1x.com/2020/04/18/JeXrUU.png" alt="JeXrUU.png"></a></p><ol start="2"><li>ELK面板</li></ol><p>ELK用于集中收集微服务日志,搭建教程可以参考:<a href="https://www.kancloud.cn/mrbird/spring-cloud/1263715" target="_blank" rel="noopener">https://www.kancloud.cn/mrbird/spring-cloud/1263715</a>。</p><ol start="3"><li>SkyWalking面板</li></ol><p><a href="http://skywalking.apache.org/" target="_blank" rel="noopener">Skywalking</a>是由国人吴晟开发的一款分布式追踪软件,后面成功孵化为Apache的顶级项目。Skywalking主要包括了分布式追踪、性能指标分析、应用和服务依赖分析等功能:</p><p><img src="https://s1.ax1x.com/2020/04/18/JejkMn.png" alt="JejkMn.png"> <img src="https://s1.ax1x.com/2020/04/18/JejeaT.png" alt="JejeaT.png"> <img src="https://s1.ax1x.com/2020/04/18/JejaJe.png" alt="JejaJe.png"></p><p>搭建教程可以参考:<a href="https://www.kancloud.cn/mrbird/spring-cloud/1337996" target="_blank" rel="noopener">https://www.kancloud.cn/mrbird/spring-cloud/1337996</a>。</p><ol start="4"><li>Grafana面板</li></ol><p>多维度监控微服务的可视化平台,包括Docker容器监控、MySQL监控、Redis监控和微服务JVM监控等,并且在必要的情况下可以发送预警邮件:</p><p>Docker容器监控: <img src="https://s1.ax1x.com/2020/04/18/JejqFU.png" alt="JejqFU.png"></p><p>微服务JVM监控: <img src="https://s1.ax1x.com/2020/04/18/JevCTK.png" alt="JevCTK.png"></p><p>MySQL数据库监控: <img src="https://s1.ax1x.com/2020/04/18/JevGlj.png" alt="JevGlj.png"></p><p>Redis监控: <img src="https://s1.ax1x.com/2020/04/18/Jeva7V.png" alt="Jeva7V.png"></p><p>具体搭建过程可以参考:<a href="https://www.kancloud.cn/mrbird/spring-cloud/1333138" target="_blank" rel="noopener">https://www.kancloud.cn/mrbird/spring-cloud/1333138</a>。</p><ol start="5"><li>微服务接口文档</li></ol><p>基于knife4j,聚合了所有微服务子模块的API接口:</p><p><img src="https://s1.ax1x.com/2020/04/18/JevfAK.png" alt="JevfAK.png"></p><p>具体使用参考开发教程。</p><ol start="6"><li>Admin面板</li></ol><p>基于Spring Boot Admin的服务监控面板:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jex9js.png" alt="Jex9js.png"></p><ol start="7"><li>TX面板</li></ol><p>分布式事务控制面板: <img src="https://s1.ax1x.com/2020/04/18/JexV4U.png" alt="JexV4U.png"></p><h2 id="代码生成"><a href="#代码生成" class="headerlink" title="代码生成"></a>代码生成</h2><h3 id="生成配置"><a href="#生成配置" class="headerlink" title="生成配置"></a>生成配置</h3><p>要使用代码生成功能,需要先启动febs-server-generator微服务:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jexs58.png" alt="Jexs58.png"></p><p>生成配置模块用于修改代码生成相关配置:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1y4vn.png" alt="270.png"></p><p>可修改的配置有:</p><ol><li>作者名称,对应Java类上@author的值;</li><li>基础包名,即生成的包和代码位于哪个路径下面;</li><li>entity包名,即实体类的包名;</li><li>mapper包名,即Dao层接口的包名;</li><li>mapperXml包名,即Mybatis XML文件的包名;</li><li>service包名,即Service接口的包名;</li><li>serviceImpl包名,即Service接口实现类的包名;</li><li>controller包名,即Controller层的包名;</li><li>是否去除表前缀,用于控制在生成Java类名的时候是否去除表前缀;</li><li>表前缀,指定去除的表前缀。</li></ol><p>就“是否去除表前缀”,这里举个例子:比如您的库表名称为TBL_USER,如果不去除表前缀,生成的实体类名称为TblUser;如果选择去除表前缀,并且指定表前缀内容为<code>TBL</code>的话,生成的实体类名称为User。</p><h3 id="生成代码"><a href="#生成代码" class="headerlink" title="生成代码"></a>生成代码</h3><p>该模块用于生成后端代码:</p><p><img src="https://s2.ax1x.com/2019/09/07/n16DG4.png" alt="271.png"></p><p>点击表格操作区域的下载图标,即可根据前面配置的内容生成该表对应的实体类,Dao接口,Service接口,Service接口实现类,Controller等代码。</p><p>比如点击t_user表格的代码,生成后如下所示:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1c9Qs.png" alt="272.png"></p><p>代码生成通过freemarker实现,您可以根据自己的需求修改文件模板。文件模板位于febs-server-generator微服务:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jex3E6.png" alt="Jex3E6.png"></p><p>其实代码生成的本质就是模板变量填充。</p><h2 id="其他模块"><a href="#其他模块" class="headerlink" title="其他模块"></a>其他模块</h2><h3 id="导入导出"><a href="#导入导出" class="headerlink" title="导入导出"></a>导入导出</h3><p>该模块用于演示Excel的导入导出:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1cTtU.png" alt="274.png"></p><p>导出的话没有什么可说的,直接点击导出按钮就可以将当前页面的数据导出到Excel表格中。</p><p>要导入Excel数据并且入库,需要下载导入模板。点击“模板下载”按钮下载模板:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1cv0x.png" alt="275.png"></p><p>每一列都定义了数据格式,我们修改几组数据,让它们不符合格式要求:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1gkjA.png" alt="276.png"></p><p>然后点击页面上的“导入”按钮,选择该模板,结果如下所示:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1gnN8.png" alt="277.png"></p><p><img src="https://s2.ax1x.com/2019/09/07/n1gQ3Q.png" alt="278.png"></p><p>导入成功的数据将会被保存到t_eximport表中,导入失败的数据会给出不符合要求的提示。</p><h3 id="个人博客"><a href="#个人博客" class="headerlink" title="个人博客"></a>个人博客</h3><p>这个页面主要演示如何通过iframe加载第三方页面,这个页面的vue源码为:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i-frame</span></span></span><br><span class="line"><span class="tag"> <span class="attr">:src</span>=<span class="string">"url"</span></span></span><br><span class="line"><span class="tag"> @<span class="attr">refresh</span>=<span class="string">"refresh"</span></span></span><br><span class="line"><span class="tag"> /></span></span><br><span class="line"><span class="tag"></<span class="name">template</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="keyword">import</span> iFrame <span class="keyword">from</span> <span class="string">'@/components/iFrame'</span></span></span><br><span class="line"><span class="javascript"><span class="keyword">export</span> <span class="keyword">default</span> {</span></span><br><span class="line"><span class="undefined"> components: { iFrame },</span></span><br><span class="line"><span class="undefined"> data() {</span></span><br><span class="line"><span class="javascript"> <span class="keyword">return</span> {</span></span><br><span class="line"><span class="javascript"> url: <span class="string">'https://mrbird.cc'</span></span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> },</span></span><br><span class="line"><span class="undefined"> methods: {</span></span><br><span class="line"><span class="undefined"> refresh(u) {</span></span><br><span class="line"><span class="javascript"> <span class="keyword">this</span>.url = u</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined">}</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure><p></p><h3 id="数据权限"><a href="#数据权限" class="headerlink" title="数据权限"></a>数据权限</h3><p>这个页面用于测试数据权限(不同的系统账户登录看到的数据不一样),数据权限的使用具体可以参考开发教程里的相关说明。</p><h2 id="网关管理"><a href="#网关管理" class="headerlink" title="网关管理"></a>网关管理</h2><h3 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h3><p>网关管理是对FEBS Gateway的增强,也是对WebFlux编程的一次实践,相关代码位于cc.mrbird.febs.gateway.enhance目录下,主要包含黑名单控制、限流控制和相关日志记录等功能。默认网关增强是关闭的,要开启它需要进行如下操作:</p><ol><li>安装MongoDB。MongoDB下载地址:<a href="https://www.mongodb.com/download-center/community" target="_blank" rel="noopener">https://www.mongodb.com/download-center/community</a>,下载后安装即可。我的安装路径为:D:\Program Files\MongoDB。</li></ol><p>安装好后,在D盘的根目录(或者任意你喜欢的位置)新建mongodb文件夹,然后到D:\Program Files\MongoDB\Server\4.2\bin目录下打开CMD窗口,输入如下命令开启MongoDB:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqeZad.png" alt="712.png"></p><p>启动后,浏览器访问:<a href="http://localhost:27017/" target="_blank" rel="noopener">http://localhost:27017/</a></p><p><img src="https://s2.ax1x.com/2020/01/14/lqe3qg.png" alt="713.png"></p><p>说明我们的MongoDB启动成功。</p><ol start="2"><li>Navicat连接MongoDB。使用Navicat新建一个MongoDB连接:</li></ol><p><img src="https://s2.ax1x.com/2020/01/14/lqe2J1.png" alt="714.png"></p><p>连接后,新建一个名称为febs_cloud_route的db:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqmG6K.png" alt="715.png"></p><p>然后在该db下导入febs-cloud/sql/febs_cloud_route.sql SQL脚本即可。</p><ol start="3"><li>打开配置。访问Nacos控制台:<a href="http://localhost:8001/nacos" target="_blank" rel="noopener">http://localhost:8001/nacos</a>,编辑febs-gateway.yaml配置:</li></ol><p><img src="https://s2.ax1x.com/2020/01/14/lqnSc6.png" alt="716.png"></p><p>修改好后,配置如下图所示:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqnANd.png" alt="717.png"></p><ol start="4"><li>编辑IDEA环境变量,在febs-gateway模块中添加mongo.url和redis.url变量配置:</li></ol><p><img src="https://s2.ax1x.com/2020/01/14/lqnfbD.png" alt="718.png"></p><ol start="5"><li>重新启动febs-gateway模块,启动日志中输出如如下内容的话,说明网关增强开启成功:</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">2020-01-14 16:17:59 INFO main cc.mrbird.febs.gateway.enhance.service.impl.RouteEnhanceCacheServiceImpl Cache blacklist into redis >>></span><br><span class="line">2020-01-14 16:17:59 INFO main cc.mrbird.febs.gateway.enhance.service.impl.RouteEnhanceCacheServiceImpl Cache rate limit rules into redis >>></span><br></pre></td></tr></table></figure><h3 id="网关用户"><a href="#网关用户" class="headerlink" title="网关用户"></a>网关用户</h3><p>网关管理新增了黑名单和限流规则等配置的增删改查接口,所以这部分内容也需要受保护。第一反应肯定是将网关配置为资源服务器,这样就可以和febs-server-system、febs-sever-test那样统一通过febs-auth认证和授权。但是,目前网关使用的是spring cloud gateway,其基于WebFlux编程,模型使用Reactive,而非Servlet模型,所以之前那一套并不适合网关。</p><p>综上所述,网关资源要受保护,不能将其配置为资源服务器,而需要额外的定义一套规则。相关配置可以参考febs-gateway模块的cc.mrbird.febs.gateway.enhance.auth目录下的代码,网关用户的作用便是用于管理网关模块的增删改查接口。网关管理的所有模块都需要认证,未认证时,页面显示如下:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqKASI.png" alt="719.png"></p><p>点击认证,输入网关用户的账号密码认证通过后即可访问网关管理的所有内容:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqKWAe.gif" alt="720.gif"></p><p>账户密码:</p><table><thead><tr><th>用户名</th><th>密码</th><th>权限</th></tr></thead><tbody><tr><td>Jack</td><td>123456</td><td>user,查看权限</td></tr><tr><td>admin</td><td>123456</td><td>admin,所有权限</td></tr></tbody></table><h3 id="网关日志"><a href="#网关日志" class="headerlink" title="网关日志"></a>网关日志</h3><p>网关转发请求日志,这些为未被限流或黑名单规则拦截的请求记录:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqMtgI.png" alt="721.png"></p><h3 id="限流规则"><a href="#限流规则" class="headerlink" title="限流规则"></a>限流规则</h3><p>定义网关限流规则,不符合规则的请求将被拦截,拦截记录可以通过限流日志查看:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqMaKP.png" alt="722.png"></p><p>图中的这条规则表示:对于/auth/captcha GET请求,在06:00:00到22:30:00时间范围内,每10秒钟只能请求1次,超出这个频率的话会被拦截,返回“访问频率超限,请稍后再试”提示,状态码为429,被限流规则拦截的请求可以通过限流日志查看。</p><h3 id="限流日志"><a href="#限流日志" class="headerlink" title="限流日志"></a>限流日志</h3><p>展示被限流规则拦截的请求日志: <img src="https://s2.ax1x.com/2020/01/14/lqQCRA.png" alt="723.png"></p><h3 id="黑名单管理"><a href="#黑名单管理" class="headerlink" title="黑名单管理"></a>黑名单管理</h3><p>定义网关请求黑名单:</p><p><img src="https://s2.ax1x.com/2020/01/14/lqQydO.png" alt="724.png"></p><p>图中这条规则表示:对于符合/**/actuator/**的请求,所有时间段,所有方法(无论是GET、POST、PUT、DELETE等),所有IP都不允许访问,返回“黑名单限制,禁止访问”提示,状态码为406。</p><h3 id="黑名单日志"><a href="#黑名单日志" class="headerlink" title="黑名单日志"></a>黑名单日志</h3><p>展示被限流规则拦截的请求日志: <img src="https://s2.ax1x.com/2020/01/14/lqlOAO.png" alt="725.png"></p><h2 id="任务调度"><a href="#任务调度" class="headerlink" title="任务调度"></a>任务调度</h2><h3 id="任务列表"><a href="#任务列表" class="headerlink" title="任务列表"></a>任务列表</h3><p>要使用任务调度的功能,需要先启动febs-server-job微服务子系统。启动前,需要先创建febs_cloud_job数据库。</p><p>使用navicat新建febs_cloud_job数据库:</p><p><img src="https://s1.ax1x.com/2020/04/18/JeztoV.png" alt="JeztoV.png"></p><p>然后导入<a href="https://github.com/wuyouzhuguli/FEBS-Cloud/blob/master/febs-cloud/sql/febs_cloud_job.sql" target="_blank" rel="noopener">febs_cloud_job.sql</a>数据库脚本,导入后库表如下所示:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jez4QH.png" alt="Jez4QH.png"></p><p>数据库准备完毕后,启动febs-server-job:</p><p><img src="https://s1.ax1x.com/2020/04/18/JezvlQ.png" alt="JezvlQ.png"></p><p>任务列表页面展示了当前系统中已配置的任务:</p><p><img src="https://s1.ax1x.com/2020/04/18/JmSJ6H.png" alt="JmSJ6H.png"></p><p>拿第二个任务来说,它的含义是:</p><p><img src="https://s1.ax1x.com/2020/04/18/JmpAEt.png" alt="JmpAEt.png"></p><p>就拿上面这个任务来说,它对应febs-server-job的TaskList类:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jmp8U0.png" alt="Jmp8U0.png"></p><p>任务默认是暂停的,我们可以通过页面上的操作按钮来进行一系列操作:</p><p>点击运行一次按钮: <img src="https://s1.ax1x.com/2020/04/18/Jmp2xe.png" alt="Jmp2xe.png"></p><p>点击后,该任务会马上运行一次,观测febs-server-job的控制台:</p><p><img src="https://s1.ax1x.com/2020/04/18/JmpIat.png" alt="JmpIat.png"></p><p>点击恢复按钮:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jm99iV.png" alt="Jm99iV.png"></p><p>任务状态会变为正常(即按照Cron表达式的规则进行循环调度):</p><p><img src="https://s1.ax1x.com/2020/04/18/Jm9QzD.png" alt="Jm9QzD.png"></p><p>观察febs-server-job控制台:</p><p><img src="https://s1.ax1x.com/2020/04/18/Jm9BQg.png" alt="Jm9BQg.png"></p><p>可以看到,任务执行的时间间隔就是我们定义的Cron表达式规则。</p><p>其他按钮为增删改查操作,自己玩玩即可,不赘述。</p><h3 id="调度日志"><a href="#调度日志" class="headerlink" title="调度日志"></a>调度日志</h3><p>任务列表中的任务没执行一次都会异步记录(不影响任务调度的性能)任务日志,可以通过任务日志判断任务是否执行成功: <img src="https://s1.ax1x.com/2020/04/18/Jm9vlD.png" alt="Jm9vlD.png"></p><h2 id="个人中心"><a href="#个人中心" class="headerlink" title="个人中心"></a>个人中心</h2><p>个人中心模块展示了当前登录用户的近期登录情况,并且可以在该页面修改个人信息,修改登录密码,修改头像等:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1gWCD.png" alt="279.png"></p><p>修改个人信息和登录密码没什么好说的,在相应的tab页下操作即可。下面主要演示如何修改头像:</p><p><img src="https://s2.ax1x.com/2019/09/07/n1gOPS.gif" alt="280.gif"></p><script>$(".post-body a").not(".thispage").addClass("ignore-href").attr("target","_blank")</script></div><div></div><div><div style="padding:10px 0;margin:20px auto;width:90%;text-align:center;color:#878787" id="reward-div"><div>请作者喝瓶肥宅水🥤</div><button id="rewardButton" style="margin-top:10px" disable="enable" onclick='var e=document.getElementById("QR");"none"===e.style.display?e.style.display="block":e.style.display="none"'><span style="height:46px;width:46px;line-height:46px;border-radius:50%;color:#fe5f55;font-weight:600;background:#ffd5be;border:none;box-shadow:0 4px 8px 0 rgba(255,213,190,.4)">¥</span></button><div id="QR" style="display:none"><div id="wechat" style="display:inline-block"><img id="wechat_qr" src="/img/wechat_pay.png" alt="MrBird WeChat Pay"></div><div id="alipay" style="display:inline-block"><img id="alipay_qr" src="/img/ali_pay.png" alt="MrBird Alipay"></div></div></div><style>#QR img{width:auto;margin:.8em 1em 0 1em}</style></div><div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者:</strong> MrBird</li><li class="post-copyright-link"><strong>本文链接:</strong> <a href="http://mrbird.cc/FEBS-Cloud项目使用教程.html" title="FEBS Cloud项目使用教程">http://mrbird.cc/FEBS-Cloud项目使用教程.html</a></li><li class="post-copyright-license"><strong>版权声明: </strong>本博客所有文章除特别声明外,均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="external nofollow" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明出处!</li></ul></div><footer class="post-footer"><div class="post-tags" style="margin-bottom:1.3rem"><a href="/tags/FEBS/" rel="tag"># FEBS</a> <a href="/tags/Spring-Cloud/" rel="tag"># Spring Cloud</a></div><div class="post-nav"><div class="post-nav-next post-nav-item"><a href="/FEBS-Cloud项目导入教程.html" rel="next" title="FEBS Cloud项目导入教程"><i class="fa fa-chevron-left"></i> FEBS Cloud项目导入教程</a></div><span class="post-nav-divider"></span><div class="post-nav-prev post-nav-item"><a href="/FEBS-Cloud项目开发教程.html" rel="prev" title="FEBS Cloud项目开发教程">FEBS Cloud项目开发教程 <i class="fa fa-chevron-right"></i></a></div></div></footer></article><hr><div id="container"></div><div class="post-spread"><div id="comment-div"></div><style>.valine .vlist{margin-bottom:3rem}.valine .vwrap .vcontrol .col.col-60{text-align:left}.valine .vlist .vcard .vhead,.valine .vlist .vcard section .vfooter{text-align:left}.valine .vlist .vcard section{padding-bottom:.5rem!important}.vname{color:#6db33f!important}div#comment-div{margin-bottom:-8rem}.valine .vlist .vcard .vcontent .code,.valine .vlist .vcard .vcontent code,.valine .vlist .vcard .vcontent pre{background:#fbfbfb}.valine .vlist .vcard .vcontent a{color:#6db33f}.valine .vlist .vcard .vimg{border-radius:3px}.valine .vinfo{text-align:left}.valine .vbtn{border-radius:2px;padding:.3rem 1.25rem}.valine .vbtn:active,.valine .vbtn:hover{color:#6db33f;border-color:#6db33f;background-color:#fff}.valine .vwrap .vheader .vinput:focus{border-bottom-color:#6db33f}.valine .vlist .vcard .vcontent.expand:before{background:-webkit-gradient(linear,left top,left bottom,from(hsla(0,0%,100%,0)),to(hsla(0,0%,100%,.2)));background:linear-gradient(180deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.2))}.valine .vlist .vcard .vcontent.expand:after{content:"点击展开";font-size:.4rem;text-align:right;left:-1rem;background:hsla(0,0%,100%,.2)}.valine .vlist .vcard section .vfooter .vat{color:#b3b3b3}.valine .vlist .vcard section .vfooter .vat:hover{color:#6db33f}.vcontent img{margin:0}.valine .info{display:none}</style><script type="text/javascript" src="/js/av.min.js"></script><script type="text/javascript" src="/js/Valine.min.js"></script><script type="text/javascript" src="/js/activate-power-mode.js"></script><script>POWERMODE.colorful=!0,POWERMODE.shake=!1,document.body.addEventListener("input",POWERMODE),new Valine({el:"#comment-div",notify:!1,verify:!0,appId:"SMcDFP1bN1jgb9Lo8JmtICHm-gzGzoHsz",appKey:"dH4nrUrt3V5XiJiI6Qyejnbi",placeholder:"",path:window.location.pathname,avatar:"monsterid",guest_info:["nick","mail","link"]});var chicken='<a href="#"><img src="https://image.uisdc.com/wp-content/uploads/2018/06/uisdc-chat-chicken.gif" class="checken"></a>';$("#comment-div").prepend(chicken)</script></div></div><script>var $bqinline=$("img[alt='bq-inline']");$bqinline.css({width:"2.3rem",height:"2.3rem",display:"inline","vertical-align":"text-bottom"})</script></div><div class="comments" id="comments"></div></div><aside id="sidebar" class="sidebar" onselectstart="return!1"><div class="sidebar-inner"><ul class="sidebar-nav motion-element"><li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">Contents</li><li class="sidebar-nav-overview" data-target="site-overview">Site Preview</li></ul><section class="site-overview sidebar-panel"><div class="sidebar-sticky sticky"><div itemscope itemtype="https://mrbird.cc"><div class="author__header"><div class="author__avatar"><img src="/images/blogImage.jpg" class="author__avatar" alt="MrBird" itemprop="image"></div><div class="author__content"><div class="author__name" itemprop="name">MrBird</div><p class="author__bio" itemprop="description">A simple blog, code repository, just keep blogging</p></div><div class="author__count"><a href="/archives" class="ignore-href"><span class="count">14</span> <span>Archives</span> </a><a href="/tags" class="ignore-href"><span class="count">2</span> <span>Labels</span></a></div></div><div class="author__urls-wrapper"><ul class="author__urls social-icons"><li><a href="/" itemprop="url" class="ignore-href">🏠 Home</a></li><li><a href="/archives" itemprop="url" class="ignore-href">📦 Archives</a></li><li><a href="/tags" itemprop="url" class="ignore-href">🔖 Labels</a></li><li><a href="/friends" itemprop="url" class="ignore-href">👬 Friends</a></li><li><a href="javascript:;" class="popup-trigger animsition-link">🔍 Search</a></li></ul></div></div></div></section><section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active"><div class="post-toc"><div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#系统管理"><span class="nav-number">1.</span> <span class="nav-text">系统管理</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#角色管理"><span class="nav-number">1.1.</span> <span class="nav-text">角色管理</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#新增角色"><span class="nav-number">1.1.1.</span> <span class="nav-text">新增角色</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#修改角色"><span class="nav-number">1.1.2.</span> <span class="nav-text">修改角色</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#删除角色"><span class="nav-number">1.1.3.</span> <span class="nav-text">删除角色</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#用户管理"><span class="nav-number">1.2.</span> <span class="nav-text">用户管理</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#新增用户"><span class="nav-number">1.2.1.</span> <span class="nav-text">新增用户</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#修改用户"><span class="nav-number">1.2.2.</span> <span class="nav-text">修改用户</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#删除用户"><span class="nav-number">1.2.3.</span> <span class="nav-text">删除用户</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#密码重置"><span class="nav-number">1.2.4.</span> <span class="nav-text">密码重置</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#菜单管理"><span class="nav-number">1.3.</span> <span class="nav-text">菜单管理</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#菜单结构介绍"><span class="nav-number">1.3.1.</span> <span class="nav-text">菜单结构介绍</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#新增菜单"><span class="nav-number">1.3.2.</span> <span class="nav-text">新增菜单</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#新增多级菜单"><span class="nav-number">1.3.3.</span> <span class="nav-text">新增多级菜单</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#新增按钮"><span class="nav-number">1.3.4.</span> <span class="nav-text">新增按钮</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#修改菜单-按钮"><span class="nav-number">1.3.5.</span> <span class="nav-text">修改菜单/按钮</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#删除菜单-按钮"><span class="nav-number">1.3.6.</span> <span class="nav-text">删除菜单/按钮</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#部门管理"><span class="nav-number">1.4.</span> <span class="nav-text">部门管理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#客户端管理"><span class="nav-number">1.5.</span> <span class="nav-text">客户端管理</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#系统监控"><span class="nav-number">2.</span> <span class="nav-text">系统监控</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#系统日志"><span class="nav-number">2.1.</span> <span class="nav-text">系统日志</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#登录日志"><span class="nav-number">2.2.</span> <span class="nav-text">登录日志</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#监控面板"><span class="nav-number">2.3.</span> <span class="nav-text">监控面板</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#代码生成"><span class="nav-number">3.</span> <span class="nav-text">代码生成</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#生成配置"><span class="nav-number">3.1.</span> <span class="nav-text">生成配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#生成代码"><span class="nav-number">3.2.</span> <span class="nav-text">生成代码</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#其他模块"><span class="nav-number">4.</span> <span class="nav-text">其他模块</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#导入导出"><span class="nav-number">4.1.</span> <span class="nav-text">导入导出</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#个人博客"><span class="nav-number">4.2.</span> <span class="nav-text">个人博客</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#数据权限"><span class="nav-number">4.3.</span> <span class="nav-text">数据权限</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#网关管理"><span class="nav-number">5.</span> <span class="nav-text">网关管理</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#使用说明"><span class="nav-number">5.1.</span> <span class="nav-text">使用说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#网关用户"><span class="nav-number">5.2.</span> <span class="nav-text">网关用户</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#网关日志"><span class="nav-number">5.3.</span> <span class="nav-text">网关日志</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#限流规则"><span class="nav-number">5.4.</span> <span class="nav-text">限流规则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#限流日志"><span class="nav-number">5.5.</span> <span class="nav-text">限流日志</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#黑名单管理"><span class="nav-number">5.6.</span> <span class="nav-text">黑名单管理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#黑名单日志"><span class="nav-number">5.7.</span> <span class="nav-text">黑名单日志</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#任务调度"><span class="nav-number">6.</span> <span class="nav-text">任务调度</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#任务列表"><span class="nav-number">6.1.</span> <span class="nav-text">任务列表</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#调度日志"><span class="nav-number">6.2.</span> <span class="nav-text">调度日志</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#个人中心"><span class="nav-number">7.</span> <span class="nav-text">个人中心</span></a></li></ol></div></div></section></div><div id="asider-footer"><div id="links"><li><a href="https://love.mrbird.cc" target="_blank" itemprop="url" class="ignore-href"><i class="fa fa-fw fa-diamond" aria-hidden="true"></i></a></li><li><a href="https://cloud.mrbird.cn" target="_blank" itemprop="url" class="ignore-href"><i class="fa fa-fw fa-skyatlas" aria-hidden="true"></i></a></li><li><a href="https://gitee.com/mrbirdd" target="_blank" itemprop="sameAs" class="ignore-href"><i class="fa fa-fw fa-codepen" aria-hidden="true"></i></a></li><li><a href="https://github.com/wuyouzhuguli" target="_blank" itemprop="sameAs" class="ignore-href"><i class="fa fa-fw fa-github-alt" aria-hidden="true"></i></a></li></div><div id="author"></div><script type="text/javascript">var $smsheoschzd100dn="@ 2016 - "+(new Date).getFullYear()+" MrBird";document.getElementById("author").innerHTML=$smsheoschzd100dn</script><div><script type="text/javascript" src="/js/busuanzi.js"></script> UV <span class="busuanzi-value" id="busuanzi_value_site_uv" style="cursor:pointer" title="统计开始时间:2019年7月5日"></span> PV <span class="busuanzi-value" id="busuanzi_value_site_pv" style="cursor:pointer" title="统计开始时间:2019年7月5日"></span></div></div><script>function c__(){var o=sidebar_nav_toc.attr("class");o.indexOf("active")!=-1?footer.hide(300):footer.show(300)}var sidebar_nav_toc=$(".sidebar-nav-toc"),footer=$("#asider-footer");c__(),$(".sidebar-nav").on("click",function(){c__()})</script></aside></div></main><div class="back-to-top"><span id="scrollpercent"><span>0</span></span></div></div><script type="text/javascript">"[object Function]"!==Object.prototype.toString.call(window.Promise)&&(window.Promise=null)</script><script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script><script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script><script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script><script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script><script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script><script type="text/javascript" src="/js/src/utils.js?v=5.1.1"></script><script type="text/javascript" src="/js/src/motion.js?v=5.1.1"></script><script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.1"></script><script type="text/javascript" src="/js/src/post-details.js?v=5.1.1"></script><script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.1"></script><script type="text/javascript">function proceedsearch(){$("body").append('<div class="search-popup-overlay local-search-pop-overlay"></div>').css("overflow","hidden"),$(".search-popup-overlay").click(onPopupClose),$(".popup").toggle();var t=$("#local-search-input");t.attr("autocapitalize","none"),t.attr("autocorrect","off"),t.focus()}var isfetched=!1,isXml=!0,search_path="search.xml";0===search_path.length?search_path="search.xml":search_path.endsWith("json")&&(isXml=!1);var path="/"+search_path,onPopupClose=function(t){$(".popup").hide(),$("#local-search-input").val(""),$(".search-result-list").remove(),$("#no-result").remove(),$(".local-search-pop-overlay").remove(),$("body").css("overflow","")},searchFunc=function(t,e,o){"use strict";$("body").append('<div class="search-popup-overlay local-search-pop-overlay"><div id="search-loading-icon"><i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i></div></div>').css("overflow","hidden"),$("#search-loading-icon").css("margin","20% auto 0 auto").css("text-align","center"),$.ajax({url:t,dataType:isXml?"xml":"json",async:!0,success:function(t){isfetched=!0,$(".popup").detach().appendTo(".header-inner");var n=isXml?$("entry",t).map(function(){return{title:$("title",this).text(),content:$("content",this).text(),url:$("url",this).text()}}).get():t,r=document.getElementById(e),s=document.getElementById(o),a=function(){var t=r.value.trim().toLowerCase(),e=t.split(/[\s\-]+/);e.length>1&&e.push(t);var o=[];if(t.length>0&&n.forEach(function(n){function r(e,o,n,r){for(var s=r[r.length-1],a=s.position,i=s.word,l=[],h=0;a+i.length<=n&&0!=r.length;){i===t&&h++,l.push({position:a,length:i.length});var p=a+i.length;for(r.pop();0!=r.length&&(s=r[r.length-1],a=s.position,i=s.word,p>a);)r.pop()}return c+=h,{hits:l,start:o,end:n,searchTextCount:h}}function s(t,e){var o="",n=e.start;return e.hits.forEach(function(e){o+=t.substring(n,e.position);var r=e.position+e.length;o+='<b class="search-keyword">'+t.substring(e.position,r)+"</b>",n=r}),o+=t.substring(n,e.end)}var a=!1,i=0,c=0,l=n.title.trim(),h=l.toLowerCase(),p=n.content.trim().replace(/<[^>]+>/g,""),u=p.toLowerCase(),f=decodeURIComponent(n.url),d=[],g=[];if(""!=l&&(e.forEach(function(t){function e(t,e,o){var n=t.length;if(0===n)return[];var r=0,s=[],a=[];for(o||(e=e.toLowerCase(),t=t.toLowerCase());(s=e.indexOf(t,r))>-1;)a.push({position:s,word:t}),r=s+n;return a}d=d.concat(e(t,h,!1)),g=g.concat(e(t,u,!1))}),(d.length>0||g.length>0)&&(a=!0,i=d.length+g.length)),a){[d,g].forEach(function(t){t.sort(function(t,e){return e.position!==t.position?e.position-t.position:t.word.length-e.word.length})});var v=[];0!=d.length&&v.push(r(l,0,l.length,d));for(var C=[];0!=g.length;){var $=g[g.length-1],m=$.position,x=$.word,w=m-20,y=m+80;w<0&&(w=0),y<m+x.length&&(y=m+x.length),y>p.length&&(y=p.length),C.push(r(p,w,y,g))}C.sort(function(t,e){return t.searchTextCount!==e.searchTextCount?e.searchTextCount-t.searchTextCount:t.hits.length!==e.hits.length?e.hits.length-t.hits.length:t.start-e.start});var T=parseInt("1");T>=0&&(C=C.slice(0,T));var b="";b+=0!=v.length?"<li><a href='"+f+"' class='search-result-title'>"+s(l,v[0])+"</a>":"<li><a href='"+f+"' class='search-result-title'>"+l+"</a>",C.forEach(function(t){b+="<a href='"+f+'\'><p class="search-result">'+s(p,t)+"...</p></a>"}),b+="</li>",o.push({item:b,searchTextCount:c,hitCount:i,id:o.length})}}),1===e.length&&""===e[0])s.innerHTML='<div id="no-result"><i class="fa fa-search fa-5x" /></div>';else if(0===o.length)s.innerHTML='<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>';else{o.sort(function(t,e){return t.searchTextCount!==e.searchTextCount?e.searchTextCount-t.searchTextCount:t.hitCount!==e.hitCount?e.hitCount-t.hitCount:e.id-t.id});var a='<ul class="search-result-list">';o.forEach(function(t){a+=t.item}),a+="</ul>",s.innerHTML=a}};r.addEventListener("input",a),$(".local-search-pop-overlay").remove(),$("body").css("overflow",""),proceedsearch()}})};$(".popup-trigger").click(function(t){t.stopPropagation(),isfetched===!1?searchFunc(path,"local-search-input","local-search-result"):proceedsearch()}),$(".popup-btn-close").click(onPopupClose),$(".popup").click(function(t){t.stopPropagation()}),$(document).on("keyup",function(t){var e=27===t.which&&$(".search-popup").is(":visible");e&&onPopupClose()})</script></body><script>$(function(){$("a").not(".nav-link,.cloud-tie-join-count,.ignore-href,.jstree-anchor").addClass("animsition-link")});var burst1=new mojs.Burst({left:0,top:0,radius:{5:40},children:{shape:"circle",fill:["red","cyan","orange"],fillOpacity:.8,radiusX:3.5,radiusY:3.5}});document.addEventListener("click",function(a){null==a.target.href&&"footer"!=a.target.className&&"copyright"!=a.target.className&&"author__urls social-icons"!=a.target.className&&"author__avatar"!=a.target.className&&"sidebar sidebar-active"!=a.target.className&&burst1.tune({x:a.pageX,y:a.pageY}).generate().replay()})</script><script type="text/javascript" src="/js/message.js"></script></html><!-- rebuild by neat -->