mirror of
https://github.com/cool-team-official/cool-admin-java-docs.git
synced 2026-10-07 11:33:24 +08:00
更新
This commit is contained in:
@@ -126,6 +126,7 @@ export default defineConfig({
|
||||
{ text: "数据初始化(init)", link: "/src/guide/initData.md" },
|
||||
{ text: "分布式ID(id)", link: "/src/guide/uniqueIDGen.md" },
|
||||
{ text: "锁(lock)", link: "/src/guide/lock.md" },
|
||||
{ text: "防重提交(submit)", link: "/src/guide/noRepeatSubmit.md" },
|
||||
{ text: "请求日志(log)", link: "/src/guide/recordLog.md" },
|
||||
{ text: "接口文档(swagger)", link: "/src/guide/swagger.md" },
|
||||
],
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{U as o,af as p,ag as u,ah as l,ai as c,aj as f,ak as d,al as m,am as h,an as g,ao as A,d as P,u as v,y,x as w,ap as C,aq as R,ar as b,as as E}from"./chunks/framework.C_oE5szm.js";import{R as S}from"./chunks/theme.yhcfifJx.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return y(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),R(),b(),s.setup&&s.setup(),()=>E(s.Layout)}});async function _(){globalThis.__VITEPRESS__=!0;const e=x(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function x(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&_().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{_ as createApp};
|
||||
import{U as o,af as p,ag as u,ah as l,ai as c,aj as f,ak as d,al as m,am as h,an as g,ao as A,d as P,u as v,y,x as w,ap as C,aq as R,ar as b,as as E}from"./chunks/framework.C_oE5szm.js";import{R as S}from"./chunks/theme.3h0kDjYh.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(S),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return y(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),R(),b(),s.setup&&s.setup(),()=>E(s.Layout)}});async function _(){globalThis.__VITEPRESS__=!0;const e=x(),a=j();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function j(){return h(T)}function x(){let e=o,a;return g(t=>{let n=A(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&_().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{_ as createApp};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
@@ -100,7 +100,7 @@ import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const F
|
||||
<span class="line"><span>│ │ │ └── admin(后端接口)</span></span>
|
||||
<span class="line"><span>│ │ │ │ └── AdminDemoInfoController.java</span></span>
|
||||
<span class="line"><span>│ │ │ └── app(前端接口)</span></span>
|
||||
<span class="line"><span>│ │ │ │ └── AppDemoInfoController.java</span></span></code></pre></div><ul><li>生成的路由前缀为: /admin/demo/info/xxx 与/app/demo/info/xxx</li><li>规则为: admin(app)/模块名/AdminDemoInfoController 转成小写替换掉 admin(app)、模块名和 controller</li></ul><h2 id="自定义路由注解" tabindex="-1">自定义路由注解 <a class="header-anchor" href="#自定义路由注解" aria-label="Permalink to "自定义路由注解""></a></h2><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">interface</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> CoolRestController</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"><span>│ │ │ │ └── AppDemoInfoController.java</span></span></code></pre></div><ul><li>生成的路由前缀为: /admin/demo/info/xxx 与/app/demo/info/xxx</li><li>规则为: admin(app)/模块名/AdminDemoInfoController 转成小写替换掉 admin(app)、模块名和 controller 如果在 AdminDemoInfoController.java 同级下有个 AdminDemoUserInfoController.java文件</li></ul><p>该接口解析的前缀则是 /admin/demo/user/info/xxx</p><div class="warning custom-block"><p class="custom-block-title">注意</p><p>这个解析规则在 v7.1.3(2024-08-25) 版本才有,在历史版本中需在 admin 包下加一级 user 包,否则这个controller eps识别不了</p></div><h2 id="自定义路由注解" tabindex="-1">自定义路由注解 <a class="header-anchor" href="#自定义路由注解" aria-label="Permalink to "自定义路由注解""></a></h2><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">interface</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> CoolRestController</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">AliasFor</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">annotation</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> RequestMapping.class)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> String </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">default</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ""</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
||||
@@ -119,4 +119,4 @@ import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const F
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> info </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> info.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mutate</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">paths</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(path).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">build</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">combine</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(info);</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> info;</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div>`,34),t=[k];function l(p,e,E,r,d,g){return a(),i("div",null,t)}const o=s(h,[["render",l]]);export{F as __pageData,o as default};
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div>`,36),t=[k];function l(p,e,E,r,d,g){return a(),i("div",null,t)}const o=s(h,[["render",l]]);export{F as __pageData,o as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const F=JSON.parse('{"title":"控制器","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/controller.md","filePath":"src/guide/controller.md","lastUpdated":1724685357000}'),h={name:"src/guide/controller.md"},k=n("",34),t=[k];function l(p,e,E,r,d,g){return a(),i("div",null,t)}const o=s(h,[["render",l]]);export{F as __pageData,o as default};
|
||||
import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const F=JSON.parse('{"title":"控制器","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/controller.md","filePath":"src/guide/controller.md","lastUpdated":1724685357000}'),h={name:"src/guide/controller.md"},k=n("",36),t=[k];function l(p,e,E,r,d,g){return a(),i("div",null,t)}const o=s(h,[["render",l]]);export{F as __pageData,o as default};
|
||||
@@ -0,0 +1,11 @@
|
||||
import{_ as a,c as s,o as n,a5 as e}from"./chunks/framework.C_oE5szm.js";const h=JSON.parse('{"title":"锁","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/lock.md","filePath":"src/guide/lock.md","lastUpdated":1724685357000}'),p={name:"src/guide/lock.md"},t=e(`<h1 id="锁" tabindex="-1">锁 <a class="header-anchor" href="#锁" aria-label="Permalink to "锁""></a></h1><p>简单锁的使用</p><p>如果项目中启用了redis,锁是基于redis 实现,否则使用 ReentrantLock</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>// 注入锁</span></span>
|
||||
<span class="line"><span>private final CoolLock coolLock;</span></span>
|
||||
<span class="line"><span></span></span>
|
||||
<span class="line"><span>String key = "lockKey";</span></span>
|
||||
<span class="line"><span>// 尝试获取锁</span></span>
|
||||
<span class="line"><span>if (coolLock.tryLock(key, Duration.ofMillis(noRepeatSubmit.expireTime()))) {</span></span>
|
||||
<span class="line"><span> // TODO 获取锁后的逻辑</span></span>
|
||||
<span class="line"><span> </span></span>
|
||||
<span class="line"><span> // 释放锁</span></span>
|
||||
<span class="line"><span> coolLock.unlock(key);</span></span>
|
||||
<span class="line"><span>}</span></span></code></pre></div>`,4),o=[t];function c(l,i,r,d,_,k){return n(),s("div",null,o)}const m=a(p,[["render",c]]);export{h as __pageData,m as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as a,c as s,o as n,a5 as e}from"./chunks/framework.C_oE5szm.js";const h=JSON.parse('{"title":"锁","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/lock.md","filePath":"src/guide/lock.md","lastUpdated":1724685357000}'),p={name:"src/guide/lock.md"},t=e("",4),o=[t];function c(l,i,r,d,_,k){return n(),s("div",null,o)}const m=a(p,[["render",c]]);export{h as __pageData,m as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const y=JSON.parse('{"title":"锁","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/lock.md","filePath":"src/guide/lock.md","lastUpdated":1724685357000}'),t={name:"src/guide/lock.md"},h=n("",3),k=[h];function l(p,e,E,r,d,g){return a(),i("div",null,k)}const c=s(t,[["render",l]]);export{y as __pageData,c as default};
|
||||
+8
-2
@@ -1,4 +1,4 @@
|
||||
import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const y=JSON.parse('{"title":"锁","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/lock.md","filePath":"src/guide/lock.md","lastUpdated":1724685357000}'),t={name:"src/guide/lock.md"},h=n(`<h1 id="锁" tabindex="-1">锁 <a class="header-anchor" href="#锁" aria-label="Permalink to "锁""></a></h1><p>简单锁的使用 如果项目中启用了redis,锁是基于redis 实现,否则使用 ReentrantLock 如下防重复提交</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Aspect</span></span>
|
||||
import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const o=JSON.parse('{"title":"防重复提交","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/noRepeatSubmit.md","filePath":"src/guide/noRepeatSubmit.md","lastUpdated":null}'),t={name:"src/guide/noRepeatSubmit.md"},h=n(`<h1 id="防重复提交" tabindex="-1">防重复提交 <a class="header-anchor" href="#防重复提交" aria-label="Permalink to "防重复提交""></a></h1><p>基于用户维度的防重复提交,该接口需要登录鉴权</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Aspect</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Component</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequiredArgsConstructor</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">public</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> class</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> NoRepeatSubmitAspect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
||||
@@ -19,4 +19,10 @@ import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const y
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> coolLock.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">unlock</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key);</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div>`,3),k=[h];function l(p,e,E,r,d,g){return a(),i("div",null,k)}const c=s(t,[["render",l]]);export{y as __pageData,c as default};
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>使用 在controller接口上加上 @NoRepeatSubmit 注解</p><div class="language-java vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">java</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">Operation</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">summary</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "'领取优惠券'"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">PostMapping</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"/receive"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> @</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">NoRepeatSubmit</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> public</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> R </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">receive</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(@</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">RequestAttribute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() JSONObject requestParams) {</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Long couponId </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> requestParams.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"couponId"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, Long.class);</span></span>
|
||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> R.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">ok</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(marketCouponInfoService.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">receive</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(couponId, CoolSecurityUtil.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getCurrentUserId</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()));</span></span>
|
||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div>`,5),k=[h];function p(l,e,E,r,d,g){return a(),i("div",null,k)}const c=s(t,[["render",p]]);export{o as __pageData,c as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as s,c as i,o as a,a5 as n}from"./chunks/framework.C_oE5szm.js";const o=JSON.parse('{"title":"防重复提交","description":"","frontmatter":{},"headers":[],"relativePath":"src/guide/noRepeatSubmit.md","filePath":"src/guide/noRepeatSubmit.md","lastUpdated":null}'),t={name:"src/guide/noRepeatSubmit.md"},h=n("",5),k=[h];function p(l,e,E,r,d,g){return a(),i("div",null,k)}const c=s(t,[["render",p]]);export{o as __pageData,c as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as a,c as l,o as e,a5 as i}from"./chunks/framework.C_oE5szm.js";const m=JSON.parse('{"title":"更新","description":"","frontmatter":{},"headers":[],"relativePath":"src/todo/update.md","filePath":"src/todo/update.md","lastUpdated":1724685357000}'),t={name:"src/todo/update.md"},r=i('<h1 id="更新" tabindex="-1">更新 <a class="header-anchor" href="#更新" aria-label="Permalink to "更新""></a></h1><p>因为有你们的支持,cool-admin 会持续不断地更新,如果方便请点下 Star,这将会给我们带来更多的动力!!!</p><h2 id="v7-1-3-2024-08-25" tabindex="-1">v7.1.3(2024-08-25) <a class="header-anchor" href="#v7-1-3-2024-08-25" aria-label="Permalink to "v7.1.3(2024-08-25)""></a></h2><ul><li>新增: list和page支持关联查询,支持自定义返回结果类型,并可以在init方法中初始化返回字段类型及数据组装函数定义(参考:<a href="/src/guide/controller.html#查询配置">控制器</a>)</li><li>新增: 分布式ID生成组件(参考:<a href="/src/guide/uniqueIDGen.html">分布式ID</a>)</li><li>新增: 锁工具(参考:<a href="/src/guide/lock.html">锁工具</a>)</li><li>新增: 防重提交注解(参考:<a href="/src/guide/noRepeatSubmit.html">防重提交</a>)</li><li>调整: 缓存数据模板(参考:<a href="/src/guide/cache.html#通过coolcache缓存模板-获取数据">缓存</a>)</li><li>调整: 优化eps解析规则 (参考:<a href="/src/guide/controller.html#接口路由规则">解析规则</a>)</li><li>调整: 优化角色修改循环单个处理为批量处理,并异步进行刷新用户权限</li><li>调整: 图形验证码获取区分app和admin</li><li>修复: 初始化数据,指定id插入不生效问题</li><li>修复: 后台人员查询列表字段关联错误</li></ul><h2 id="v7-1-2-2024-08-04" tabindex="-1">v7.1.2(2024-08-04) <a class="header-anchor" href="#v7-1-2-2024-08-04" aria-label="Permalink to "v7.1.2(2024-08-04)""></a></h2><ul><li>新增: 支持postgresql</li><li>新增: 忽略记录请求日志url配置</li><li>新增: app端手机密码登录和手机验证码登录</li><li>调整: 鉴权调整兼容app端</li><li>调整: 优化插件过大加载慢问题,移除插件jar文件落库</li><li>修复: refreshToken可以当token使用问题</li></ul><h2 id="v7-1-1-2024-07-15" tabindex="-1">v7.1.1(2024-07-15) <a class="header-anchor" href="#v7-1-1-2024-07-15" aria-label="Permalink to "v7.1.1(2024-07-15)""></a></h2><ul><li>新增 Ai 自动编码功能,简单功能零代码实现;</li><li>新增后台扩展插件,如文件上传、支付、短信等功能可以通过安装插件的方式添加;</li></ul><h2 id="v7-1-0-2024-06-27" tabindex="-1">v7.1.0(2024-06-27) <a class="header-anchor" href="#v7-1-0-2024-06-27" aria-label="Permalink to "v7.1.0(2024-06-27)""></a></h2><ul><li>升级到 Springboot3.x;</li><li>升级所有相关依赖到最新;</li><li>跟进<a href="https://cool-js.com" target="_blank" rel="noreferrer">Nodejs 版</a>相关功能;</li><li>优化若干问题;</li></ul>',10),o=[r];function c(s,h,d,n,u,p){return e(),l("div",null,o)}const f=a(t,[["render",c]]);export{m as __pageData,f as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as a,c as l,o as e,a5 as i}from"./chunks/framework.C_oE5szm.js";const m=JSON.parse('{"title":"更新","description":"","frontmatter":{},"headers":[],"relativePath":"src/todo/update.md","filePath":"src/todo/update.md","lastUpdated":1724685357000}'),t={name:"src/todo/update.md"},r=i("",10),o=[r];function s(c,d,h,n,u,p){return e(),l("div",null,o)}const f=a(t,[["render",s]]);export{m as __pageData,f as default};
|
||||
import{_ as a,c as l,o as e,a5 as i}from"./chunks/framework.C_oE5szm.js";const m=JSON.parse('{"title":"更新","description":"","frontmatter":{},"headers":[],"relativePath":"src/todo/update.md","filePath":"src/todo/update.md","lastUpdated":1724685357000}'),t={name:"src/todo/update.md"},r=i("",10),o=[r];function c(s,h,d,n,u,p){return e(),l("div",null,o)}const f=a(t,[["render",c]]);export{m as __pageData,f as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as a,c as l,o as e,a5 as i}from"./chunks/framework.C_oE5szm.js";const m=JSON.parse('{"title":"更新","description":"","frontmatter":{},"headers":[],"relativePath":"src/todo/update.md","filePath":"src/todo/update.md","lastUpdated":1724685357000}'),t={name:"src/todo/update.md"},r=i('<h1 id="更新" tabindex="-1">更新 <a class="header-anchor" href="#更新" aria-label="Permalink to "更新""></a></h1><p>因为有你们的支持,cool-admin 会持续不断地更新,如果方便请点下 Star,这将会给我们带来更多的动力!!!</p><h2 id="v7-1-3-2024-08-25" tabindex="-1">v7.1.3(2024-08-25) <a class="header-anchor" href="#v7-1-3-2024-08-25" aria-label="Permalink to "v7.1.3(2024-08-25)""></a></h2><ul><li>新增: list和page支持关联查询,支持自定义返回结果类型,并可以在init方法中初始化返回字段类型及数据组装函数定义(参考:<a href="/src/guide/controller.html#查询配置">控制器</a>)</li><li>新增: 分布式ID生成组件(参考:<a href="/src/guide/uniqueIDGen.html">分布式ID</a>)</li><li>新增: 锁工具(参考:<a href="/src/guide/lock.html">锁工具</a>)</li><li>新增: app端访问参数配置接口</li><li>调整: 缓存数据模板(参考:<a href="/src/guide/cache.html#通过coolcache缓存模板-获取数据">缓存</a>)</li><li>调整: 优化角色修改循环单个处理为批量处理,并异步进行刷新用户权限</li><li>调整: 优化eps解析规则</li><li>调整: 图形验证码获取区分app和admin</li><li>修复: 初始化数据,指定id插入不生效问题</li><li>修复: 后台人员查询列表字段关联错误</li></ul><h2 id="v7-1-2-2024-08-04" tabindex="-1">v7.1.2(2024-08-04) <a class="header-anchor" href="#v7-1-2-2024-08-04" aria-label="Permalink to "v7.1.2(2024-08-04)""></a></h2><ul><li>新增: 支持postgresql</li><li>新增: 忽略记录请求日志url配置</li><li>新增: app端手机密码登录和手机验证码登录</li><li>调整: 鉴权调整兼容app端</li><li>调整: 优化插件过大加载慢问题,移除插件jar文件落库</li><li>修复: refreshToken可以当token使用问题</li></ul><h2 id="v7-1-1-2024-07-15" tabindex="-1">v7.1.1(2024-07-15) <a class="header-anchor" href="#v7-1-1-2024-07-15" aria-label="Permalink to "v7.1.1(2024-07-15)""></a></h2><ul><li>新增 Ai 自动编码功能,简单功能零代码实现;</li><li>新增后台扩展插件,如文件上传、支付、短信等功能可以通过安装插件的方式添加;</li></ul><h2 id="v7-1-0-2024-06-27" tabindex="-1">v7.1.0(2024-06-27) <a class="header-anchor" href="#v7-1-0-2024-06-27" aria-label="Permalink to "v7.1.0(2024-06-27)""></a></h2><ul><li>升级到 Springboot3.x;</li><li>升级所有相关依赖到最新;</li><li>跟进<a href="https://cool-js.com" target="_blank" rel="noreferrer">Nodejs 版</a>相关功能;</li><li>优化若干问题;</li></ul>',10),o=[r];function s(c,d,h,n,u,p){return e(),l("div",null,o)}const f=a(t,[["render",s]]);export{m as __pageData,f as default};
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"index.md":"IDM-wWfu","readme.md":"21sdoxr8","src_about_index.md":"u0DlwXFy","src_guide_ai.md":"BONNk2Tk","src_guide_cache.md":"CFAfegzm","src_guide_controller.md":"D6YeMkQu","src_guide_db.md":"Duwyo5Xx","src_guide_deploy.md":"D3Yfqu-Q","src_guide_dev.md":"Dkd1jFPN","src_guide_dir.md":"RpZMF5oN","src_guide_exception.md":"B8TYnOY4","src_guide_flow.md":"B5L__6Os","src_guide_initdata.md":"BVn22GWI","src_guide_lock.md":"DE-VfeJh","src_guide_plugin.md":"CkiuwUnt","src_guide_quick.md":"Bto1F7au","src_guide_recordlog.md":"Dmgx8D5v","src_guide_security.md":"CWvVuPgm","src_guide_service.md":"DFVHuVBZ","src_guide_swagger.md":"Cb0cwFc8","src_guide_uniqueidgen.md":"xLCPnQAi","src_guide_upload.md":"CxcWqhw1","src_introduce_index.md":"DA1PheMx","src_introduce_show.md":"D0p_OwAi","src_introduce_src.md":"Cg4D7UK8","src_question_common.md":"DOoSuwHd","src_todo_plan.md":"OECDxoZt","src_todo_update.md":"CM3yST2v"}
|
||||
{"index.md":"IDM-wWfu","readme.md":"21sdoxr8","src_about_index.md":"u0DlwXFy","src_guide_ai.md":"BONNk2Tk","src_guide_cache.md":"CFAfegzm","src_guide_controller.md":"CrlXUAp2","src_guide_db.md":"Duwyo5Xx","src_guide_deploy.md":"D3Yfqu-Q","src_guide_dev.md":"Dkd1jFPN","src_guide_dir.md":"RpZMF5oN","src_guide_exception.md":"B8TYnOY4","src_guide_flow.md":"B5L__6Os","src_guide_initdata.md":"BVn22GWI","src_guide_lock.md":"B687k0lQ","src_guide_norepeatsubmit.md":"DwVVy_Kc","src_guide_plugin.md":"CkiuwUnt","src_guide_quick.md":"Bto1F7au","src_guide_recordlog.md":"Dmgx8D5v","src_guide_security.md":"CWvVuPgm","src_guide_service.md":"DFVHuVBZ","src_guide_swagger.md":"Cb0cwFc8","src_guide_uniqueidgen.md":"xLCPnQAi","src_guide_upload.md":"CxcWqhw1","src_introduce_index.md":"DA1PheMx","src_introduce_show.md":"D0p_OwAi","src_introduce_src.md":"Cg4D7UK8","src_question_common.md":"DOoSuwHd","src_todo_plan.md":"OECDxoZt","src_todo_update.md":"BeuhZcon"}
|
||||
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+6
-6
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+15
-26
File diff suppressed because one or more lines are too long
+51
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+5
-5
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+5
-5
File diff suppressed because one or more lines are too long
@@ -172,9 +172,15 @@ public class DemoServiceImpl extends BaseServiceImpl<DemoMapper, DemoEntity> imp
|
||||
│ │ │ │ └── AppDemoInfoController.java
|
||||
|
||||
```
|
||||
|
||||
- 生成的路由前缀为: /admin/demo/info/xxx 与/app/demo/info/xxx
|
||||
- 规则为: admin(app)/模块名/AdminDemoInfoController 转成小写替换掉 admin(app)、模块名和 controller
|
||||
如果在 AdminDemoInfoController.java 同级下有个 AdminDemoUserInfoController.java文件
|
||||
|
||||
该接口解析的前缀则是 /admin/demo/user/info/xxx
|
||||
|
||||
::: warning 注意
|
||||
这个解析规则在 v7.1.3(2024-08-25) 版本才有,在历史版本中需在 admin 包下加一级 user 包,否则这个controller eps识别不了
|
||||
:::
|
||||
|
||||
## 自定义路由注解
|
||||
|
||||
|
||||
+11
-21
@@ -1,28 +1,18 @@
|
||||
# 锁
|
||||
简单锁的使用
|
||||
|
||||
如果项目中启用了redis,锁是基于redis 实现,否则使用 ReentrantLock
|
||||
如下防重复提交
|
||||
```java
|
||||
@Aspect
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class NoRepeatSubmitAspect {
|
||||
|
||||
private final CoolLock coolLock;
|
||||
```
|
||||
// 注入锁
|
||||
private final CoolLock coolLock;
|
||||
|
||||
@Around("@annotation(noRepeatSubmit)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(
|
||||
RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String key = request.getRequestURI() + ":" + CoolSecurityUtil.getCurrentUserId();
|
||||
// 加锁
|
||||
CoolPreconditions.check(!coolLock.tryLock(key, Duration.ofMillis(noRepeatSubmit.expireTime())), "请勿重复操作");
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
} finally {
|
||||
// 移除锁
|
||||
coolLock.unlock(key);
|
||||
}
|
||||
}
|
||||
String key = "lockKey";
|
||||
// 尝试获取锁
|
||||
if (coolLock.tryLock(key, Duration.ofMillis(noRepeatSubmit.expireTime()))) {
|
||||
// TODO 获取锁后的逻辑
|
||||
|
||||
// 释放锁
|
||||
coolLock.unlock(key);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
# 防重复提交
|
||||
基于用户维度的防重复提交,该接口需要登录鉴权
|
||||
```java
|
||||
@Aspect
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class NoRepeatSubmitAspect {
|
||||
|
||||
private final CoolLock coolLock;
|
||||
|
||||
@Around("@annotation(noRepeatSubmit)")
|
||||
public Object around(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable {
|
||||
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(
|
||||
RequestContextHolder.getRequestAttributes())).getRequest();
|
||||
String key = request.getRequestURI() + ":" + CoolSecurityUtil.getCurrentUserId();
|
||||
// 加锁
|
||||
CoolPreconditions.check(!coolLock.tryLock(key, Duration.ofMillis(noRepeatSubmit.expireTime())), "请勿重复操作");
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
} finally {
|
||||
// 移除锁
|
||||
coolLock.unlock(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
使用 在controller接口上加上 @NoRepeatSubmit 注解
|
||||
|
||||
```java
|
||||
@Operation(summary = "'领取优惠券'")
|
||||
@PostMapping("/receive")
|
||||
@NoRepeatSubmit
|
||||
public R receive(@RequestAttribute() JSONObject requestParams) {
|
||||
Long couponId = requestParams.get("couponId", Long.class);
|
||||
return R.ok(marketCouponInfoService.receive(couponId, CoolSecurityUtil.getCurrentUserId()));
|
||||
}
|
||||
```
|
||||
+2
-2
@@ -6,10 +6,10 @@
|
||||
- 新增: list和page支持关联查询,支持自定义返回结果类型,并可以在init方法中初始化返回字段类型及数据组装函数定义(参考:[控制器](/src/guide/controller.html#查询配置))
|
||||
- 新增: 分布式ID生成组件(参考:[分布式ID](/src/guide/uniqueIDGen.md))
|
||||
- 新增: 锁工具(参考:[锁工具](/src/guide/lock.md))
|
||||
- 新增: app端访问参数配置接口
|
||||
- 新增: 防重提交注解(参考:[防重提交](/src/guide/noRepeatSubmit.md))
|
||||
- 调整: 缓存数据模板(参考:[缓存](/src/guide/cache.html#通过coolcache缓存模板-获取数据))
|
||||
- 调整: 优化eps解析规则 (参考:[解析规则](/src/guide/controller.html#接口路由规则))
|
||||
- 调整: 优化角色修改循环单个处理为批量处理,并异步进行刷新用户权限
|
||||
- 调整: 优化eps解析规则
|
||||
- 调整: 图形验证码获取区分app和admin
|
||||
- 修复: 初始化数据,指定id插入不生效问题
|
||||
- 修复: 后台人员查询列表字段关联错误
|
||||
|
||||
Reference in New Issue
Block a user