JasonsGong.github.io/posts/5293.html
2024-06-14 22:00:25 +08:00

302 lines
52 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>开源项目-若依框架 | The Blog</title><meta name="author" content="Jason"><meta name="copyright" content="Jason"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="一.若依简介官网简介 RuoYi 是一个后台管理系统,主要目的让开发者注重专注业务,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。 单体版本技术栈Spring Boot、Apache Shiro、MyBatis、Thymeleaf 前后端分离版本技术栈SpringBoot、Spring Security、Jwt、Vue 微服务版本技术栈Spring Boot、Spring">
<meta property="og:type" content="article">
<meta property="og:title" content="开源项目-若依框架">
<meta property="og:url" content="https://qingling.icu/posts/5293.html">
<meta property="og:site_name" content="The Blog">
<meta property="og:description" content="一.若依简介官网简介 RuoYi 是一个后台管理系统,主要目的让开发者注重专注业务,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。 单体版本技术栈Spring Boot、Apache Shiro、MyBatis、Thymeleaf 前后端分离版本技术栈SpringBoot、Spring Security、Jwt、Vue 微服务版本技术栈Spring Boot、Spring">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://qingling.icu/img/5.png">
<meta property="article:published_time" content="2024-02-02T14:26:04.000Z">
<meta property="article:modified_time" content="2024-02-03T14:30:54.022Z">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="若依">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://qingling.icu/img/5.png"><link rel="shortcut icon" href="/img/%E5%9B%BE%E6%A0%87.png"><link rel="canonical" href="https://qingling.icu/posts/5293.html"><link rel="preconnect" href="//fastly.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="/cdn/icon/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="/cdn/css/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="/cdn/css/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
root: '/',
algolia: undefined,
localSearch: {"path":"/search.xml","preload":true,"top_n_per_article":1,"unescape":false,"languages":{"hits_empty":"找不到您查询的内容:${query}","hits_stats":"共找到 ${hits} 篇文章"}},
translate: undefined,
noticeOutdate: undefined,
highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":400},
copy: {
success: '复制成功',
error: '复制错误',
noSupport: '浏览器不支持'
},
relativeDate: {
homepage: true,
post: true
},
runtime: '天',
dateSuffix: {
just: '刚刚',
min: '分钟前',
hour: '小时前',
day: '天前',
month: '个月前'
},
copyright: undefined,
lightbox: 'mediumZoom',
Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#006650","bgDark":"#006650","position":"top-center"},
source: {
justifiedGallery: {
js: 'https://fastly.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
css: 'https://fastly.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
}
},
isPhotoFigcaption: false,
islazyload: false,
isAnchor: true,
percent: {
toc: true,
rightside: false,
},
autoDarkmode: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
title: '开源项目-若依框架',
isPost: true,
isHome: false,
isHighlightShrink: false,
isToc: true,
postUpdate: '2024-02-03 22:30:54'
}</script><noscript><style type="text/css">
#nav {
opacity: 1
}
.justified-gallery img {
opacity: 1
}
#recent-posts time,
#post-meta time {
display: inline !important
}
</style></noscript><script>(win=>{
win.saveToLocal = {
set: function setWithExpiry(key, value, ttl) {
if (ttl === 0) return
const now = new Date()
const expiryDay = ttl * 86400000
const item = {
value: value,
expiry: now.getTime() + expiryDay,
}
localStorage.setItem(key, JSON.stringify(item))
},
get: function getWithExpiry(key) {
const itemStr = localStorage.getItem(key)
if (!itemStr) {
return undefined
}
const item = JSON.parse(itemStr)
const now = new Date()
if (now.getTime() > item.expiry) {
localStorage.removeItem(key)
return undefined
}
return item.value
}
}
win.getScript = url => new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = url
script.async = true
script.onerror = reject
script.onload = script.onreadystatechange = function() {
const loadState = this.readyState
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
script.onload = script.onreadystatechange = null
resolve()
}
document.head.appendChild(script)
})
win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = url
if (id) link.id = id
link.onerror = reject
link.onload = link.onreadystatechange = function() {
const loadState = this.readyState
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
link.onload = link.onreadystatechange = null
resolve()
}
document.head.appendChild(link)
})
win.activateDarkMode = function () {
document.documentElement.setAttribute('data-theme', 'dark')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
}
}
win.activateLightMode = function () {
document.documentElement.setAttribute('data-theme', 'light')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
}
}
const t = saveToLocal.get('theme')
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified
if (t === undefined) {
if (isLightMode) activateLightMode()
else if (isDarkMode) activateDarkMode()
else if (isNotSpecified || hasNoSupport) {
const now = new Date()
const hour = now.getHours()
const isNight = hour <= 8 || hour >= 22
isNight ? activateDarkMode() : activateLightMode()
}
window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
if (saveToLocal.get('theme') === undefined) {
e.matches ? activateDarkMode() : activateLightMode()
}
})
} else if (t === 'light') activateLightMode()
else activateDarkMode()
const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
if (asideStatus === 'hide') {
document.documentElement.classList.add('hide-aside')
} else {
document.documentElement.classList.remove('hide-aside')
}
}
const detectApple = () => {
if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
document.documentElement.classList.add('apple')
}
}
detectApple()
})(window)</script><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script><script type="text/javascript" src ="/js/welcome.js" ></script><script src="/js/sweetalert.js"></script><link rel="stylesheet" href="/css/sweetalert.css"><!-- hexo injector head_end start --><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css" media="print" onload="this.media='all'"><!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/img/avatar.jpg" onerror="onerror=null;src='/img/loading.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">60</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">39</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">10</div></a></div><br/><div class="menus_items"><div class="menus_item"><a class="site-page" target="_blank" rel="noopener" href="https://www.tutorialspoint.com/compile_java8_online.php"><i class="fa-fw fas fa-code"></i><span> 代码</span></a></div><div class="menus_item"><a class="site-page" href="/notice/"><i class="fa-fw fas fa-stream"></i><span> 公告</span></a></div><div class="menus_item"><a class="site-page" href="/website/"><i class="fa-fw fas fa-list"></i><span> 网址</span></a></div><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="not-top-img" id="page-header"><nav id="nav"><span id="blog-info"><a href="/" title="The Blog"><img class="site-icon" src="/img/logo.png"/><span class="site-name">The Blog</span></a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search" href="javascript:void(0);"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" target="_blank" rel="noopener" href="https://www.tutorialspoint.com/compile_java8_online.php"><i class="fa-fw fas fa-code"></i><span> 代码</span></a></div><div class="menus_item"><a class="site-page" href="/notice/"><i class="fa-fw fas fa-stream"></i><span> 公告</span></a></div><div class="menus_item"><a class="site-page" href="/website/"><i class="fa-fw fas fa-list"></i><span> 网址</span></a></div><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav></header><main class="layout" id="content-inner"><div id="post"><div id="post-info"><h1 class="post-title">开源项目-若依框架</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2024-02-02T14:26:04.000Z" title="发表于 2024-02-02 22:26:04">2024-02-02</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-02-03T14:30:54.022Z" title="更新于 2024-02-03 22:30:54">2024-02-03</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE/">开源项目</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">1.4k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>5分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="开源项目-若依框架"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div><article class="post-content" id="article-container"><h1 id="一-若依简介"><a href="#一-若依简介" class="headerlink" title="一.若依简介"></a>一.若依简介</h1><p><strong>官网简介</strong></p>
<p>RuoYi 是一个后台管理系统,主要目的让开发者注重专注业务,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。</p>
<p>单体版本技术栈Spring Boot、Apache Shiro、MyBatis、Thymeleaf</p>
<p>前后端分离版本技术栈SpringBoot、Spring Security、Jwt、Vue</p>
<p>微服务版本技术栈Spring Boot、Spring Cloud &amp; Alibaba</p>
<p><strong>相关网站</strong></p>
<ul>
<li>若依官网:<a target="_blank" rel="noopener" href="http://ruoyi.vip/">http://ruoyi.vip(opens new window)</a></li>
<li>演示地址:<a target="_blank" rel="noopener" href="http://demo.ruoyi.vip/">http://demo.ruoyi.vip(opens new window)</a></li>
<li>代码下载:<a target="_blank" rel="noopener" href="https://gitee.com/y_project/RuoYi">https://gitee.com/y_project/RuoYi</a></li>
<li>文档地址:<a target="_blank" rel="noopener" href="https://doc.ruoyi.vip/ruoyi/">https://doc.ruoyi.vip/ruoyi/</a></li>
</ul>
<p><strong>总结</strong></p>
<p>若依就是一个后台管理系统的通用模板,这个模板中包含了后台管理系统的常用功能,比如登录、权限管理、菜单管理、用户管理等,避免我们在开发中重复造轮子,让开发回归到业务本身。</p>
<h1 id="二-下载使用"><a href="#二-下载使用" class="headerlink" title="二.下载使用"></a>二.下载使用</h1><h2 id="1-前置环境"><a href="#1-前置环境" class="headerlink" title="1.前置环境"></a>1.前置环境</h2><p>后端:JDK、Maven、Mysql、Redis</p>
<p>前端:Node、Npm</p>
<h2 id="2-下载运行"><a href="#2-下载运行" class="headerlink" title="2.下载运行"></a>2.下载运行</h2><p>1.克隆命令</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://gitee.com/y_project/RuoYi-Vue.git</span><br></pre></td></tr></table></figure>
<p>2.使用Idea打开项目并初始化数据库脚本</p>
<blockquote>
<p>执行克隆的项目工程目录下sql目录中的两个sql文件初始化数据库</p>
</blockquote>
<p>3.修改Mysql和Redis的连接信息</p>
<blockquote>
<p>在application.yml中修改redis的连接信息在application-druid.yml中修改mysql的连接信息</p>
<p>application.yml</p>
<p>application-druid.yml</p>
</blockquote>
<p>4.使用Vscode或者Idea打开前端项目并执行命令初始化前端项目</p>
<figure class="highlight shell"><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">前端相关命令</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进入项目目录</span></span><br><span class="line">cd ruoyi-ui</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装依赖</span></span><br><span class="line">npm install</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题</span></span><br><span class="line">npm install --registry=https://registry.npmmirror.com</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">启动服务</span></span><br><span class="line">npm run dev</span><br></pre></td></tr></table></figure>
<p><img src="/pictures/image-20240203135647790.png" alt="image-20240203135647790"></p>
<h1 id="三-项目功能实现逻辑"><a href="#三-项目功能实现逻辑" class="headerlink" title="三.项目功能实现逻辑"></a>三.项目功能实现逻辑</h1><h2 id="1-基本配置"><a href="#1-基本配置" class="headerlink" title="1.基本配置"></a>1.基本配置</h2><h3 id="1-1-浏览器请求过程"><a href="#1-1-浏览器请求过程" class="headerlink" title="1.1 浏览器请求过程"></a>1.1 浏览器请求过程</h3><p><strong>配置的原因是在前端解决跨域</strong></p>
<p>1.浏览器发送<code>http://localhost/prod-api/captchaImage</code> 请求</p>
<p>2.前端接收<code>http://localhost/prod-api/captchaImage</code> 请求通过下面的配置重写url然后再将请求发送给后端通过<code>[&#39;^&#39; + process.env.VUE_APP_BASE_API]: &#39;&#39;</code>配置将<code>http://localhost/prod-api/captchaImage</code>重写为<code>http://localhost:8080/captchaImage</code></p>
<p>该配置在<code>vue.config.js</code>配置文件中</p>
<figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="attr">devServer</span>: &#123;</span><br><span class="line"> <span class="attr">host</span>: <span class="string">&#x27;0.0.0.0&#x27;</span>,</span><br><span class="line"> <span class="attr">port</span>: port,</span><br><span class="line"> <span class="attr">open</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="attr">proxy</span>: &#123;</span><br><span class="line"> <span class="comment">// detail: https://cli.vuejs.org/config/#devserver-proxy</span></span><br><span class="line"> [process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>]: &#123;</span><br><span class="line"> <span class="comment">//在这里我们我们可以把target修改为我们自己的后端服务地址</span></span><br><span class="line"> <span class="attr">target</span>: <span class="string">`http://localhost:8080`</span>,</span><br><span class="line"> <span class="attr">changeOrigin</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="attr">pathRewrite</span>: &#123;</span><br><span class="line"> <span class="comment">//将VUE_APP_BASE_API(VUE_APP_BASE_API的值可能为dev-api、pood-api)置换为空再在前面拼接target</span></span><br><span class="line"> [<span class="string">&#x27;^&#x27;</span> + process.<span class="property">env</span>.<span class="property">VUE_APP_BASE_API</span>]: <span class="string">&#x27;&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="attr">disableHostCheck</span>: <span class="literal">true</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="2-登录功能"><a href="#2-登录功能" class="headerlink" title="2.登录功能"></a>2.登录功能</h2><p><img src="/pictures/image-20240203152609601.png" alt="image-20240203152609601"></p>
<p><strong>实现思路</strong></p>
<p>1.后端生成一个计算表达式 ,例如 1+1&#x3D;?@2</p>
<p>2.然后将1+1&#x3D;?以流的方式传递给前端前端展示为图片同时后端也会传递一个UUID给前端这个UUID为就是<code>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code>2作为结果value值存入Redis中。存入Redis中的key的格式为<code>captcha_codes:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code> </p>
<p>3.用户在填写完表单之后会携带账号、密码、验证码的结果值以及之前后端传递给前端的UUID值给后端后端会先以<code>captcha_codes:+UUID</code>作为key在reidis中查找value值再和前端输入的验证码结果值作比较如果验证码相同再比较账号密码账号密码在数据库中也可以匹配上就登录成功反之返回给前端账号密码错误如果验证码不相同直接返回给前端验证码错误。</p>
<p><strong>代码实现</strong></p>
<p>1.前端在页面初始化或者刷新验证码的时候会调用下面的方法获取验证码和UUID值</p>
<figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="title function_">getCode</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="title function_">getCodeImg</span>().<span class="title function_">then</span>(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">captchaEnabled</span> = res.<span class="property">captchaEnabled</span> === <span class="literal">undefined</span> ? <span class="literal">true</span> : res.<span class="property">captchaEnabled</span>;</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable language_">this</span>.<span class="property">captchaEnabled</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">codeUrl</span> = <span class="string">&quot;data:image/gif;base64,&quot;</span> + res.<span class="property">img</span>;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">loginForm</span>.<span class="property">uuid</span> = res.<span class="property">uuid</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>2.后端生成验证码的过程</p>
<figure class="highlight java"><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><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 生成验证码</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@GetMapping(&quot;/captchaImage&quot;)</span></span><br><span class="line"><span class="keyword">public</span> AjaxResult <span class="title function_">getCode</span><span class="params">(HttpServletResponse response)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line"> <span class="comment">//创建一个ajax的返回值对象</span></span><br><span class="line"> <span class="type">AjaxResult</span> <span class="variable">ajax</span> <span class="operator">=</span> AjaxResult.success();</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//判断是否开启的验证码功能</span></span><br><span class="line"> <span class="type">boolean</span> <span class="variable">captchaEnabled</span> <span class="operator">=</span> configService.selectCaptchaEnabled();</span><br><span class="line"> ajax.put(<span class="string">&quot;captchaEnabled&quot;</span>, captchaEnabled);</span><br><span class="line"> <span class="keyword">if</span> (!captchaEnabled) &#123;</span><br><span class="line"> <span class="keyword">return</span> ajax;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 保存验证码信息</span></span><br><span class="line"> <span class="comment">//获取uui</span></span><br><span class="line"> <span class="type">String</span> <span class="variable">uuid</span> <span class="operator">=</span> IdUtils.simpleUUID();</span><br><span class="line"> <span class="comment">//生成验证码的key值</span></span><br><span class="line"> <span class="type">String</span> <span class="variable">verifyKey</span> <span class="operator">=</span> CacheConstants.CAPTCHA_CODE_KEY + uuid;</span><br><span class="line"></span><br><span class="line"> <span class="type">String</span> <span class="variable">capStr</span> <span class="operator">=</span> <span class="literal">null</span>, code = <span class="literal">null</span>;</span><br><span class="line"> <span class="type">BufferedImage</span> <span class="variable">image</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 生成验证码</span></span><br><span class="line"> <span class="type">String</span> <span class="variable">captchaType</span> <span class="operator">=</span> RuoYiConfig.getCaptchaType();</span><br><span class="line"> <span class="keyword">if</span> (<span class="string">&quot;math&quot;</span>.equals(captchaType)) &#123;</span><br><span class="line"> <span class="type">String</span> <span class="variable">capText</span> <span class="operator">=</span> captchaProducerMath.createText();</span><br><span class="line"> capStr = capText.substring(<span class="number">0</span>, capText.lastIndexOf(<span class="string">&quot;@&quot;</span>));</span><br><span class="line"> code = capText.substring(capText.lastIndexOf(<span class="string">&quot;@&quot;</span>) + <span class="number">1</span>);</span><br><span class="line"> image = captchaProducerMath.createImage(capStr);</span><br><span class="line"> &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="string">&quot;char&quot;</span>.equals(captchaType)) &#123;</span><br><span class="line"> capStr = code = captchaProducer.createText();</span><br><span class="line"> image = captchaProducer.createImage(capStr);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);</span><br><span class="line"> <span class="comment">// 转换流信息写出</span></span><br><span class="line"> <span class="type">FastByteArrayOutputStream</span> <span class="variable">os</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FastByteArrayOutputStream</span>();</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> ImageIO.write(image, <span class="string">&quot;jpg&quot;</span>, os);</span><br><span class="line"> &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line"> <span class="keyword">return</span> AjaxResult.error(e.getMessage());</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> ajax.put(<span class="string">&quot;uuid&quot;</span>, uuid);</span><br><span class="line"> ajax.put(<span class="string">&quot;img&quot;</span>, Base64.encode(os.toByteArray()));</span><br><span class="line"> <span class="keyword">return</span> ajax;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>3.前端登录提交的表单和处理登录的方法</p>
<figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="title function_">data</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> &#123;</span><br><span class="line"> <span class="comment">//验证码图片的链接</span></span><br><span class="line"> <span class="attr">codeUrl</span>: <span class="string">&quot;&quot;</span>,</span><br><span class="line"> <span class="comment">//登录提交的表单信息</span></span><br><span class="line"> <span class="attr">loginForm</span>: &#123;</span><br><span class="line"> <span class="comment">//用户名</span></span><br><span class="line"> <span class="attr">username</span>: <span class="string">&quot;admin&quot;</span>,</span><br><span class="line"> <span class="comment">//密码</span></span><br><span class="line"> <span class="attr">password</span>: <span class="string">&quot;admin123&quot;</span>,</span><br><span class="line"> <span class="comment">//是否记住密码</span></span><br><span class="line"> <span class="attr">rememberMe</span>: <span class="literal">false</span>,</span><br><span class="line"> <span class="comment">//验证码结果值</span></span><br><span class="line"> <span class="attr">code</span>: <span class="string">&quot;&quot;</span>,</span><br><span class="line"> <span class="comment">//uuid值</span></span><br><span class="line"> <span class="attr">uuid</span>: <span class="string">&quot;&quot;</span></span><br><span class="line"> &#125;</span><br><span class="line"> &#125;;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><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><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">handleLogin</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">$refs</span>.<span class="property">loginForm</span>.<span class="title function_">validate</span>(<span class="function"><span class="params">valid</span> =&gt;</span> &#123;</span><br><span class="line"> <span class="keyword">if</span> (valid) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">loading</span> = <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable language_">this</span>.<span class="property">loginForm</span>.<span class="property">rememberMe</span>) &#123;</span><br><span class="line"> <span class="title class_">Cookies</span>.<span class="title function_">set</span>(<span class="string">&quot;username&quot;</span>, <span class="variable language_">this</span>.<span class="property">loginForm</span>.<span class="property">username</span>, &#123; <span class="attr">expires</span>: <span class="number">30</span> &#125;);</span><br><span class="line"> <span class="title class_">Cookies</span>.<span class="title function_">set</span>(<span class="string">&quot;password&quot;</span>, <span class="title function_">encrypt</span>(<span class="variable language_">this</span>.<span class="property">loginForm</span>.<span class="property">password</span>), &#123; <span class="attr">expires</span>: <span class="number">30</span> &#125;);</span><br><span class="line"> <span class="title class_">Cookies</span>.<span class="title function_">set</span>(<span class="string">&#x27;rememberMe&#x27;</span>, <span class="variable language_">this</span>.<span class="property">loginForm</span>.<span class="property">rememberMe</span>, &#123; <span class="attr">expires</span>: <span class="number">30</span> &#125;);</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="title class_">Cookies</span>.<span class="title function_">remove</span>(<span class="string">&quot;username&quot;</span>);</span><br><span class="line"> <span class="title class_">Cookies</span>.<span class="title function_">remove</span>(<span class="string">&quot;password&quot;</span>);</span><br><span class="line"> <span class="title class_">Cookies</span>.<span class="title function_">remove</span>(<span class="string">&#x27;rememberMe&#x27;</span>);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">$store</span>.<span class="title function_">dispatch</span>(<span class="string">&quot;Login&quot;</span>, <span class="variable language_">this</span>.<span class="property">loginForm</span>).<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">$router</span>.<span class="title function_">push</span>(&#123; <span class="attr">path</span>: <span class="variable language_">this</span>.<span class="property">redirect</span> || <span class="string">&quot;/&quot;</span> &#125;).<span class="title function_">catch</span>(<span class="function">()=&gt;</span>&#123;&#125;);</span><br><span class="line"> &#125;).<span class="title function_">catch</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">loading</span> = <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable language_">this</span>.<span class="property">captchaEnabled</span>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">getCode</span>();</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>4.后端登录的实现逻辑</p>
</article><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E8%8B%A5%E4%BE%9D/">若依</a></div><div class="post_share"><div class="social-share" data-image="/img/5.png" data-sites="wechat,weibo,qq"></div><link rel="stylesheet" href="/cdn/css/share.min.css" media="print" onload="this.media='all'"><script src="/cdn/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/img/wechat.jpg" target="_blank"><img class="post-qr-code-img" src="/img/wechat.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/img/alipay.jpg" target="_blank"><img class="post-qr-code-img" src="/img/alipay.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><br/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="far fa-comment-alt fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="gitalk-container"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/img/avatar.jpg" onerror="this.onerror=null;this.src='/img/loading.gif'" alt="avatar"/></div><div class="author-info__name">Jason</div><div class="author-info__description">Debug the World</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">60</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">39</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">10</div></a></div><a id="card-info-btn"><i class="fab fa-microsoft"></i><span>Ctrl + D 收藏</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/JasonsGong" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="tencent://AddContact/?fromId=45&amp;fromSubId=1&amp;subcmd=all&amp;uin=2602183349&amp;website=www.oicqzone.com" target="_blank" title="QQ"><i class="fab fa-qq"></i></a><a class="social-icon" href="mailto:2602183349@qq.com" target="_blank" title="Email"><i class="fas fa-envelope-open-text"></i></a><a class="social-icon" href="https://github.com/JasonsGong?tab=repositories" target="_blank" title="代码仓库"><i class="fas fa-database"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">本网站是静态网站,更新页面资源请使用Ctrl+F5;若网站内文章对你有帮助,请使用Ctrl+D收藏该网站</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%80-%E8%8B%A5%E4%BE%9D%E7%AE%80%E4%BB%8B"><span class="toc-text">一.若依简介</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BA%8C-%E4%B8%8B%E8%BD%BD%E4%BD%BF%E7%94%A8"><span class="toc-text">二.下载使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E5%89%8D%E7%BD%AE%E7%8E%AF%E5%A2%83"><span class="toc-text">1.前置环境</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E4%B8%8B%E8%BD%BD%E8%BF%90%E8%A1%8C"><span class="toc-text">2.下载运行</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%89-%E9%A1%B9%E7%9B%AE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0%E9%80%BB%E8%BE%91"><span class="toc-text">三.项目功能实现逻辑</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE"><span class="toc-text">1.基本配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AF%B7%E6%B1%82%E8%BF%87%E7%A8%8B"><span class="toc-text">1.1 浏览器请求过程</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E7%99%BB%E5%BD%95%E5%8A%9F%E8%83%BD"><span class="toc-text">2.登录功能</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最近更新</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/posts/8957.html" title="Linux从入门到进阶"><img src="/img/8.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Linux从入门到进阶"/></a><div class="content"><a class="title" href="/posts/8957.html" title="Linux从入门到进阶">Linux从入门到进阶</a><time datetime="2024-05-10T05:31:11.691Z" title="更新于 2024-05-10 13:31:11">2024-05-10</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/35630.html" title="接口测试工具"><img src="/img/2.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="接口测试工具"/></a><div class="content"><a class="title" href="/posts/35630.html" title="接口测试工具">接口测试工具</a><time datetime="2024-05-10T05:31:11.686Z" title="更新于 2024-05-10 13:31:11">2024-05-10</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/32246.html" title="SpringBoot中整合Swagger2"><img src="/img/3.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="SpringBoot中整合Swagger2"/></a><div class="content"><a class="title" href="/posts/32246.html" title="SpringBoot中整合Swagger2">SpringBoot中整合Swagger2</a><time datetime="2024-05-10T05:31:11.681Z" title="更新于 2024-05-10 13:31:11">2024-05-10</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/19306.html" title="Docker容器化技术"><img src="/img/1.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Docker容器化技术"/></a><div class="content"><a class="title" href="/posts/19306.html" title="Docker容器化技术">Docker容器化技术</a><time datetime="2024-05-10T05:31:11.675Z" title="更新于 2024-05-10 13:31:11">2024-05-10</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/20683.html" title="Linux中开发环境的搭建"><img src="/img/8.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Linux中开发环境的搭建"/></a><div class="content"><a class="title" href="/posts/20683.html" title="Linux中开发环境的搭建">Linux中开发环境的搭建</a><time datetime="2024-05-10T05:31:11.669Z" title="更新于 2024-05-10 13:31:11">2024-05-10</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comment-alt"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/cdn/js/medium-zoom.min.js"></script><script src="/cdn/js/instantpage.min.js" type="module"></script><script src="/cdn/js/snackbar.min.js"></script><div class="js-pjax"><script>function loadGitalk () {
function initGitalk () {
var gitalk = new Gitalk(Object.assign({
clientID: '00fb27b1e484536359c2',
clientSecret: 'be41a12281c68b6e228d1a27e8d08aeb91541145',
repo: 'BlogComment',
owner: 'JasonsGong',
admin: ['JasonsGong'],
id: '25bf57d383b9062442b18c882ac8cb82',
updateCountCallback: commentCount
},null))
gitalk.render('gitalk-container')
}
if (typeof Gitalk === 'function') initGitalk()
else {
getCSS('/cdn/css/gitalk.min.css')
getScript('/cdn/js/gitalk.min.js').then(initGitalk)
}
}
function commentCount(n){
let isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
if (isCommentCount) {
isCommentCount.textContent= n
}
}
if ('Gitalk' === 'Gitalk' || !true) {
if (true) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
else loadGitalk()
} else {
function loadOtherComment () {
loadGitalk()
}
}</script></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span> 数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><br/><div class="no-result" id="local-search-results"></div><div id="local-search-stats-wrap"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js"></script></div></div><!-- hexo injector body_end start --><script data-pjax>
function butterfly_swiper_injector_config(){
var parent_div_git = document.getElementById('recent-posts');
var item_html = '<div class="recent-post-item" style="height: auto;width: 100%"><div class="blog-slider swiper-container-fade swiper-container-horizontal" id="swiper_container"><div class="blog-slider__wrp swiper-wrapper" style="transition-duration: 0ms;"><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" href="posts/19306.html" alt=""><img width="48" height="48" src="/img/1.png" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2023-04-21</span><a class="blog-slider__title" href="posts/19306.html" alt="">Docker容器化技术</a><div class="blog-slider__text">Docker</div><a class="blog-slider__button" href="posts/19306.html" alt="">详情 </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" href="posts/47003.html" alt=""><img width="48" height="48" src="/img/5.png" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2023-03-10</span><a class="blog-slider__title" href="posts/47003.html" alt="">常用正则表达式大全</a><div class="blog-slider__text">正则表达式</div><a class="blog-slider__button" href="posts/47003.html" alt="">详情 </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" href="posts/20683.html" alt=""><img width="48" height="48" src="/img/8.png" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2023-06-05</span><a class="blog-slider__title" href="posts/20683.html" alt="">Linux中开发环境的搭建</a><div class="blog-slider__text">环境搭建</div><a class="blog-slider__button" href="posts/20683.html" alt="">详情 </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" href="posts/63333.html" alt=""><img width="48" height="48" src="/img/10.png" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2023-06-03</span><a class="blog-slider__title" href="posts/63333.html" alt="">开发环境的搭建</a><div class="blog-slider__text">环境搭建</div><a class="blog-slider__button" href="posts/63333.html" alt="">详情 </a></div></div></div><div class="blog-slider__pagination swiper-pagination-clickable swiper-pagination-bullets"></div></div></div>';
if (parent_div_git !== null && typeof parent_div_git !== 'undefined') {
parent_div_git.insertAdjacentHTML("afterbegin",item_html)
}
}
var elist = 'undefined'.split(',');
var cpage = location.pathname;
var epage = 'all';
var flag = 0;
for (var i=0;i<elist.length;i++){
if (cpage.includes(elist[i])){
flag++;
}
}
if ((epage ==='all')&&(flag == 0)){
butterfly_swiper_injector_config();
}
else if (epage === cpage){
butterfly_swiper_injector_config();
}
</script><script defer src="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js"></script><script defer data-pjax src="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js"></script><!-- hexo injector body_end end --></body></html>